From 0979ca7e3e8ff1bb3f38f7b93a02db2e1704333c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 9 May 2004 04:29:57 +0000 Subject: [PATCH] Implement the AddPrototypes method git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13432 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/IntrinsicLowering.cpp | 44 ++++++++++++++++++++++++++++++- lib/VMCore/IntrinsicLowering.cpp | 44 ++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index b199ad38331..072c41520bf 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -18,6 +18,18 @@ #include "llvm/iOther.h" using namespace llvm; +template +static Function *EnsureFunctionExists(Module &M, const char *Name, + ArgIt ArgBegin, ArgIt ArgEnd, + const Type *RetTy) { + if (Function *F = M.getNamedFunction(Name)) return F; + // It doesn't already exist in the program, insert a new definition now. + std::vector ParamTys; + for (ArgIt I = ArgBegin; I != ArgEnd; ++I) + ParamTys.push_back(I->getType()); + return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); +} + /// ReplaceCallWith - This function is used when we want to lower an intrinsic /// call to a call of an external function. This handles hard cases such as /// when there was already a prototype for the external function, and if that @@ -39,7 +51,7 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, FCache = M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false)); } - } + } const FunctionType *FT = FCache->getFunctionType(); std::vector Operands; @@ -60,6 +72,36 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, return new CallInst(FCache, Operands, Name, CI); } +void DefaultIntrinsicLowering::AddPrototypes(Module &M) { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->isExternal() && !I->use_empty()) + switch (I->getIntrinsicID()) { + default: break; + case Intrinsic::setjmp: + EnsureFunctionExists(M, "setjmp", I->abegin(), I->aend(), Type::IntTy); + break; + case Intrinsic::longjmp: + EnsureFunctionExists(M, "longjmp", I->abegin(), I->aend(),Type::VoidTy); + break; + case Intrinsic::siglongjmp: + EnsureFunctionExists(M, "abort", I->aend(), I->aend(), Type::VoidTy); + break; + case Intrinsic::memcpy: + EnsureFunctionExists(M, "memcpy", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memmove: + EnsureFunctionExists(M, "memmove", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memset: + EnsureFunctionExists(M, "memset", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + + } + +} void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { Function *Callee = CI->getCalledFunction(); diff --git a/lib/VMCore/IntrinsicLowering.cpp b/lib/VMCore/IntrinsicLowering.cpp index b199ad38331..072c41520bf 100644 --- a/lib/VMCore/IntrinsicLowering.cpp +++ b/lib/VMCore/IntrinsicLowering.cpp @@ -18,6 +18,18 @@ #include "llvm/iOther.h" using namespace llvm; +template +static Function *EnsureFunctionExists(Module &M, const char *Name, + ArgIt ArgBegin, ArgIt ArgEnd, + const Type *RetTy) { + if (Function *F = M.getNamedFunction(Name)) return F; + // It doesn't already exist in the program, insert a new definition now. + std::vector ParamTys; + for (ArgIt I = ArgBegin; I != ArgEnd; ++I) + ParamTys.push_back(I->getType()); + return M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false)); +} + /// ReplaceCallWith - This function is used when we want to lower an intrinsic /// call to a call of an external function. This handles hard cases such as /// when there was already a prototype for the external function, and if that @@ -39,7 +51,7 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, FCache = M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false)); } - } + } const FunctionType *FT = FCache->getFunctionType(); std::vector Operands; @@ -60,6 +72,36 @@ static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, return new CallInst(FCache, Operands, Name, CI); } +void DefaultIntrinsicLowering::AddPrototypes(Module &M) { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->isExternal() && !I->use_empty()) + switch (I->getIntrinsicID()) { + default: break; + case Intrinsic::setjmp: + EnsureFunctionExists(M, "setjmp", I->abegin(), I->aend(), Type::IntTy); + break; + case Intrinsic::longjmp: + EnsureFunctionExists(M, "longjmp", I->abegin(), I->aend(),Type::VoidTy); + break; + case Intrinsic::siglongjmp: + EnsureFunctionExists(M, "abort", I->aend(), I->aend(), Type::VoidTy); + break; + case Intrinsic::memcpy: + EnsureFunctionExists(M, "memcpy", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memmove: + EnsureFunctionExists(M, "memmove", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + case Intrinsic::memset: + EnsureFunctionExists(M, "memset", I->abegin(), --I->aend(), + I->abegin()->getType()); + break; + + } + +} void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { Function *Callee = CI->getCalledFunction(); -- 2.34.1