diff options
author | arphaman <arphaman@gmail.com> | 2013-09-14 09:46:56 +0100 |
---|---|---|
committer | arphaman <arphaman@gmail.com> | 2013-09-14 09:46:56 +0100 |
commit | c5c76bd18831fd3fbd8706fd2d3de17cc56cae84 (patch) | |
tree | fb257a50a2c73ff03dee2f96b0dadd1b36e07835 | |
parent | 60c615aa6ef39869b461054f016f439290a1575e (diff) | |
download | flang-c5c76bd18831fd3fbd8706fd2d3de17cc56cae84.tar.gz |
added target info for x86 complex return abi
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 34 | ||||
-rw-r--r-- | lib/CodeGen/CGCall.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 26 | ||||
-rw-r--r-- | test/CodeGen/x86LinuxAggregateABI.f95 | 17 |
7 files changed, 79 insertions, 22 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 49436246de..5d364dd589 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -44,13 +44,15 @@ llvm::Type *CodeGenTypes::ConvertReturnType(QualType T, break; } - ReturnInfo.Kind = T->isComplexType()? CGFunctionInfo::RetInfo::ComplexValue : - CGFunctionInfo::RetInfo::ScalarValue; - + ReturnInfo.Type = T; if(T->isComplexType()) { CGM.getTargetCodeGenInfo().getABIInfo().computeReturnTypeInfo(T, ReturnInfo.ABIInfo); if(ReturnInfo.ABIInfo.hasAggregateReturnType()) return ReturnInfo.ABIInfo.getAggregateReturnType(); + if(ReturnInfo.ABIInfo.getKind() == ABIRetInfo::AggregateValueAsArg) { + ReturnInfo.ReturnArgInfo.ABIInfo = ABIArgInfo(ABIArgInfo::Reference); + return CGM.VoidTy; + } } return ConvertType(T); @@ -108,7 +110,8 @@ void CodeGenTypes::ConvertArgumentTypeForReturnValue(SmallVectorImpl<CGFunctionI SmallVectorImpl<llvm::Type *> &AdditionalArgTypes, QualType T, const CGFunctionInfo::RetInfo &ReturnInfo) { - if(ReturnInfo.ABIInfo.getKind() == ABIRetInfo::CharacterValueAsArg) { + if(ReturnInfo.ABIInfo.getKind() == ABIRetInfo::CharacterValueAsArg || + ReturnInfo.ABIInfo.getKind() == ABIRetInfo::AggregateValueAsArg) { ArgInfo.push_back(ReturnInfo.ReturnArgInfo); ConvertArgumentType(ArgTypes, AdditionalArgTypes, T, ReturnInfo.ReturnArgInfo); @@ -163,17 +166,26 @@ RValueTy CodeGenFunction::EmitCall(llvm::Value *Callee, CallArgList &ArgList, ArrayRef<Expr*> Arguments, bool ReturnsNothing) { - llvm::Value *ResultTemp; + // arguments auto ArgumentInfo = FuncInfo->getArguments(); auto FType = Callee->getType()->isFunctionTy()? cast<llvm::FunctionType>(Callee->getType()) : dyn_cast<llvm::FunctionType>(cast<llvm::PointerType>(Callee->getType())->getPointerElementType()); for(size_t I = 0; I < Arguments.size(); ++I) EmitCallArg(FType->getParamType(ArgList.getOffset()), ArgList, Arguments[I], ArgumentInfo[I]); + + // return value auto RetABIKind = FuncInfo->getReturnInfo().ABIInfo.getKind(); + auto RetType = FuncInfo->getReturnInfo().Type; if(RetABIKind == ABIRetInfo::CharacterValueAsArg) EmitCallArg(ArgList, ArgList.getReturnValueArg().asCharacter(), FuncInfo->getReturnInfo().ReturnArgInfo); + else if(RetABIKind == ABIRetInfo::AggregateValueAsArg) { + auto ResultTemp = CreateTempAlloca(ConvertTypeForMem(RetType), + "complex-return"); + ArgList.addReturnValueArg(ResultTemp); + ArgList.add(ResultTemp); + } auto Result = Builder.CreateCall(Callee, ArgList.createValues(), "call"); @@ -183,7 +195,7 @@ RValueTy CodeGenFunction::EmitCall(llvm::Value *Callee, RetABIKind == ABIRetInfo::Nothing) return RValueTy(); else if(RetABIKind == ABIRetInfo::Value && - FuncInfo->getReturnInfo().Kind == CGFunctionInfo::RetInfo::ComplexValue) { + !RetType.isNull() && RetType->isComplexType()) { auto RetInfo = FuncInfo->getReturnInfo(); if(RetInfo.ABIInfo.hasAggregateReturnType()) { auto T = RetInfo.ABIInfo.getAggregateReturnType(); @@ -193,7 +205,12 @@ RValueTy CodeGenFunction::EmitCall(llvm::Value *Callee, } return ExtractComplexValue(Result); } - else if(RetABIKind == ABIRetInfo::CharacterValueAsArg) + else if(RetABIKind == ABIRetInfo::AggregateValueAsArg) { + if(RetType->isComplexType()) + return EmitComplexLoad(ArgList.getReturnValueArg().asScalar()); + else + llvm_unreachable("unsupported aggregate return ABI"); + } else if(RetABIKind == ABIRetInfo::CharacterValueAsArg) return ArgList.getReturnValueArg(); return Result; } @@ -216,7 +233,8 @@ RValueTy CodeGenFunction::EmitCall(CGFunction Func, auto Result = Builder.CreateCall(Func.getFunction(), ArgList.createValues(), "call"); Result->setCallingConv(FuncInfo->getCallingConv()); - if(FuncInfo->getReturnInfo().Kind == CGFunctionInfo::RetInfo::ComplexValue) + if(!FuncInfo->getReturnInfo().Type.isNull() && + FuncInfo->getReturnInfo().Type->isComplexType()) return ExtractComplexValue(Result); return Result; } diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index ad14d88de8..b1ea770e3b 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -75,9 +75,9 @@ public: ABIRetInfo ABIInfo; ArgInfo ReturnArgInfo; - ValueKind Kind; + QualType Type; - RetInfo() : ABIInfo(ABIRetInfo::Nothing), Kind(ScalarValue) {} + RetInfo() : ABIInfo(ABIRetInfo::Nothing) {} }; private: llvm::FunctionType *Type; diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 4786a66813..e2d370a6a5 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -1,4 +1,4 @@ -//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===// +//===--- CGExprAgg.cpp - Emit LLVM Code from Aggregate Expressions --------===// // // The LLVM Compiler Infrastructure // @@ -92,7 +92,7 @@ llvm::Value *CodeGenFunction::EmitAggregateMember(llvm::Value *Agg, const FieldD } void CodeGenFunction::EmitAggregateReturn(const CGFunctionInfo::RetInfo &Info, llvm::Value *Ptr) { - if(Info.Kind == CGFunctionInfo::RetInfo::ComplexValue) { + if(Info.Type->isComplexType()) { if(Info.ABIInfo.hasAggregateReturnType()) { Builder.CreateRet(Builder.CreateLoad( Builder.CreateBitCast(Ptr, llvm::PointerType::get(Info.ABIInfo.getAggregateReturnType(), 0)))); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index d8b0661bcc..9ef0d28058 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -88,7 +88,9 @@ void CodeGenFunction::EmitFunctionArguments(const FunctionDecl *Func, } // Extra argument for the returned data. - if(Info->getReturnInfo().ABIInfo.getKind() == ABIRetInfo::CharacterValueAsArg) { + auto RetABIKind = Info->getReturnInfo().ABIInfo.getKind(); + if(RetABIKind == ABIRetInfo::CharacterValueAsArg || + RetABIKind == ABIRetInfo::AggregateValueAsArg) { Arg->setName(Func->getName()); ReturnValuePtr = Arg; ++Arg; @@ -160,14 +162,11 @@ void CodeGenFunction::EmitFunctionEpilogue(const FunctionDecl *Func, auto ReturnInfo = Info->getReturnInfo(); if(ReturnInfo.ABIInfo.getKind() == ABIRetInfo::Value) { - switch(ReturnInfo.Kind) { - case CGFunctionInfo::RetInfo::ScalarValue: - Builder.CreateRet(Builder.CreateLoad(RetVar)); - break; - case CGFunctionInfo::RetInfo::ComplexValue: + if(ReturnInfo.Type->isComplexType() || + ReturnInfo.Type->isRecordType()) { EmitAggregateReturn(ReturnInfo, RetVar); - break; - } + } else + Builder.CreateRet(Builder.CreateLoad(RetVar)); } else Builder.CreateRetVoid(); } else diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index fe94917792..8b9a355767 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -198,7 +198,6 @@ CodeGenTypes::GetFunctionType(FortranABI &ABI, } else { ReturnInfo.ABIInfo = ABIRetInfo(ABIRetInfo::Value); - ReturnInfo.Kind = CGFunctionInfo::RetInfo::ScalarValue; RetType = ReturnType.asLLVMType(); } diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 27336cb1a6..0a9bce32ea 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -30,9 +30,29 @@ namespace CodeGen { class DefaultABIInfo : public ABIInfo { public: - void computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const {} + void computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const; }; +void DefaultABIInfo::computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const { + if(!T->isComplexType()) + return; + + Info = ABIRetInfo(ABIRetInfo::AggregateValueAsArg); +} + +/// ABI Info for x86_32 +class X86_32ABIInfo : public ABIInfo { +public: + void computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const; +}; + +void X86_32ABIInfo::computeReturnTypeInfo(QualType T, ABIRetInfo &Info) const { + if(!T->isComplexType()) + return; + + Info = ABIRetInfo(ABIRetInfo::AggregateValueAsArg); +} + /// ABI Info for x86_64 /// NB: works only with x86_64-pc-{linux,darwin} class X86_64ABIInfo : public ABIInfo { @@ -75,6 +95,10 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { TheTargetCodeGenInfo = new TargetCodeGenInfo(new DefaultABIInfo()); break; + case llvm::Triple::x86: + TheTargetCodeGenInfo = new TargetCodeGenInfo(new X86_32ABIInfo()); + break; + case llvm::Triple::x86_64: TheTargetCodeGenInfo = new TargetCodeGenInfo(new X86_64ABIInfo(*this)); break; diff --git a/test/CodeGen/x86LinuxAggregateABI.f95 b/test/CodeGen/x86LinuxAggregateABI.f95 new file mode 100644 index 0000000000..29bbe5efb2 --- /dev/null +++ b/test/CodeGen/x86LinuxAggregateABI.f95 @@ -0,0 +1,17 @@ +! RUN: %flang -triple "i686-unknown-linux" -emit-llvm -o - %s | %file_check %s + +complex function foo() ! CHECK: define void @foo_({ float, float }* + foo = (1.0, 2.0) +end + +complex(8) function bar() ! CHECK: define void @bar_({ double, double }* + bar = 0.0 +end + +program test + complex c + complex(8) dc + + c = foo() + dc = bar() +end |