34 #define DEBUG_TYPE "lowerintrinsics"
39 #include "llvm/Transforms/Scalar.h"
40 #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
41 #include "tce_config.h"
42 #include "llvm/IR/Module.h"
43 #include "llvm/IR/Instructions.h"
44 #include "llvm/IR/Constants.h"
45 #include "llvm/IR/Intrinsics.h"
46 #include "llvm/IR/DerivedTypes.h"
47 #include "llvm/IR/LLVMContext.h"
48 #include "llvm/Support/Compiler.h"
49 #include "llvm/Pass.h"
50 #include "llvm/CodeGen/IntrinsicLowering.h"
51 #include "tce_config.h"
55 #include "llvm/IR/DataLayout.h"
64 class LowerIntrinsics :
public FunctionPass {
68 virtual ~LowerIntrinsics();
71 bool doInitialization(Module &M);
72 bool doFinalization (Module &M);
75 using llvm::FunctionPass::doInitialization;
76 using llvm::FunctionPass::doFinalization;
78 bool runOnBasicBlock(BasicBlock &BB);
79 bool runOnFunction(Function &F)
override;
83 std::set<unsigned> replace_;
84 IntrinsicLowering* iLowering_;
88 char LowerIntrinsics::ID = 0;
89 RegisterPass<LowerIntrinsics>
90 X(
"lowerintrinsics",
"Lower llvm intrinsics back to libcalls.");
97 LowerIntrinsics::LowerIntrinsics() :
99 iLowering_(NULL), td_(NULL) {
105 LowerIntrinsics::~LowerIntrinsics() {
110 LowerIntrinsics::doInitialization(Module &M) {
113 replace_.insert(Intrinsic::flt_rounds);
114 replace_.insert(Intrinsic::ceil);
115 replace_.insert(Intrinsic::floor);
116 replace_.insert(Intrinsic::round);
117 replace_.insert(Intrinsic::exp2);
118 replace_.insert(Intrinsic::memcpy);
119 replace_.insert(Intrinsic::memset);
120 replace_.insert(Intrinsic::memmove);
122 assert(iLowering_ == NULL && td_ == NULL);
124 iLowering_ =
new IntrinsicLowering(*td_);
129 LowerIntrinsics::doFinalization(Module& ) {
130 if (iLowering_ != NULL) {
143 LowerIntrinsics::runOnBasicBlock(BasicBlock &BB) {
148 for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
149 CallInst* ci = dyn_cast<CallInst>(&(*I));
150 if (ci != NULL && ci->arg_size() != 0) {
151 Function* callee = ci->getCalledFunction();
152 if (callee != NULL && callee->isIntrinsic() &&
153 replace_.find(callee->getIntrinsicID()) != replace_.end()) {
154 if (callee->getIntrinsicID() == Intrinsic::flt_rounds) {
158 I->replaceAllUsesWith(
160 Type::getInt32Ty(BB.getContext()), 0,
true));
161 I->eraseFromParent();
165 iLowering_->LowerIntrinsicCall(ci);
177 LowerIntrinsics::runOnFunction(Function &F) {
179 for (BasicBlock &BB : F) {