[llvm-commits] [llvm-gcc-4.2] r50398 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Chris Lattner
sabre at nondot.org
Mon Apr 28 22:54:46 PDT 2008
Author: lattner
Date: Tue Apr 29 00:54:45 2008
New Revision: 50398
URL: http://llvm.org/viewvc/llvm-project?rev=50398&view=rev
Log:
Implement support for turning inline asms with multiple results into
a multiple return value call. This fixes the last part of PR2094.
Testcase here: llvm/test/CFrontend/inline-asm-mrv.c
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=50398&r1=50397&r2=50398&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Apr 29 00:54:45 2008
@@ -3794,8 +3794,8 @@
std::string ConstraintStr;
// StoreCallResultAddr - The pointer to store the result of the call through.
- Value *StoreCallResultAddr = 0;
- const Type *CallResultType = Type::VoidTy;
+ SmallVector<Value *, 4> StoreCallResultAddrs;
+ SmallVector<const Type *, 4> CallResultTypes;
// Process outputs.
int ValNum = 0;
@@ -3856,13 +3856,11 @@
cast<PointerType>(Dest.Ptr->getType())->getElementType();
assert(!Dest.isBitfield() && "Cannot assign into a bitfield!");
- if (ConstraintStr.empty() && !AllowsMem && // Reg dest and no output yet?
- DestValTy->isFirstClassType()) {
- assert(StoreCallResultAddr == 0 && "Already have a result val?");
- StoreCallResultAddr = Dest.Ptr;
+ if (!AllowsMem && DestValTy->isFirstClassType()) { // Reg dest -> asm return
+ StoreCallResultAddrs.push_back(Dest.Ptr);
ConstraintStr += ",=";
ConstraintStr += SimplifiedConstraint;
- CallResultType = DestValTy;
+ CallResultTypes.push_back(DestValTy);
} else {
ConstraintStr += ",=*";
ConstraintStr += SimplifiedConstraint;
@@ -3989,6 +3987,17 @@
}
}
+ const Type *CallResultType;
+ switch (CallResultTypes.size()) {
+ case 0: CallResultType = Type::VoidTy; break;
+ case 1: CallResultType = CallResultTypes[0]; break;
+ default:
+ std::vector<const Type*> TmpVec(CallResultTypes.begin(),
+ CallResultTypes.end());
+ CallResultType = StructType::get(TmpVec);
+ break;
+ }
+
const FunctionType *FTy =
FunctionType::get(CallResultType, CallArgTypes, false);
@@ -4005,12 +4014,18 @@
Value *Asm = InlineAsm::get(FTy, NewAsmStr, ConstraintStr,
ASM_VOLATILE_P(exp) || !ASM_OUTPUTS(exp));
CallInst *CV = Builder.CreateCall(Asm, CallOps.begin(), CallOps.end(),
- StoreCallResultAddr ? "tmp" : "");
+ CallResultTypes.empty() ? "" : "asmtmp");
CV->setDoesNotThrow();
// If the call produces a value, store it into the destination.
- if (StoreCallResultAddr)
- Builder.CreateStore(CV, StoreCallResultAddr);
+ if (StoreCallResultAddrs.size() == 1)
+ Builder.CreateStore(CV, StoreCallResultAddrs[0]);
+ else if (unsigned NumResults = StoreCallResultAddrs.size()) {
+ for (unsigned i = 0; i != NumResults; ++i) {
+ Value *ValI = Builder.CreateGetResult(CV, i, "asmresult");
+ Builder.CreateStore(ValI, StoreCallResultAddrs[i]);
+ }
+ }
// Give the backend a chance to upgrade the inline asm to LLVM code. This
// handles some common cases that LLVM has intrinsics for, e.g. x86 bswap ->
More information about the llvm-commits
mailing list