diff options
author | Dan Gohman <gohman@apple.com> | 2008-07-23 00:34:11 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-07-23 00:34:11 +0000 |
commit | fc74abfba5128544a750fce22fdf13eb0403e3ce (patch) | |
tree | 36ed972103bbbb170370e4e6688787ed5f1f9ac8 | |
parent | 5e6ebaf4d1d3043d3428b65ee8054c71c24af930 (diff) |
Enable first-class aggregates support.
Remove the GetResultInst instruction. It is still accepted in LLVM assembly
and bitcode, where it is now auto-upgraded to ExtractValueInst. Also, remove
support for return instructions with multiple values. These are auto-upgraded
to use InsertValueInst instructions.
The IRBuilder still accepts multiple-value returns, and auto-upgrades them
to InsertValueInst instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53941 91177308-0d34-0410-b5e6-96231b3b80d8
29 files changed, 168 insertions, 559 deletions
diff --git a/include/llvm/AutoUpgrade.h b/include/llvm/AutoUpgrade.h index 023587790f..3a97353ac9 100644 --- a/include/llvm/AutoUpgrade.h +++ b/include/llvm/AutoUpgrade.h @@ -35,12 +35,6 @@ namespace llvm { /// so that it can update all calls to the old function. void UpgradeCallsToIntrinsic(Function* F); - /// This is an auto-upgrade hook for mutiple-value return statements. - /// This function auto-upgrades all such return statements in the given - /// function to use aggregate return values built with insertvalue - /// instructions. - void UpgradeMultipleReturnValues(Function *F); - } // End llvm namespace #endif diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index ef7f870c1a..50af9d5dd6 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -202,6 +202,7 @@ namespace bitc { // this is so information only available in the pointer type (e.g. address // spaces) is retained. FUNC_CODE_INST_STORE2 = 24, // STORE: [ptrty,ptr,val, align, vol] + // FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0 FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n] FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands] FUNC_CODE_INST_INSERTVAL = 27 // INSERTVAL: [n x operands] diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index 0a3fbed804..c8dd4e6ef1 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -117,7 +117,6 @@ public: I->getOpcode() == Instruction::Free || I->getOpcode() == Instruction::Load || I->getOpcode() == Instruction::VAArg || - I->getOpcode() == Instruction::GetResult || I->getOpcode() == Instruction::ExtractValue || (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd); } diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 2189c86cfb..dcc22e51c2 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -164,12 +164,10 @@ HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value - //from aggregate result -HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(53, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(54, VICmp , VICmpInst ) // Vec Int comparison instruction. -HANDLE_OTHER_INST(55, VFCmp , VFCmpInst ) // Vec FP point comparison instr. +HANDLE_OTHER_INST(51, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(52, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(53, VICmp , VICmpInst ) // Vec Int comparison instruction. +HANDLE_OTHER_INST(54, VFCmp , VFCmpInst ) // Vec FP point comparison instr. LAST_OTHER_INST(55) diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index d6252932fa..41daca3233 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -2000,7 +2000,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value) /// class ReturnInst : public TerminatorInst { ReturnInst(const ReturnInst &RI); - void init(Value * const* retVals, unsigned N); private: // ReturnInst constructors: @@ -2011,16 +2010,11 @@ private: // ReturnInst(Value* X, Inst *I) - 'ret X' instruction, insert before I // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of B // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of B - // ReturnInst(Value* X, N) - 'ret X,X+1...X+N-1' instruction - // ReturnInst(Value* X, N, Inst *I) - 'ret X,X+1...X+N-1', insert before I - // ReturnInst(Value* X, N, BB *B) - 'ret X,X+1...X+N-1', insert @ end of B // // NOTE: If the Value* passed is of type void then the constructor behaves as // if it was passed NULL. explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0); ReturnInst(Value *retVal, BasicBlock *InsertAtEnd); - ReturnInst(Value * const* retVals, unsigned N, Instruction *InsertBefore = 0); - ReturnInst(Value * const* retVals, unsigned N, BasicBlock *InsertAtEnd); explicit ReturnInst(BasicBlock *InsertAtEnd); public: static ReturnInst* Create(Value *retVal = 0, Instruction *InsertBefore = 0) { @@ -2029,19 +2023,10 @@ public: static ReturnInst* Create(Value *retVal, BasicBlock *InsertAtEnd) { return new(!!retVal) ReturnInst(retVal, InsertAtEnd); } - static ReturnInst* Create(Value * const* retVals, unsigned N, - Instruction *InsertBefore = 0) { - return new(N) ReturnInst(retVals, N, InsertBefore); - } - static ReturnInst* Create(Value * const* retVals, unsigned N, - BasicBlock *InsertAtEnd) { - return new(N) ReturnInst(retVals, N, InsertAtEnd); - } static ReturnInst* Create(BasicBlock *InsertAtEnd) { return new(0) ReturnInst(InsertAtEnd); } virtual ~ReturnInst(); - inline void operator delete(void*); virtual ReturnInst *clone() const; @@ -2072,16 +2057,10 @@ public: }; template <> -struct OperandTraits<ReturnInst> : VariadicOperandTraits<> { +struct OperandTraits<ReturnInst> : OptionalOperandTraits<> { }; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value) -void ReturnInst::operator delete(void *it) { - ReturnInst* me(static_cast<ReturnInst*>(it)); - Use::zap(OperandTraits<ReturnInst>::op_begin(me), - OperandTraits<ReturnInst>::op_end(me), - true); -} //===----------------------------------------------------------------------===// // BranchInst Class @@ -3126,53 +3105,6 @@ public: } }; -//===----------------------------------------------------------------------===// -// GetResultInst Class -//===----------------------------------------------------------------------===// - -/// GetResultInst - This instruction extracts individual result value from -/// aggregate value, where aggregate value is returned by CallInst. -/// -class GetResultInst : public UnaryInstruction { - unsigned Idx; - GetResultInst(const GetResultInst &GRI) : - UnaryInstruction(GRI.getType(), Instruction::GetResult, GRI.getOperand(0)), - Idx(GRI.Idx) { - } - -public: - GetResultInst(Value *Aggr, unsigned index, - const std::string &Name = "", - Instruction *InsertBefore = 0); - - /// isValidOperands - Return true if an getresult instruction can be - /// formed with the specified operands. - static bool isValidOperands(const Value *Aggr, unsigned index); - - virtual GetResultInst *clone() const; - - Value *getAggregateValue() { - return getOperand(0); - } - - const Value *getAggregateValue() const { - return getOperand(0); - } - - unsigned getIndex() const { - return Idx; - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const GetResultInst *) { return true; } - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::GetResult); - } - static inline bool classof(const Value *V) { - return isa<Instruction>(V) && classof(cast<Instruction>(V)); - } -}; - } // End llvm namespace #endif diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 95d9c5a060..b025d4c657 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -102,7 +102,15 @@ public: } ReturnInst *CreateRet(Value * const* retVals, unsigned N) { - return Insert(ReturnInst::Create(retVals, N)); + const Type *RetType = BB->getParent()->getReturnType(); + if (N == 0 && RetType == Type::VoidTy) + return CreateRetVoid(); + if (N == 1 && retVals[0]->getType() == RetType) + return Insert(ReturnInst::Create(retVals[0])); + Value *V = UndefValue::get(RetType); + for (unsigned i = 0; i != N; ++i) + V = CreateInsertValue(V, retVals[i], i, "mrv"); + return Insert(ReturnInst::Create(V)); } /// CreateBr - Create an unconditional 'br label X' instruction. @@ -568,11 +576,6 @@ public: return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } - GetResultInst *CreateGetResult(Value *V, unsigned Index, - const char *Name = "") { - return Insert(new GetResultInst(V, Index), Name); - } - Value *CreateExtractValue(Value *Agg, unsigned Idx, const char *Name = "") { if (Constant *AggC = dyn_cast<Constant>(Agg)) diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 9606187508..932e7fbb7f 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -196,7 +196,6 @@ public: RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); } RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } - RetTy visitGetResultInst(GetResultInst &I) { DELEGATE(Instruction); } RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 42fb3b2d32..1da2e383ab 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -604,7 +604,7 @@ int LLLexer::LexIdentifier() { INSTKEYWORD("extractelement", OtherOpVal, ExtractElement, EXTRACTELEMENT); INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT); INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR); - INSTKEYWORD("getresult", OtherOpVal, GetResult, GETRESULT); + INSTKEYWORD("getresult", OtherOpVal, ExtractValue, GETRESULT); INSTKEYWORD("extractvalue", OtherOpVal, ExtractValue, EXTRACTVALUE); INSTKEYWORD("insertvalue", OtherOpVal, InsertValue, INSERTVALUE); #undef INSTKEYWORD diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 6f483fa92d..b9d561633c 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -2704,7 +2704,20 @@ BBTerminatorInst : RET ReturnedVal { // Return with a result... ValueList &VL = *$2; assert(!VL.empty() && "Invalid ret operands!"); - $$ = ReturnInst::Create(&VL[0], VL.size()); + const Type *ReturnType = CurFun.CurrentFunction->getReturnType(); + if (VL.size() > 1 || + (isa<StructType>(ReturnType) && + (VL.empty() || VL[0]->getType() != ReturnType))) { + Value *RV = UndefValue::get(ReturnType); + for (unsigned i = 0, e = VL.size(); i != e; ++i) { + Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv"); + ($<BasicBlockVal>-1)->getInstList().push_back(I); + RV = I; + } + $$ = ReturnInst::Create(RV); + } else { + $$ = ReturnInst::Create(VL[0]); + } delete $2; CHECK_FOR_ERROR } @@ -3309,12 +3322,18 @@ MemoryInst : MALLOC Types OptCAlign { delete $5; } | GETRESULT Types ValueRef ',' EUINT64VAL { - Value *TmpVal = getVal($2->get(), $3); - if (!GetResultInst::isValidOperands(TmpVal, $5)) - GEN_ERROR("Invalid getresult operands"); - $$ = new GetResultInst(TmpVal, $5); - delete $2; + if (!UpRefs.empty()) + GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); + if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get())) + GEN_ERROR("getresult insn requires an aggregate operand"); + if (!ExtractValueInst::getIndexedType(*$2, $5)) + GEN_ERROR("Invalid getresult index for type '" + + (*$2)->getDescription()+ "'"); + + Value *tmpVal = getVal(*$2, $3); CHECK_FOR_ERROR + $$ = ExtractValueInst::Create(tmpVal, $5); + delete $2; } | GETELEMENTPTR Types ValueRef IndexList { if (!UpRefs.empty()) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 3e2af4f172..f7796a6f9f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1472,7 +1472,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { Value *Op; getValueTypePair(Record, OpNum, NextValueNo, Op); unsigned Index = Record[1]; - I = new GetResultInst(Op, Index); + I = ExtractValueInst::Create(Op, Index); break; } @@ -1482,20 +1482,34 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (Size == 0) { I = ReturnInst::Create(); break; - } else { - unsigned OpNum = 0; - SmallVector<Value *,4> Vs; - do { - Value *Op = NULL; - if (getValueTypePair(Record, OpNum, NextValueNo, Op)) - return Error("Invalid RET record"); - Vs.push_back(Op); - } while(OpNum != Record.size()); - - // SmallVector Vs has at least one element. - I = ReturnInst::Create(&Vs[0], Vs.size()); + } + + unsigned OpNum = 0; + SmallVector<Value *,4> Vs; + do { + Value *Op = NULL; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return Error("Invalid RET record"); + Vs.push_back(Op); + } while(OpNum != Record.size()); + + const Type *ReturnType = F->getReturnType(); + if (Vs.size() > 1 || + (isa<StructType>(ReturnType) && + (Vs.empty() || Vs[0]->getType() != ReturnType))) { + Value *RV = UndefValue::get(ReturnType); + for (unsigned i = 0, e = Vs.size(); i != e; ++i) { + I = InsertValueInst::Create(RV, Vs[i], i, "mrv"); + CurBB->getInstList().push_back(I); + ValueList.AssignValue(I, NextValueNo++); + RV = I; + } + I = ReturnInst::Create(RV); break; } + + I = ReturnInst::Create(Vs[0]); + break; } case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#] if (Record.size() != 1 && Record.size() != 3) diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index f4d73598b9..2c585b1370 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -768,11 +768,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.push_back(VE.getValueID(I.getOperand(1))); Vals.push_back(cast<CmpInst>(I).getPredicate()); break; - case Instruction::GetResult: - Code = bitc::FUNC_CODE_INST_GETRESULT; - PushValueAndType(I.getOperand(0), InstID, Vals, VE); - Vals.push_back(cast<GetResultInst>(I).getIndex()); - break; case Instruction::Ret: { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 12c54c1eef..fdc3d25bd5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -806,8 +806,6 @@ public: void visitVAEnd(CallInst &I); void visitVACopy(CallInst &I); - void visitGetResult(GetResultInst &I); - void visitUserOp1(Instruction &I) { assert(0 && "UserOp1 should not exist at instruction selection time!"); abort(); @@ -3688,24 +3686,6 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } -void SelectionDAGLowering::visitGetResult(GetResultInst &I) { - if (isa<UndefValue>(I.getOperand(0))) { - SDOperand Undef = DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType())); - setValue(&I, Undef); - return; - } - - // To add support for individual return values with aggregate types, - // we'd need a way to take a getresult index and determine which - // values of the Call SDNode are associated with it. - assert(TLI.getValueType(I.getType(), true) != MVT::Other && - "Individual return values must not be aggregates!"); - - SDOperand Call = getValue(I.getOperand(0)); - setValue(&I, SDOperand(Call.Val, I.getIndex())); -} - - /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from /// this value and returns the result as a ValueVT value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 34511e8a3a..cda81e428d 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -285,7 +285,6 @@ namespace { void visitInsertElementInst(InsertElementInst &I); void visitExtractElementInst(ExtractElementInst &I); void visitShuffleVectorInst(ShuffleVectorInst &SVI); - void visitGetResultInst(GetResultInst &GRI); void visitInsertValueInst(InsertValueInst &I); void visitExtractValueInst(ExtractValueInst &I); @@ -3325,18 +3324,6 @@ void CWriter::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Out << "}"; } -void CWriter::visitGetResultInst(GetResultInst &GRI) { - Out << "("; - if (isa<UndefValue>(GRI.getOperand(0))) { - Out << "("; - printType(Out, GRI.getType()); - Out << ") 0/*UNDEF*/"; - } else { - Out << GetValueName(GRI.getOperand(0)) << ".field" << GRI.getIndex(); - } - Out << ")"; -} - void CWriter::visitInsertValueInst(InsertValueInst &IVI) { // Start by copying the entire aggregate value into the result variable. writeOperand(IVI.getOperand(0)); diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp index fa004fda1e..42c02e6a45 100644 --- a/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -255,9 +255,7 @@ bool IPCP::PropagateConstantReturn(Function &F) { // Find the index of the retval to replace with int index = -1; - if (GetResultInst *GR = dyn_cast<GetResultInst>(Ins)) - index = GR->getIndex(); - else if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins)) + if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins)) if (EV->hasIndices()) index = *EV->idx_begin(); diff --git a/lib/Transforms/IPO/StructRetPromotion.cpp b/lib/Transforms/IPO/StructRetPromotion.cpp index 94bf4c6d5f..aa74944850 100644 --- a/lib/Transforms/IPO/StructRetPromotion.cpp +++ b/lib/Transforms/IPO/StructRetPromotion.cpp @@ -97,9 +97,6 @@ bool SRETPromotion::PromoteReturn(CallGraphNode *CGN) { dyn_cast<StructType>(FArgType->getElementType()); assert (STy && "Invalid sret parameter element type"); - if (nestedStructType(STy)) - return false; - // Check if it is ok to perform this promotion. if (isSafeToUpdateAllCallers(F) == false) { NumRejectedSRETUses++; @@ -114,25 +111,13 @@ bool SRETPromotion::PromoteReturn(CallGraphNode *CGN) { NFirstArg->replaceAllUsesWith(TheAlloca); // [2] Find and replace ret instructions - SmallVector<Value *,4> RetVals; for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) for(BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) { Instruction *I = BI; ++BI; if (isa<ReturnInst>(I)) { - RetVals.clear(); - for (unsigned idx = 0; idx < STy->getNumElements(); ++idx) { - SmallVector<Value*, 2> GEPIdx; - GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, 0)); - GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, idx)); - Value *NGEPI = GetElementPtrInst::Create(TheAlloca, GEPIdx.begin(), - GEPIdx.end(), - "mrv.gep", I); - Value *NV = new LoadInst(NGEPI, "mrv.ld", I); - RetVals.push_back(NV); - } - - ReturnInst *NR = ReturnInst::Create(&RetVals[0], RetVals.size(), I); + Value *NV = new LoadInst(TheAlloca, "mrv.ld", I); + ReturnInst *NR = ReturnInst::Create(NV); I->replaceAllUsesWith(NR); I->eraseFromParent(); } @@ -315,7 +300,7 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) { ArgAttrsVec.clear(); New->takeName(Call); - // Update all users of sret parameter to extract value using getresult. + // Update all users of sret parameter to extract value using extractvalue. for (Value::use_iterator UI = FirstCArg->use_begin(), UE = FirstCArg->use_end(); UI != UE; ) { User *U2 = *UI++; @@ -325,7 +310,8 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) { else if (GetElementPtrInst *UGEP = dyn_cast<GetElementPtrInst>(U2)) { ConstantInt *Idx = dyn_cast<ConstantInt>(UGEP->getOperand(2)); assert (Idx && "Unexpected getelementptr index!"); - Value *GR = new GetResultInst(New, Idx->getZExtValue(), "gr", UGEP); + Value *GR = ExtractValueInst::Create(New, Idx->getZExtValue(), + "evi", UGEP); for (Value::use_iterator GI = UGEP->use_begin(), GE = UGEP->use_end(); GI != GE; ++GI) { if (LoadInst *L = dyn_cast<LoadInst>(*GI)) { diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 861badf8f0..da98d0a0fc 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -11476,9 +11476,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) { } // See if we can trivially sink this instruction to a successor basic block. - // FIXME: Remove GetResultInst test when first class support for aggregates - // is implemented. - if (I->hasOneUse() && !isa<GetResultInst>(I)) { + if (I->hasOneUse()) { BasicBlock *BB = I->getParent(); BasicBlock *UserParent = cast<Instruction>(I->use_back())->getParent(); if (UserParent != BB) { diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 4e57f0e74c..1d3bfbfe7c 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -440,20 +440,7 @@ void JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, // We found a use of I outside of BB. Create a new stack slot to // break this inter-block usage pattern. - if (!isa<StructType>(I->getType())) { - DemoteRegToStack(*I); - continue; - } - - // Alternatively, I must be a call or invoke that returns multiple retvals. - // We can't use 'DemoteRegToStack' because that will create loads and - // stores of aggregates which is not valid yet. If I is a call, we can just - // pull all the getresult instructions up to this block. If I is an invoke, - // we are out of luck. - BasicBlock::iterator IP = I; ++IP; - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) - cast<GetResultInst>(UI)->moveBefore(IP); + DemoteRegToStack(*I); } // We are going to have to map operands from the original BB block to the new diff --git a/lib/Transforms/Scalar/LoopRotation.cpp b/lib/Transforms/Scalar/LoopRotation.cpp index 38364c1587..f0dd40bd33 100644 --- a/lib/Transforms/Scalar/LoopRotation.cpp +++ b/lib/Transforms/Scalar/LoopRotation.cpp @@ -249,35 +249,11 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // create new PHINode for this instruction. Instruction *NewHeaderReplacement = NULL; if (usedOutsideOriginalHeader(In)) { - // FIXME: remove this when we have first-class aggregates. - if (isa<StructType>(In->getType())) { - // Can't create PHI nodes for this type. If there are any getResults - // not defined in this block, move them back to this block. PHI - // nodes will be created for all getResults later. - BasicBlock::iterator InsertPoint; - if (InvokeInst *II = dyn_cast<InvokeInst>(In)) { - InsertPoint = II->getNormalDest()->getFirstNonPHI(); - } else { - InsertPoint = I; // call - ++InsertPoint; - } - for (Value::use_iterator UI = In->use_begin(), UE = In->use_end(); - UI != UE; ++UI) { - GetResultInst *InGR = cast<GetResultInst>(UI); - if (InGR->getParent() != OrigHeader) { - // Move InGR to immediately after the call or in the normal dest of - // the invoke. It will be picked up, cloned and PHI'd on the next - // iteration. - InGR->moveBefore(InsertPoint); - } - } - } else { - PHINode *PN = PHINode::Create(In->getType(), In->getName(), - NewHeader->begin()); - PN->addIncoming(In, OrigHeader); - PN->addIncoming(C, OrigPreHeader); - NewHeaderReplacement = PN; - } + PHINode *PN = PHINode::Create(In->getType(), In->getName(), + NewHeader->begin()); + PN->addIncoming(In, OrigHeader); + PN->addIncoming(C, OrigPreHeader); + NewHeaderReplacement = PN; } LoopHeaderInfo.push_back(RenameData(In, C, NewHeaderReplacement)); } diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index ff88137af8..d52cef607c 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -384,7 +384,6 @@ private: void visitTerminatorInst(TerminatorInst &TI); void visitCastInst(CastInst &I); - void visitGetResultInst(GetResultInst &GRI); void visitSelectInst(SelectInst &I); void visitBinaryOperator(Instruction &I); void visitCmpInst(CmpInst &I); @@ -669,41 +668,6 @@ void SCCPSolver::visitCastInst(CastInst &I) { VState.getConstant(), I.getType())); } -void SCCPSolver::visitGetResultInst(GetResultInst &GRI) { - Value *Aggr = GRI.getOperand(0); - - // If the operand to the getresult is an undef, the result is undef. - if (isa<UndefValue>(Aggr)) - return; - - Function *F; - if (CallInst *CI = dyn_cast<CallInst>(Aggr)) - F = CI->getCalledFunction(); - else - F = cast<InvokeInst>(Aggr)->getCalledFunction(); - - // TODO: If IPSCCP resolves the callee of this function, we could propagate a - // result back! - if (F == 0 || TrackedMultipleRetVals.empty()) { - markOverdefined(&GRI); - return; - } - - // See if we are tracking the result of the callee. - std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator - It = TrackedMultipleRetVals.find(std::make_pair(F, GRI.getIndex())); - - // If not tracking this function (for example, it is a declaration) just move - // to overdefined. - if (It == TrackedMultipleRetVals.end()) { - markOverdefined(&GRI); - return; - } - - // Otherwise, the value will be merged in here as a result of CallSite - // handling. -} - void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) { Value *Aggr = EVI.getAggregateOperand(); @@ -1267,11 +1231,6 @@ CallOverdefined: // currently handled conservatively. for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; ++UI) { - if (GetResultInst *GRI = dyn_cast<GetResultInst>(*UI)) { - mergeInValue(GRI, - TrackedMultipleRetVals[std::make_pair(F, GRI->getIndex())]); - continue; - } if (Extract |