IntrinsicLowering.cpp revision cf8990838143fcfa91dd6276af523ac6c23517c2
1//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the default intrinsic lowering implementation. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/IntrinsicLowering.h" 15#include "llvm/Constants.h" 16#include "llvm/DerivedTypes.h" 17#include "llvm/Module.h" 18#include "llvm/iOther.h" 19using namespace llvm; 20 21void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 22 Function *Callee = CI->getCalledFunction(); 23 assert(Callee && "Cannot lower an indirect call!"); 24 25 Module *M = Callee->getParent(); 26 27 switch (Callee->getIntrinsicID()) { 28 case Intrinsic::not_intrinsic: 29 std::cerr << "Cannot lower a call to a non-intrinsic function '" 30 << Callee->getName() << "'!\n"; 31 abort(); 32 default: 33 std::cerr << "Error: Code generator does not support intrinsic function '" 34 << Callee->getName() << "'!\n"; 35 abort(); 36 37 // The default implementation of setjmp/longjmp transforms setjmp into a 38 // noop that always returns zero and longjmp into a call to abort. This 39 // allows code that never longjmps to work correctly. 40 case Intrinsic::setjmp: 41 case Intrinsic::sigsetjmp: 42 if (CI->getType() != Type::VoidTy) 43 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 44 break; 45 46 case Intrinsic::longjmp: 47 case Intrinsic::siglongjmp: 48 // Insert the call to abort 49 new CallInst(M->getOrInsertFunction("abort", Type::VoidTy, 0), "", CI); 50 break; 51 52 case Intrinsic::returnaddress: 53 case Intrinsic::frameaddress: 54 CI->replaceAllUsesWith(ConstantPointerNull::get( 55 cast<PointerType>(CI->getType()))); 56 break; 57 58 case Intrinsic::dbg_stoppoint: 59 case Intrinsic::dbg_region_start: 60 case Intrinsic::dbg_region_end: 61 case Intrinsic::dbg_declare: 62 case Intrinsic::dbg_func_start: 63 if (CI->getType() != Type::VoidTy) 64 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 65 break; // Simply strip out debugging intrinsics 66 67 case Intrinsic::memcpy: { 68 // The memcpy intrinsic take an extra alignment argument that the memcpy 69 // libc function does not. 70 const FunctionType *CFT = Callee->getFunctionType(); 71 FunctionType *FT = 72 FunctionType::get(*CFT->param_begin(), 73 std::vector<const Type*>(CFT->param_begin(), CFT->param_end()-1), 74 false); 75 Function *MemCpy = M->getOrInsertFunction("memcpy", FT); 76 new CallInst(MemCpy, std::vector<Value*>(CI->op_begin()+1, CI->op_end()-1), 77 CI->getName(), CI); 78 break; 79 } 80 case Intrinsic::memmove: { 81 // The memmove intrinsic take an extra alignment argument that the memmove 82 // libc function does not. 83 const FunctionType *CFT = Callee->getFunctionType(); 84 FunctionType *FT = 85 FunctionType::get(*CFT->param_begin(), 86 std::vector<const Type*>(CFT->param_begin(), CFT->param_end()-1), 87 false); 88 Function *MemMove = M->getOrInsertFunction("memmove", FT); 89 new CallInst(MemMove, std::vector<Value*>(CI->op_begin()+1, CI->op_end()-1), 90 CI->getName(), CI); 91 break; 92 } 93 case Intrinsic::memset: { 94 // The memset intrinsic take an extra alignment argument that the memset 95 // libc function does not. 96 const FunctionType *CFT = Callee->getFunctionType(); 97 FunctionType *FT = 98 FunctionType::get(*CFT->param_begin(), 99 std::vector<const Type*>(CFT->param_begin(), CFT->param_end()-1), 100 false); 101 Function *MemSet = M->getOrInsertFunction("memset", FT); 102 new CallInst(MemSet, std::vector<Value*>(CI->op_begin()+1, CI->op_end()-1), 103 CI->getName(), CI); 104 break; 105 } 106 } 107 108 assert(CI->use_empty() && 109 "Lowering should have eliminated any uses of the intrinsic call!"); 110 CI->getParent()->getInstList().erase(CI); 111} 112