From: Anders Carlsson Date: Sun, 9 Dec 2007 21:20:04 +0000 (+0000) Subject: Generate code for target specific intrinsics. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ca6fcfad547dcec3fdd17790b4fab0918df74b37;p=clang Generate code for target specific intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44744 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGBuiltin.cpp b/CodeGen/CGBuiltin.cpp index 8f9b7b3d74..14e13e6ffc 100644 --- a/CodeGen/CGBuiltin.cpp +++ b/CodeGen/CGBuiltin.cpp @@ -13,6 +13,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "clang/Basic/TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Builtins.h" #include "clang/AST/Expr.h" @@ -23,11 +24,61 @@ using namespace clang; using namespace CodeGen; +using namespace llvm; + RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { switch (BuiltinID) { - default: + default: { if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) return EmitCallExpr(CGM.getBuiltinLibFunction(BuiltinID), E); + + // See if we have a target specific intrinsic. + llvm::Intrinsic::ID IntrinsicID; + const char *TargetPrefix = Target.getTargetPrefix(); + const char *BuiltinName = getContext().BuiltinInfo.GetName(BuiltinID); +#define GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN +#include "llvm/Intrinsics.gen" +#undef GET_LLVM_INTRINSIC_FOR_GCC_BUILTIN + + if (IntrinsicID != Intrinsic::not_intrinsic) { + llvm::SmallVector Args; + + llvm::Function *F = llvm::Intrinsic::getDeclaration(&CGM.getModule(), + IntrinsicID); + + const llvm::FunctionType *FTy = F->getFunctionType(); + + for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { + llvm::Value *ArgValue = EmitScalarExpr(E->getArg(i)); + + // If the intrinsic arg type is different from the builtin arg type + // we need to do a bit cast. + const llvm::Type *PTy = FTy->getParamType(i); + if (PTy != ArgValue->getType()) { + assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && + "Must be able to losslessly bit cast to param"); + ArgValue = Builder.CreateBitCast(ArgValue, PTy); + } + + Args.push_back(ArgValue); + } + + llvm::Value *V = Builder.CreateCall(F, &Args[0], &Args[0] + Args.size()); + + QualType BuiltinRetType = E->getType(); + + const llvm::Type *RetTy = BuiltinRetType->isVoidType() ? + llvm::Type::VoidTy : ConvertType(BuiltinRetType); + + if (RetTy != V->getType()) { + assert(V->getType()->canLosslesslyBitCastTo(RetTy) && + "Must be able to losslessly bit cast result type"); + + V = Builder.CreateBitCast(V, RetTy); + } + + return RValue::get(V); + } WarnUnsupported(E, "builtin function"); @@ -35,7 +86,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (hasAggregateLLVMType(E->getType())) return RValue::getAggregate(CreateTempAlloca(ConvertType(E->getType()))); return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); - + } case Builtin::BI__builtin___CFStringMakeConstantString: { const Expr *Arg = E->getArg(0);