aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/AutoUpgrade.h6
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h1
-rw-r--r--include/llvm/InstrTypes.h1
-rw-r--r--include/llvm/Instruction.def10
-rw-r--r--include/llvm/Instructions.h70
-rw-r--r--include/llvm/Support/IRBuilder.h15
-rw-r--r--include/llvm/Support/InstVisitor.h1
-rw-r--r--lib/AsmParser/LLLexer.cpp2
-rw-r--r--lib/AsmParser/llvmAsmParser.y31
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp40
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp20
-rw-r--r--lib/Target/CBackend/CBackend.cpp13
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp4
-rw-r--r--lib/Transforms/IPO/StructRetPromotion.cpp24
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp4
-rw-r--r--lib/Transforms/Scalar/JumpThreading.cpp15
-rw-r--r--lib/Transforms/Scalar/LoopRotation.cpp34
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp41
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp74
-rw-r--r--lib/Transforms/Utils/LCSSA.cpp22
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp77
-rw-r--r--lib/Transforms/Utils/UnifyFunctionExitNodes.cpp34
-rw-r--r--lib/VMCore/AsmWriter.cpp3
-rw-r--r--lib/VMCore/AutoUpgrade.cpp28
-rw-r--r--lib/VMCore/Instruction.cpp1
-rw-r--r--lib/VMCore/Instructions.cpp103
-rw-r--r--lib/VMCore/Verifier.cpp41
-rw-r--r--test/Transforms/SCCP/2008-03-10-sret.ll7
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 (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(*UI)) {
if (EVI->getNumIndices() == 1) {
mergeInValue(EVI,
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 22dab69846..a198356fd2 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -442,17 +442,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
// uses of the returned value.
if (!TheCall->use_empty()) {
ReturnInst *R = Returns[0];
- if (isa<StructType>(TheCall->getType()) &&
- TheCall->getType() != R->getOperand(0)->getType()) {
- // Multiple-value return statements.
- while (!TheCall->use_empty()) {
- GetResultInst *GR = cast<GetResultInst>(TheCall->use_back());
- Value *RV = R->getOperand(GR->getIndex());
- GR->replaceAllUsesWith(RV);
- GR->eraseFromParent();