From 17b708d61827cd86278e9580b041dd6cbadf07d3 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 9 Sep 2008 23:27:19 +0000 Subject: [PATCH] Move ABI specific code for functions / calls to CGCall.cpp: - Factor out EmitFunction{Pro,Epi}log git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56031 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGCall.cpp | 102 ++++++++++++++++++++++++++++++++ lib/CodeGen/CGExpr.cpp | 55 ----------------- lib/CodeGen/CodeGenFunction.cpp | 40 +------------ lib/CodeGen/CodeGenFunction.h | 13 +++- 4 files changed, 117 insertions(+), 93 deletions(-) diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index a3a330e5e0..89004325c1 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -114,3 +114,105 @@ void CGCallInfo::constructParamAttrList(ParamAttrListType &PAL) const { // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. constructParamAttrListInternal(0, ArgTypes, PAL); } + +/***/ + +void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, + QualType RetTy, + const FunctionArgList &Args) { + // Emit allocs for param decls. Give the LLVM Argument nodes names. + llvm::Function::arg_iterator AI = Fn->arg_begin(); + + // Name the struct return argument. + if (hasAggregateLLVMType(RetTy)) { + AI->setName("agg.result"); + ++AI; + } + + for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); + i != e; ++i, ++AI) { + const VarDecl *Arg = i->first; + QualType T = i->second; + assert(AI != Fn->arg_end() && "Argument mismatch!"); + llvm::Value* V = AI; + if (!getContext().typesAreCompatible(T, Arg->getType())) { + // This must be a promotion, for something like + // "void a(x) short x; {..." + V = EmitScalarConversion(V, T, Arg->getType()); + } + EmitParmDecl(*Arg, V); + } + assert(AI == Fn->arg_end() && "Argument mismatch!"); +} + +void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, + llvm::Value *ReturnValue) { + if (!ReturnValue) { + Builder.CreateRetVoid(); + } else { + if (!hasAggregateLLVMType(RetTy)) { + Builder.CreateRet(Builder.CreateLoad(ReturnValue)); + } else if (RetTy->isAnyComplexType()) { + EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy); + Builder.CreateRetVoid(); + } else { + EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy); + Builder.CreateRetVoid(); + } + } +} + +RValue CodeGenFunction::EmitCall(llvm::Value *Callee, + QualType ResultType, + const CallArgList &CallArgs) { + // FIXME: Factor out code to load from args into locals into target. + llvm::SmallVector Args; + llvm::Value *TempArg0 = 0; + + // Handle struct-return functions by passing a pointer to the + // location that we would like to return into. + if (hasAggregateLLVMType(ResultType)) { + // Create a temporary alloca to hold the result of the call. :( + TempArg0 = CreateTempAlloca(ConvertType(ResultType)); + Args.push_back(TempArg0); + } + + for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); + I != E; ++I) { + RValue RV = I->first; + if (RV.isScalar()) { + Args.push_back(RV.getScalarVal()); + } else if (RV.isComplex()) { + // Make a temporary alloca to pass the argument. + Args.push_back(CreateTempAlloca(ConvertType(I->second))); + StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); + } else { + Args.push_back(RV.getAggregateAddr()); + } + } + + llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); + CGCallInfo CallInfo(ResultType, CallArgs); + + CodeGen::ParamAttrListType ParamAttrList; + CallInfo.constructParamAttrList(ParamAttrList); + CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), + ParamAttrList.size())); + + if (const llvm::Function *F = dyn_cast(Callee)) + CI->setCallingConv(F->getCallingConv()); + if (CI->getType() != llvm::Type::VoidTy) + CI->setName("call"); + else if (ResultType->isAnyComplexType()) + return RValue::getComplex(LoadComplexFromAddr(TempArg0, false)); + else if (hasAggregateLLVMType(ResultType)) + // Struct return. + return RValue::getAggregate(TempArg0); + else { + // void return. + assert(ResultType->isVoidType() && "Should only have a void expr here"); + CI = 0; + } + + return RValue::get(CI); +} diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 1c10171194..f8dc9dcd43 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -856,58 +856,3 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, return EmitCall(Callee, ResultType, Args); } - -RValue CodeGenFunction::EmitCall(llvm::Value *Callee, - QualType ResultType, - const CallArgList &CallArgs) { - // FIXME: Factor out code to load from args into locals into target. - llvm::SmallVector Args; - llvm::Value *TempArg0 = 0; - - // Handle struct-return functions by passing a pointer to the - // location that we would like to return into. - if (hasAggregateLLVMType(ResultType)) { - // Create a temporary alloca to hold the result of the call. :( - TempArg0 = CreateTempAlloca(ConvertType(ResultType)); - Args.push_back(TempArg0); - } - - for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end(); - I != E; ++I) { - RValue RV = I->first; - if (RV.isScalar()) { - Args.push_back(RV.getScalarVal()); - } else if (RV.isComplex()) { - // Make a temporary alloca to pass the argument. - Args.push_back(CreateTempAlloca(ConvertType(I->second))); - StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); - } else { - Args.push_back(RV.getAggregateAddr()); - } - } - - llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); - CGCallInfo CallInfo(ResultType, CallArgs); - - CodeGen::ParamAttrListType ParamAttrList; - CallInfo.constructParamAttrList(ParamAttrList); - CI->setParamAttrs(llvm::PAListPtr::get(ParamAttrList.begin(), - ParamAttrList.size())); - - if (const llvm::Function *F = dyn_cast(Callee)) - CI->setCallingConv(F->getCallingConv()); - if (CI->getType() != llvm::Type::VoidTy) - CI->setName("call"); - else if (ResultType->isAnyComplexType()) - return RValue::getComplex(LoadComplexFromAddr(TempArg0, false)); - else if (hasAggregateLLVMType(ResultType)) - // Struct return. - return RValue::getAggregate(TempArg0); - else { - // void return. - assert(ResultType->isVoidType() && "Should only have a void expr here"); - CI = 0; - } - - return RValue::get(CI); -} diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index a934e43e48..8b3dd84bb8 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -86,21 +86,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - // Emit code to actually return. + // Emit function epilog (to return). Builder.SetInsertPoint(ReturnBlock); - if (!ReturnValue) { - Builder.CreateRetVoid(); - } else { - if (!hasAggregateLLVMType(FnRetTy)) { - Builder.CreateRet(Builder.CreateLoad(ReturnValue)); - } else if (FnRetTy->isAnyComplexType()) { - EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, FnRetTy); - Builder.CreateRetVoid(); - } else { - EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, FnRetTy); - Builder.CreateRetVoid(); - } - } + EmitFunctionEpilog(FnRetTy, ReturnValue); // Remove the AllocaInsertPt instruction, which is just a convenience for us. AllocaInsertPt->eraseFromParent(); @@ -146,29 +134,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, } } - // Emit allocs for param decls. Give the LLVM Argument nodes names. - llvm::Function::arg_iterator AI = CurFn->arg_begin(); - - // Name the struct return argument. - if (hasAggregateLLVMType(FnRetTy)) { - AI->setName("agg.result"); - ++AI; - } - - for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); - i != e; ++i, ++AI) { - const VarDecl *Arg = i->first; - QualType T = i->second; - assert(AI != CurFn->arg_end() && "Argument mismatch!"); - llvm::Value* V = AI; - if (!getContext().typesAreCompatible(T, Arg->getType())) { - // This must be a promotion, for something like - // "void a(x) short x; {..." - V = EmitScalarConversion(V, T, Arg->getType()); - } - EmitParmDecl(*Arg, V); - } - assert(AI == CurFn->arg_end() && "Argument mismatch!"); + EmitFunctionProlog(CurFn, FnRetTy, Args); } void CodeGenFunction::GenerateCode(const FunctionDecl *FD, diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index cef6503eeb..5054b56d21 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -137,7 +137,18 @@ public: llvm::Function *Fn, const FunctionArgList &Args); void FinishFunction(SourceLocation EndLoc=SourceLocation()); - + + /// EmitFunctionProlog - Emit the target specific LLVM code to load + /// the arguments for the given function. This is also responsible + /// for naming the LLVM function arguments. + void EmitFunctionProlog(llvm::Function *Fn, QualType RetTy, + const FunctionArgList &Args); + + /// EmitFunctionEpilog - Emit the target specific LLVM code to + /// return the given temporary. + void EmitFunctionEpilog(QualType RetTy, + llvm::Value *ReturnValue); + const llvm::Type *ConvertType(QualType T); /// LoadObjCSelf - Load the value of self. This function is only -- 2.40.0