/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- PreISelIntrinsicLowering.cpp - Pre-ISel intrinsic lowering pass ----===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This pass implements IR lowering for the llvm.load.relative intrinsic. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/CodeGen/PreISelIntrinsicLowering.h" |
15 | | #include "llvm/CodeGen/Passes.h" |
16 | | #include "llvm/IR/Function.h" |
17 | | #include "llvm/IR/IRBuilder.h" |
18 | | #include "llvm/IR/Instructions.h" |
19 | | #include "llvm/IR/Module.h" |
20 | | #include "llvm/IR/Type.h" |
21 | | #include "llvm/IR/User.h" |
22 | | #include "llvm/Pass.h" |
23 | | #include "llvm/Support/Casting.h" |
24 | | |
25 | | using namespace llvm; |
26 | | |
27 | 4 | static bool lowerLoadRelative(Function &F) { |
28 | 4 | if (F.use_empty()) |
29 | 0 | return false; |
30 | 4 | |
31 | 4 | bool Changed = false; |
32 | 4 | Type *Int32Ty = Type::getInt32Ty(F.getContext()); |
33 | 4 | Type *Int32PtrTy = Int32Ty->getPointerTo(); |
34 | 4 | Type *Int8Ty = Type::getInt8Ty(F.getContext()); |
35 | 4 | |
36 | 8 | for (auto I = F.use_begin(), E = F.use_end(); I != E8 ;) { |
37 | 4 | auto CI = dyn_cast<CallInst>(I->getUser()); |
38 | 4 | ++I; |
39 | 4 | if (!CI || 4 CI->getCalledValue() != &F4 ) |
40 | 0 | continue; |
41 | 4 | |
42 | 4 | IRBuilder<> B(CI); |
43 | 4 | Value *OffsetPtr = |
44 | 4 | B.CreateGEP(Int8Ty, CI->getArgOperand(0), CI->getArgOperand(1)); |
45 | 4 | Value *OffsetPtrI32 = B.CreateBitCast(OffsetPtr, Int32PtrTy); |
46 | 4 | Value *OffsetI32 = B.CreateAlignedLoad(OffsetPtrI32, 4); |
47 | 4 | |
48 | 4 | Value *ResultPtr = B.CreateGEP(Int8Ty, CI->getArgOperand(0), OffsetI32); |
49 | 4 | |
50 | 4 | CI->replaceAllUsesWith(ResultPtr); |
51 | 4 | CI->eraseFromParent(); |
52 | 4 | Changed = true; |
53 | 4 | } |
54 | 4 | |
55 | 4 | return Changed; |
56 | 4 | } |
57 | | |
58 | 33.4k | static bool lowerIntrinsics(Module &M) { |
59 | 33.4k | bool Changed = false; |
60 | 836k | for (Function &F : M) { |
61 | 836k | if (F.getName().startswith("llvm.load.relative.")) |
62 | 4 | Changed |= lowerLoadRelative(F); |
63 | 836k | } |
64 | 33.4k | return Changed; |
65 | 33.4k | } |
66 | | |
67 | | namespace { |
68 | | |
69 | | class PreISelIntrinsicLoweringLegacyPass : public ModulePass { |
70 | | public: |
71 | | static char ID; |
72 | | |
73 | 33.5k | PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {} |
74 | | |
75 | 33.4k | bool runOnModule(Module &M) override { return lowerIntrinsics(M); } |
76 | | }; |
77 | | |
78 | | } // end anonymous namespace |
79 | | |
80 | | char PreISelIntrinsicLoweringLegacyPass::ID; |
81 | | |
82 | | INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass, |
83 | | "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering", |
84 | | false, false) |
85 | | |
86 | 33.5k | ModulePass *llvm::createPreISelIntrinsicLoweringPass() { |
87 | 33.5k | return new PreISelIntrinsicLoweringLegacyPass; |
88 | 33.5k | } |
89 | | |
90 | | PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M, |
91 | 1 | ModuleAnalysisManager &AM) { |
92 | 1 | if (!lowerIntrinsics(M)) |
93 | 0 | return PreservedAnalyses::all(); |
94 | 1 | else |
95 | 1 | return PreservedAnalyses::none(); |
96 | 0 | } |