Chris Lattner | 3b66ecb | 2003-12-28 08:19:41 +0000 | [diff] [blame] | 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 | |
Chris Lattner | 42450d8 | 2003-12-28 08:30:20 +0000 | [diff] [blame] | 14 | #include "llvm/IntrinsicLowering.h" |
Chris Lattner | 3b66ecb | 2003-12-28 08:19:41 +0000 | [diff] [blame] | 15 | #include "llvm/Constant.h" |
Chris Lattner | 5fe51cc | 2004-02-12 17:01:09 +0000 | [diff] [blame] | 16 | #include "llvm/DerivedTypes.h" |
Chris Lattner | 3b66ecb | 2003-12-28 08:19:41 +0000 | [diff] [blame] | 17 | #include "llvm/Module.h" |
Chris Lattner | 3b66ecb | 2003-12-28 08:19:41 +0000 | [diff] [blame] | 18 | #include "llvm/iOther.h" |
| 19 | using namespace llvm; |
| 20 | |
| 21 | void 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; |
Chris Lattner | 77b1330 | 2004-01-05 05:36:30 +0000 | [diff] [blame] | 51 | |
| 52 | case Intrinsic::dbg_stoppoint: |
| 53 | case Intrinsic::dbg_region_start: |
| 54 | case Intrinsic::dbg_region_end: |
Chris Lattner | f907bac | 2004-01-14 20:41:29 +0000 | [diff] [blame] | 55 | case Intrinsic::dbg_declare: |
Chris Lattner | 77b1330 | 2004-01-05 05:36:30 +0000 | [diff] [blame] | 56 | case Intrinsic::dbg_func_start: |
| 57 | if (CI->getType() != Type::VoidTy) |
| 58 | CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); |
| 59 | break; // Simply strip out debugging intrinsics |
Chris Lattner | 5fe51cc | 2004-02-12 17:01:09 +0000 | [diff] [blame] | 60 | |
| 61 | case Intrinsic::memcpy: { |
| 62 | // The memcpy intrinsic take an extra alignment argument that the memcpy |
| 63 | // libc function does not. |
| 64 | const FunctionType *CFT = Callee->getFunctionType(); |
| 65 | FunctionType *FT = |
| 66 | FunctionType::get(*CFT->param_begin(), |
| 67 | std::vector<const Type*>(CFT->param_begin(), CFT->param_end()-1), |
| 68 | false); |
| 69 | Function *MemCpy = M->getOrInsertFunction("memcpy", FT); |
| 70 | new CallInst(MemCpy, std::vector<Value*>(CI->op_begin()+1, CI->op_end()-1), |
| 71 | CI->getName(), CI); |
| 72 | break; |
| 73 | } |
Chris Lattner | 3b66ecb | 2003-12-28 08:19:41 +0000 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | assert(CI->use_empty() && |
| 77 | "Lowering should have eliminated any uses of the intrinsic call!"); |
| 78 | CI->getParent()->getInstList().erase(CI); |
| 79 | } |