| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 1 | //===- PreISelIntrinsicLowering.cpp - Pre-ISel intrinsic lowering pass ----===// | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 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 |  | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/PreISelIntrinsicLowering.h" | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 15 | #include "llvm/CodeGen/Passes.h" | 
|  | 16 | #include "llvm/IR/Function.h" | 
|  | 17 | #include "llvm/IR/IRBuilder.h" | 
|  | 18 | #include "llvm/IR/Instructions.h" | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 19 | #include "llvm/IR/Module.h" | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 20 | #include "llvm/IR/Type.h" | 
|  | 21 | #include "llvm/IR/User.h" | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 22 | #include "llvm/Pass.h" | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 23 | #include "llvm/Support/Casting.h" | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 24 |  | 
|  | 25 | using namespace llvm; | 
|  | 26 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 27 | static bool lowerLoadRelative(Function &F) { | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 28 | if (F.use_empty()) | 
|  | 29 | return false; | 
|  | 30 |  | 
|  | 31 | bool Changed = false; | 
|  | 32 | Type *Int32Ty = Type::getInt32Ty(F.getContext()); | 
|  | 33 | Type *Int32PtrTy = Int32Ty->getPointerTo(); | 
|  | 34 | Type *Int8Ty = Type::getInt8Ty(F.getContext()); | 
|  | 35 |  | 
|  | 36 | for (auto I = F.use_begin(), E = F.use_end(); I != E;) { | 
|  | 37 | auto CI = dyn_cast<CallInst>(I->getUser()); | 
|  | 38 | ++I; | 
|  | 39 | if (!CI || CI->getCalledValue() != &F) | 
|  | 40 | continue; | 
|  | 41 |  | 
|  | 42 | IRBuilder<> B(CI); | 
|  | 43 | Value *OffsetPtr = | 
|  | 44 | B.CreateGEP(Int8Ty, CI->getArgOperand(0), CI->getArgOperand(1)); | 
|  | 45 | Value *OffsetPtrI32 = B.CreateBitCast(OffsetPtr, Int32PtrTy); | 
|  | 46 | Value *OffsetI32 = B.CreateAlignedLoad(OffsetPtrI32, 4); | 
|  | 47 |  | 
|  | 48 | Value *ResultPtr = B.CreateGEP(Int8Ty, CI->getArgOperand(0), OffsetI32); | 
|  | 49 |  | 
|  | 50 | CI->replaceAllUsesWith(ResultPtr); | 
|  | 51 | CI->eraseFromParent(); | 
|  | 52 | Changed = true; | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | return Changed; | 
|  | 56 | } | 
|  | 57 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 58 | static bool lowerIntrinsics(Module &M) { | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 59 | bool Changed = false; | 
|  | 60 | for (Function &F : M) { | 
|  | 61 | if (F.getName().startswith("llvm.load.relative.")) | 
|  | 62 | Changed |= lowerLoadRelative(F); | 
|  | 63 | } | 
|  | 64 | return Changed; | 
|  | 65 | } | 
|  | 66 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 67 | namespace { | 
|  | 68 |  | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 69 | class PreISelIntrinsicLoweringLegacyPass : public ModulePass { | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 70 | public: | 
|  | 71 | static char ID; | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 72 |  | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 73 | PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {} | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 74 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 75 | bool runOnModule(Module &M) override { return lowerIntrinsics(M); } | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 76 | }; | 
|  | 77 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 78 | } // end anonymous namespace | 
|  | 79 |  | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 80 | char PreISelIntrinsicLoweringLegacyPass::ID; | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 81 |  | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 82 | INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass, | 
|  | 83 | "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering", | 
|  | 84 | false, false) | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 85 |  | 
| Eugene Zelenko | 618c555 | 2017-09-13 21:15:20 +0000 | [diff] [blame] | 86 | ModulePass *llvm::createPreISelIntrinsicLoweringPass() { | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 87 | return new PreISelIntrinsicLoweringLegacyPass; | 
| Peter Collingbourne | 7dd8dbf | 2016-04-22 21:18:02 +0000 | [diff] [blame] | 88 | } | 
| Michael Kuperstein | 82d5da5 | 2016-06-24 20:13:42 +0000 | [diff] [blame] | 89 |  | 
|  | 90 | PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M, | 
|  | 91 | ModuleAnalysisManager &AM) { | 
|  | 92 | if (!lowerIntrinsics(M)) | 
|  | 93 | return PreservedAnalyses::all(); | 
|  | 94 | else | 
|  | 95 | return PreservedAnalyses::none(); | 
|  | 96 | } |