/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/Transform/RewriteByReferenceParameters.cpp
Line | Count | Source (jump to first uncovered line) |
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; |
34 | 2 | explicit RewriteByrefParams() : FunctionPass(ID) {} |
35 | | |
36 | 2 | virtual void getAnalysisUsage(AnalysisUsage &AU) const override {} |
37 | | |
38 | 27 | void tryRewriteInstruction(Instruction &Inst) { |
39 | 27 | BasicBlock *Entry = &Inst.getParent()->getParent()->getEntryBlock(); |
40 | 27 | |
41 | 27 | auto *Call = dyn_cast<CallInst>(&Inst); |
42 | 27 | |
43 | 27 | if (!Call) |
44 | 26 | return; |
45 | 1 | |
46 | 1 | llvm::Function *F = Call->getCalledFunction(); |
47 | 1 | |
48 | 1 | if (!F) |
49 | 0 | return; |
50 | 1 | |
51 | 1 | // We currently match for a very specific function. In case this proves |
52 | 1 | // useful, we can make this code dependent on readonly metadata. |
53 | 1 | if (!F->hasName() || F->getName() != "_gfortran_transfer_integer_write") |
54 | 0 | return; |
55 | 1 | |
56 | 1 | auto *BitCast = dyn_cast<BitCastInst>(Call->getOperand(1)); |
57 | 1 | |
58 | 1 | if (!BitCast) |
59 | 0 | return; |
60 | 1 | |
61 | 1 | auto *Alloca = dyn_cast<AllocaInst>(BitCast->getOperand(0)); |
62 | 1 | |
63 | 1 | if (!Alloca) |
64 | 0 | return; |
65 | 1 | |
66 | 1 | std::string InstName = Alloca->getName(); |
67 | 1 | |
68 | 1 | auto NewAlloca = |
69 | 1 | new AllocaInst(Alloca->getType()->getElementType(), 0, |
70 | 1 | "polly_byref_alloca_" + InstName, &*Entry->begin()); |
71 | 1 | |
72 | 1 | auto *LoadedVal = |
73 | 1 | new LoadInst(Alloca, "polly_byref_load_" + InstName, &Inst); |
74 | 1 | |
75 | 1 | new StoreInst(LoadedVal, NewAlloca, &Inst); |
76 | 1 | auto *NewBitCast = new BitCastInst(NewAlloca, BitCast->getType(), |
77 | 1 | "polly_byref_cast_" + InstName, &Inst); |
78 | 1 | Call->setOperand(1, NewBitCast); |
79 | 1 | } |
80 | | |
81 | 2 | virtual bool runOnFunction(Function &F) override { |
82 | 2 | for (BasicBlock &BB : F) |
83 | 11 | for (Instruction &Inst : BB) |
84 | 27 | tryRewriteInstruction(Inst); |
85 | 2 | |
86 | 2 | return true; |
87 | 2 | } |
88 | | }; |
89 | | |
90 | | char RewriteByrefParams::ID; |
91 | | } // anonymous namespace |
92 | | |
93 | 1 | Pass *polly::createRewriteByrefParamsPass() { return new RewriteByrefParams(); } |
94 | | |
95 | 48.2k | INITIALIZE_PASS_BEGIN(RewriteByrefParams, "polly-rewrite-byref-params", |
96 | 48.2k | "Polly - Rewrite by reference parameters", false, false) |
97 | 48.2k | INITIALIZE_PASS_END(RewriteByrefParams, "polly-rewrite-byref-params", |
98 | | "Polly - Rewrite by reference parameters", false, false) |