1 //===------ RewriteByReferenceParameters.cpp --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass introduces separate 'alloca' instructions for read-only
10 // by-reference function parameters to indicate that these paramters are
11 // read-only. After this transformation -mem2reg has more freedom to promote
12 // variables to registers, which allows SCEV to work in more cases.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "polly/LinkAllPasses.h"
17 #include "llvm/IR/Instruction.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/Pass.h"
20
21 #define DEBUG_TYPE "polly-rewrite-byref-params"
22
23 using namespace llvm;
24
25 namespace {
26
27 class RewriteByrefParams : public FunctionPass {
28 private:
29 RewriteByrefParams(const RewriteByrefParams &) = delete;
30 const RewriteByrefParams &operator=(const RewriteByrefParams &) = delete;
31
32 public:
33 static char ID;
RewriteByrefParams()34 explicit RewriteByrefParams() : FunctionPass(ID) {}
35
getAnalysisUsage(AnalysisUsage & AU) const36 virtual void getAnalysisUsage(AnalysisUsage &AU) const override {}
37
tryRewriteInstruction(Instruction & Inst)38 void tryRewriteInstruction(Instruction &Inst) {
39 BasicBlock *Entry = &Inst.getParent()->getParent()->getEntryBlock();
40
41 auto *Call = dyn_cast<CallInst>(&Inst);
42
43 if (!Call)
44 return;
45
46 llvm::Function *F = Call->getCalledFunction();
47
48 if (!F)
49 return;
50
51 // We currently match for a very specific function. In case this proves
52 // useful, we can make this code dependent on readonly metadata.
53 if (!F->hasName() || F->getName() != "_gfortran_transfer_integer_write")
54 return;
55
56 auto *BitCast = dyn_cast<BitCastInst>(Call->getOperand(1));
57
58 if (!BitCast)
59 return;
60
61 auto *Alloca = dyn_cast<AllocaInst>(BitCast->getOperand(0));
62
63 if (!Alloca)
64 return;
65
66 std::string InstName = Alloca->getName().str();
67
68 auto NewAlloca =
69 new AllocaInst(Alloca->getAllocatedType(), 0,
70 "polly_byref_alloca_" + InstName, &*Entry->begin());
71
72 auto *LoadedVal = new LoadInst(Alloca->getAllocatedType(), Alloca,
73 "polly_byref_load_" + InstName, &Inst);
74
75 new StoreInst(LoadedVal, NewAlloca, &Inst);
76 auto *NewBitCast = new BitCastInst(NewAlloca, BitCast->getType(),
77 "polly_byref_cast_" + InstName, &Inst);
78 Call->setOperand(1, NewBitCast);
79 }
80
runOnFunction(Function & F)81 virtual bool runOnFunction(Function &F) override {
82 for (BasicBlock &BB : F)
83 for (Instruction &Inst : BB)
84 tryRewriteInstruction(Inst);
85
86 return true;
87 }
88 };
89
90 char RewriteByrefParams::ID;
91 } // anonymous namespace
92
createRewriteByrefParamsPass()93 Pass *polly::createRewriteByrefParamsPass() { return new RewriteByrefParams(); }
94
95 INITIALIZE_PASS_BEGIN(RewriteByrefParams, "polly-rewrite-byref-params",
96 "Polly - Rewrite by reference parameters", false, false)
97 INITIALIZE_PASS_END(RewriteByrefParams, "polly-rewrite-byref-params",
98 "Polly - Rewrite by reference parameters", false, false)
99