1 //===- PreISelIntrinsicLowering.cpp - Pre-ISel intrinsic lowering pass ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This pass implements IR lowering for the llvm.load.relative intrinsic.
12 //===----------------------------------------------------------------------===//
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"
27 static bool lowerLoadRelative(Function
&F
) {
32 Type
*Int32Ty
= Type::getInt32Ty(F
.getContext());
33 Type
*Int32PtrTy
= Int32Ty
->getPointerTo();
34 Type
*Int8Ty
= Type::getInt8Ty(F
.getContext());
36 for (auto I
= F
.use_begin(), E
= F
.use_end(); I
!= E
;) {
37 auto CI
= dyn_cast
<CallInst
>(I
->getUser());
39 if (!CI
|| CI
->getCalledValue() != &F
)
44 B
.CreateGEP(Int8Ty
, CI
->getArgOperand(0), CI
->getArgOperand(1));
45 Value
*OffsetPtrI32
= B
.CreateBitCast(OffsetPtr
, Int32PtrTy
);
46 Value
*OffsetI32
= B
.CreateAlignedLoad(OffsetPtrI32
, 4);
48 Value
*ResultPtr
= B
.CreateGEP(Int8Ty
, CI
->getArgOperand(0), OffsetI32
);
50 CI
->replaceAllUsesWith(ResultPtr
);
51 CI
->eraseFromParent();
58 static bool lowerIntrinsics(Module
&M
) {
60 for (Function
&F
: M
) {
61 if (F
.getName().startswith("llvm.load.relative."))
62 Changed
|= lowerLoadRelative(F
);
69 class PreISelIntrinsicLoweringLegacyPass
: public ModulePass
{
73 PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID
) {}
75 bool runOnModule(Module
&M
) override
{ return lowerIntrinsics(M
); }
78 } // end anonymous namespace
80 char PreISelIntrinsicLoweringLegacyPass::ID
;
82 INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass
,
83 "pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering",
86 ModulePass
*llvm::createPreISelIntrinsicLoweringPass() {
87 return new PreISelIntrinsicLoweringLegacyPass
;
90 PreservedAnalyses
PreISelIntrinsicLoweringPass::run(Module
&M
,
91 ModuleAnalysisManager
&AM
) {
92 if (!lowerIntrinsics(M
))
93 return PreservedAnalyses::all();
95 return PreservedAnalyses::none();