[cfe-commits] r56051 - /cfe/trunk/lib/CodeGen/CGCall.cpp
Daniel Dunbar
daniel at zuster.org
Wed Sep 10 00:04:10 PDT 2008
Author: ddunbar
Date: Wed Sep 10 02:04:09 2008
New Revision: 56051
URL: http://llvm.org/viewvc/llvm-project?rev=56051&view=rev
Log:
Implement ABIArgType::Coerce support.
- As a test, enable basic usage for some common x86-32 cases. This
increases our x86-32 compliance (on other targets our compliance
will just be broken in a different way).
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=56051&r1=56050&r2=56051&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Sep 10 02:04:09 2008
@@ -104,18 +104,19 @@
private:
Kind TheKind;
- QualType TypeData;
+ const llvm::Type *TypeData;
- ABIArgInfo(Kind K, QualType TD) : TheKind(K),
- TypeData(TD) {}
+ ABIArgInfo(Kind K, const llvm::Type *TD) : TheKind(K),
+ TypeData(TD) {}
public:
static ABIArgInfo getDefault() {
- return ABIArgInfo(Default, QualType());
+ return ABIArgInfo(Default, 0);
}
static ABIArgInfo getStructRet() {
- return ABIArgInfo(StructRet, QualType());
+ return ABIArgInfo(StructRet, 0);
}
- static ABIArgInfo getCoerce(QualType T) {
+ static ABIArgInfo getCoerce(const llvm::Type *T) {
+ assert(T->isSingleValueType() && "Can only coerce to simple types");
return ABIArgInfo(Coerce, T);
}
@@ -125,7 +126,7 @@
bool isCoerce() const { return TheKind == Coerce; }
// Coerce accessors
- QualType getCoerceToType() const {
+ const llvm::Type *getCoerceToType() const {
assert(TheKind == Coerce && "Invalid kind!");
return TypeData;
}
@@ -133,9 +134,21 @@
/***/
-static ABIArgInfo classifyReturnType(QualType RetTy) {
+static ABIArgInfo classifyReturnType(QualType RetTy,
+ ASTContext &Context) {
if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
- return ABIArgInfo::getStructRet();
+ uint64_t Size = Context.getTypeSize(RetTy);
+ if (Size == 8) {
+ return ABIArgInfo::getCoerce(llvm::Type::Int8Ty);
+ } else if (Size == 16) {
+ return ABIArgInfo::getCoerce(llvm::Type::Int16Ty);
+ } else if (Size == 32) {
+ return ABIArgInfo::getCoerce(llvm::Type::Int32Ty);
+ } else if (Size == 64) {
+ return ABIArgInfo::getCoerce(llvm::Type::Int64Ty);
+ } else {
+ return ABIArgInfo::getStructRet();
+ }
} else {
return ABIArgInfo::getDefault();
}
@@ -161,7 +174,7 @@
const llvm::Type *ResultType = 0;
QualType RetTy = *begin;
- ABIArgInfo RetAI = classifyReturnType(RetTy);
+ ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
switch (RetAI.getKind()) {
case ABIArgInfo::Default:
if (RetTy->isVoidType()) {
@@ -179,8 +192,7 @@
}
case ABIArgInfo::Coerce:
- ResultType = llvm::Type::VoidTy;
- ArgTys.push_back(ConvertType(RetAI.getCoerceToType()));
+ ResultType = RetAI.getCoerceToType();
break;
}
@@ -196,9 +208,8 @@
return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
}
-// FIXME: This can die now?
bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) {
- return classifyReturnType(RetTy).isStructRet();
+ return classifyReturnType(RetTy, getContext()).isStructRet();
}
void CodeGenModule::ConstructParamAttrList(const Decl *TargetDecl,
@@ -216,7 +227,7 @@
QualType RetTy = *begin;
unsigned Index = 1;
- ABIArgInfo RetAI = classifyReturnType(RetTy);
+ ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
switch (RetAI.getKind()) {
case ABIArgInfo::Default:
if (RetTy->isPromotableIntegerType()) {
@@ -235,7 +246,6 @@
break;
case ABIArgInfo::Coerce:
- assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
break;
}
@@ -292,7 +302,7 @@
// Functions with no result always return void.
if (ReturnValue) {
- ABIArgInfo RetAI = classifyReturnType(RetTy);
+ ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
switch (RetAI.getKind()) {
case ABIArgInfo::StructRet:
@@ -303,9 +313,11 @@
RV = Builder.CreateLoad(ReturnValue);
break;
- case ABIArgInfo::Coerce:
- assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
- break;
+ case ABIArgInfo::Coerce: {
+ const llvm::Type *CoerceToPTy =
+ llvm::PointerType::getUnqual(RetAI.getCoerceToType());
+ RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy));
+ }
}
}
@@ -325,7 +337,7 @@
// Handle struct-return functions by passing a pointer to the
// location that we would like to return into.
- ABIArgInfo RetAI = classifyReturnType(RetTy);
+ ABIArgInfo RetAI = classifyReturnType(RetTy, getContext());
switch (RetAI.getKind()) {
case ABIArgInfo::StructRet:
// Create a temporary alloca to hold the result of the call. :(
@@ -334,10 +346,7 @@
break;
case ABIArgInfo::Default:
- break;
-
case ABIArgInfo::Coerce:
- assert(0 && "FIXME: ABIArgInfo::Coerce not handled\n");
break;
}
@@ -382,9 +391,13 @@
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);
+ case ABIArgInfo::Coerce: {
+ const llvm::Type *CoerceToPTy =
+ llvm::PointerType::getUnqual(RetAI.getCoerceToType());
+ llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp");
+ Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy));
+ return RValue::getAggregate(V);
+ }
}
assert(0 && "Unhandled ABIArgInfo::Kind");
More information about the cfe-commits
mailing list