[cfe-commits] r56046 - /cfe/trunk/lib/CodeGen/CGCall.cpp
Daniel Dunbar
daniel at zuster.org
Tue Sep 9 19:41:04 PDT 2008
Author: ddunbar
Date: Tue Sep 9 21:41:04 2008
New Revision: 56046
URL: http://llvm.org/viewvc/llvm-project?rev=56046&view=rev
Log:
Add ABIArgInfo class to encapsulate ABI decision of how to lower types
to LLVM.
- Will move to target sometime soon.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=56046&r1=56045&r2=56046&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Sep 9 21:41:04 2008
@@ -76,14 +76,57 @@
/***/
+class ABIArgInfo {
+public:
+ enum Kind {
+ Default,
+ StructRet, // Only valid for struct return types
+ Coerce // Only valid for return types
+ };
+
+private:
+ Kind TheKind;
+ QualType TypeData;
+
+ ABIArgInfo(Kind K, QualType TD) : TheKind(K),
+ TypeData(TD) {}
+public:
+ static ABIArgInfo getDefault() {
+ return ABIArgInfo(Default, QualType());
+ }
+ static ABIArgInfo getStructRet() {
+ return ABIArgInfo(StructRet, QualType());
+ }
+ static ABIArgInfo getCoerce(QualType T) {
+ return ABIArgInfo(Coerce, T);
+ }
+
+ Kind getKind() const { return TheKind; }
+ bool isDefault() const { return TheKind == Default; }
+ bool isStructRet() const { return TheKind == StructRet; }
+ bool isCoerce() const { return TheKind == Coerce; }
+};
+
+/***/
+
+static ABIArgInfo classifyReturnType(QualType RetTy) {
+ if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+ return ABIArgInfo::getStructRet();
+ } else {
+ return ABIArgInfo::getDefault();
+ }
+}
+
+/***/
+
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
- return CodeGenFunction::hasAggregateLLVMType(RetTy);
+ return classifyReturnType(RetTy).isStructRet();
}
void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
- ArgTypeIterator begin,
- ArgTypeIterator end,
- ParamAttrListType &PAL) {
+ ArgTypeIterator begin,
+ ArgTypeIterator end,
+ ParamAttrListType &PAL) {
unsigned FuncAttrs = 0;
if (TargetDecl) {
@@ -93,19 +136,31 @@
FuncAttrs |= llvm::ParamAttr::NoReturn;
}
- QualType ResTy = *begin;
+ QualType RetTy = *begin;
unsigned Index = 1;
- if (ReturnTypeUsesSret(ResTy)) {
+ ABIArgInfo ResAI = classifyReturnType(RetTy);
+ switch (ResAI.getKind()) {
+ case ABIArgInfo::Default:
+ if (RetTy->isPromotableIntegerType()) {
+ if (RetTy->isSignedIntegerType()) {
+ FuncAttrs |= llvm::ParamAttr::SExt;
+ } else if (RetTy->isUnsignedIntegerType()) {
+ FuncAttrs |= llvm::ParamAttr::ZExt;
+ }
+ }
+ break;
+
+ case ABIArgInfo::StructRet:
PAL.push_back(llvm::ParamAttrsWithIndex::get(Index,
llvm::ParamAttr::StructRet));
++Index;
- } else if (ResTy->isPromotableIntegerType()) {
- if (ResTy->isSignedIntegerType()) {
- FuncAttrs |= llvm::ParamAttr::SExt;
- } else if (ResTy->isUnsignedIntegerType()) {
- FuncAttrs |= llvm::ParamAttr::ZExt;
- }
+ break;
+
+ case ABIArgInfo::Coerce:
+ assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
+ break;
}
+
if (FuncAttrs)
PAL.push_back(llvm::ParamAttrsWithIndex::get(0, FuncAttrs));
for (++begin; begin != end; ++begin, ++Index) {
@@ -132,7 +187,7 @@
llvm::Function::arg_iterator AI = Fn->arg_begin();
// Name the struct return argument.
- if (hasAggregateLLVMType(RetTy)) {
+ if (CGM.ReturnTypeUsesSret(RetTy)) {
AI->setName("agg.result");
++AI;
}
@@ -155,23 +210,36 @@
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 {
+ llvm::Value *RV = 0;
+
+ // Functions with no result always return void.
+ if (ReturnValue) {
+ ABIArgInfo RetAI = classifyReturnType(RetTy);
+
+ switch (RetAI.getKind()) {
+ case ABIArgInfo::StructRet:
EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
- Builder.CreateRetVoid();
+ break;
+
+ case ABIArgInfo::Default:
+ RV = Builder.CreateLoad(ReturnValue);
+ break;
+
+ case ABIArgInfo::Coerce:
+ assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
+ break;
}
}
+
+ if (RV) {
+ Builder.CreateRet(RV);
+ } else {
+ Builder.CreateRetVoid();
+ }
}
RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
- QualType ResultType,
+ QualType RetTy,
const CallArgList &CallArgs) {
// FIXME: Factor out code to load from args into locals into target.
llvm::SmallVector<llvm::Value*, 16> Args;
@@ -179,10 +247,20 @@
// Handle struct-return functions by passing a pointer to the
// location that we would like to return into.
- if (hasAggregateLLVMType(ResultType)) {
+ ABIArgInfo RetAI = classifyReturnType(RetTy);
+ switch (RetAI.getKind()) {
+ case ABIArgInfo::StructRet:
// Create a temporary alloca to hold the result of the call. :(
- TempArg0 = CreateTempAlloca(ConvertType(ResultType));
+ TempArg0 = CreateTempAlloca(ConvertType(RetTy));
Args.push_back(TempArg0);
+ break;
+
+ case ABIArgInfo::Default:
+ break;
+
+ case ABIArgInfo::Coerce:
+ assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
+ break;
}
for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
@@ -200,7 +278,7 @@
}
llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size());
- CGCallInfo CallInfo(ResultType, CallArgs);
+ CGCallInfo CallInfo(RetTy, CallArgs);
// FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set.
CodeGen::ParamAttrListType ParamAttrList;
@@ -214,16 +292,23 @@
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;
+
+ switch (RetAI.getKind()) {
+ case ABIArgInfo::StructRet:
+ if (RetTy->isAnyComplexType())
+ return RValue::getComplex(LoadComplexFromAddr(TempArg0, false));
+ else
+ // Struct return.
+ return RValue::getAggregate(TempArg0);
+
+ case ABIArgInfo::Default:
+ return RValue::get(RetTy->isVoidType() ? 0 : CI);
+
+ case ABIArgInfo::Coerce:
+ assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
+ return RValue::get(0);
}
-
- return RValue::get(CI);
+
+ assert(0 && "Unhandled ABIArgInfo::Kind");
+ return RValue::get(0);
}
More information about the cfe-commits
mailing list