From: Chris Lattner Date: Fri, 31 Aug 2007 04:31:45 +0000 (+0000) Subject: add the ability to get the llvm function corresponding to a library builtin. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bef20ac367a09555b30d6eb3847a81ec164caf88;p=clang add the ability to get the llvm function corresponding to a library builtin. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41633 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGBuiltin.cpp b/CodeGen/CGBuiltin.cpp index 833b1882d1..a04557bd00 100644 --- a/CodeGen/CGBuiltin.cpp +++ b/CodeGen/CGBuiltin.cpp @@ -13,6 +13,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Builtins.h" #include "clang/AST/Expr.h" #include "llvm/Constants.h" @@ -45,3 +46,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { return RValue::get(0); } + +RValue CodeGenFunction::EmitBuiltinLibFuncExpr(unsigned BuiltinID, + const CallExpr *E) { + //llvm::Function *Callee = CGM.getBuiltinLibFunction(BuiltinID); + return RValue(); +} diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 3b8d7a20af..12c227bad9 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -325,6 +325,7 @@ public: RValue EmitCallExpr(const CallExpr *E); RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + RValue EmitBuiltinLibFuncExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index 74c7d43e1d..a6a887f90f 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -18,8 +18,7 @@ #include "clang/Basic/TargetInfo.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" +#include "llvm/Module.h" #include "llvm/Intrinsics.h" using namespace clang; using namespace CodeGen; @@ -101,6 +100,41 @@ void CodeGenModule::EmitGlobalVarDeclarator(const FileVarDecl *D) { EmitGlobalVar(D); } +/// getBuiltinLibFunction +llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) { + if (BuiltinFunctions.size() <= BuiltinID) + BuiltinFunctions.resize(BuiltinID); + + // Already available? + llvm::Function *&FunctionSlot = BuiltinFunctions[BuiltinID]; + if (FunctionSlot) + return FunctionSlot; + + assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a lib fn"); + + // Get the name, skip over the __builtin_ prefix. + const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10; + + // Get the type for the builtin. + QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context); + const llvm::FunctionType *Ty = + cast(getTypes().ConvertType(Type)); + + // FIXME: This has a serious problem with code like this: + // void abs() {} + // ... __builtin_abs(x); + // The two versions of abs will collide. The fix is for the builtin to win, + // and for the existing one to be turned into a constantexpr cast of the + // builtin. In the case where the existing one is a static function, it + // should just be renamed. + assert(getModule().getFunction(Name) == 0 && "FIXME: Name collision"); + + // FIXME: param attributes for sext/zext etc. + return FunctionSlot = new llvm::Function(Ty, llvm::Function::ExternalLinkage, + Name, &getModule()); +} + + llvm::Function *CodeGenModule::getMemCpyFn() { if (MemCpyFn) return MemCpyFn; llvm::Intrinsic::ID IID; @@ -114,8 +148,8 @@ llvm::Function *CodeGenModule::getMemCpyFn() { return MemCpyFn = llvm::Intrinsic::getDeclaration(&TheModule, IID); } -llvm::Constant *CodeGenModule::GetAddrOfConstantCFString(const std::string &str) -{ +llvm::Constant *CodeGenModule:: +GetAddrOfConstantCFString(const std::string &str) { llvm::StringMapEntry &Entry = CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]); diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h index 97d6a02f47..af2db80840 100644 --- a/CodeGen/CodeGenModule.h +++ b/CodeGen/CodeGenModule.h @@ -44,6 +44,8 @@ class CodeGenModule { llvm::StringMap CFConstantStringMap; llvm::Constant *CFConstantStringClassRef; + + std::vector BuiltinFunctions; public: CodeGenModule(ASTContext &C, llvm::Module &M); @@ -52,9 +54,15 @@ public: CodeGenTypes &getTypes() { return Types; } llvm::Constant *GetAddrOfGlobalDecl(const Decl *D); + + /// getBuiltinLibFunction - Given a builtin id for a function like + /// "__builtin_fabsf", return a Function* for "fabsf". + /// + llvm::Function *getBuiltinLibFunction(unsigned BuiltinID); llvm::Constant *GetAddrOfConstantCFString(const std::string& str); llvm::Function *getMemCpyFn(); + void EmitFunction(const FunctionDecl *FD); void EmitGlobalVar(const FileVarDecl *D); void EmitGlobalVarDeclarator(const FileVarDecl *D);