Line data Source code
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 : return false;
30 :
31 : 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 :
36 8 : for (auto I = F.use_begin(), E = F.use_end(); I != E;) {
37 4 : auto CI = dyn_cast<CallInst>(I->getUser());
38 : ++I;
39 4 : if (!CI || CI->getCalledValue() != &F)
40 0 : continue;
41 :
42 4 : IRBuilder<> B(CI);
43 : Value *OffsetPtr =
44 8 : 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 :
48 4 : Value *ResultPtr = B.CreateGEP(Int8Ty, CI->getArgOperand(0), OffsetI32);
49 :
50 4 : CI->replaceAllUsesWith(ResultPtr);
51 4 : CI->eraseFromParent();
52 : Changed = true;
53 : }
54 :
55 : return Changed;
56 : }
57 :
58 27318 : static bool lowerIntrinsics(Module &M) {
59 : bool Changed = false;
60 553131 : for (Function &F : M) {
61 1051622 : if (F.getName().startswith("llvm.load.relative."))
62 4 : Changed |= lowerLoadRelative(F);
63 : }
64 27318 : return Changed;
65 : }
66 :
67 : namespace {
68 :
69 : class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
70 : public:
71 : static char ID;
72 :
73 27454 : PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
74 :
75 27317 : bool runOnModule(Module &M) override { return lowerIntrinsics(M); }
76 : };
77 :
78 : } // end anonymous namespace
79 :
80 : char PreISelIntrinsicLoweringLegacyPass::ID;
81 :
82 103150 : INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass,
83 : "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering",
84 : false, false)
85 :
86 27453 : ModulePass *llvm::createPreISelIntrinsicLoweringPass() {
87 27453 : return new PreISelIntrinsicLoweringLegacyPass;
88 : }
89 :
90 1 : PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M,
91 : ModuleAnalysisManager &AM) {
92 1 : if (!lowerIntrinsics(M))
93 : return PreservedAnalyses::all();
94 : else
95 : return PreservedAnalyses::none();
96 : }
|