aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-07-23 00:34:11 +0000
committerDan Gohman <gohman@apple.com>2008-07-23 00:34:11 +0000
commitfc74abfba5128544a750fce22fdf13eb0403e3ce (patch)
tree36ed972103bbbb170370e4e6688787ed5f1f9ac8 /lib/Transforms
parent5e6ebaf4d1d3043d3428b65ee8054c71c24af930 (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
Diffstat (limited to 'lib/Transforms')
-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
10 files changed, 68 insertions, 261 deletions
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();
- }
- } else
- TheCall->replaceAllUsesWith(R->getReturnValue());
+ TheCall->replaceAllUsesWith(R->getReturnValue());
}
// Since we are now done with the Call/Invoke, we can delete it.
TheCall->eraseFromParent();
@@ -508,63 +498,27 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) {
// Handle all of the return instructions that we just cloned in, and eliminate
// any users of the original call/invoke instruction.
const Type *RTy = CalledFunc->getReturnType();
- const StructType *STy = dyn_cast<StructType>(RTy);
-
- // We do special handling for multiple-value return statements. If this is
- // a plain aggregate return, don't do the special handling.
- if (!Returns.empty() && Returns[0]->getNumOperands() != 0 &&
- Returns[0]->getOperand(0)->getType() == STy)
- STy = 0;
- if (Returns.size() > 1 || STy) {
+ if (Returns.size() > 1) {
// The PHI node should go at the front of the new basic block to merge all
// possible incoming values.
- SmallVector<PHINode *, 4> PHIs;
+ PHINode *PHI = 0;
if (!TheCall->use_empty()) {
- if (STy) {
- unsigned NumRetVals = STy->getNumElements();
- // Create new phi nodes such that phi node number in the PHIs vector
- // match corresponding return value operand number.
- Instruction *InsertPt = AfterCallBB->begin();
- for (unsigned i = 0; i < NumRetVals; ++i) {
- PHINode *PHI = PHINode::Create(STy->getElementType(i),
- TheCall->getName() + "." + utostr(i),
- InsertPt);
- PHIs.push_back(PHI);
- }
- // TheCall results are used by GetResult instructions.
- while (!TheCall->use_empty()) {
- GetResultInst *GR = cast<GetResultInst>(TheCall->use_back());
- GR->replaceAllUsesWith(PHIs[GR->getIndex()]);
- GR->eraseFromParent();
- }
- } else {
- PHINode *PHI = PHINode::Create(RTy, TheCall->getName(),
- AfterCallBB->begin());
- PHIs.push_back(PHI);
- // Anything that used the result of the function call should now use the
- // PHI node as their operand.
- TheCall->replaceAllUsesWith(PHI);
- }
+ PHI = PHINode::Create(RTy, TheCall->getName(),
+ AfterCallBB->begin());
+ // Anything that used the result of the function call should now use the
+ // PHI node as their operand.
+ TheCall->replaceAllUsesWith(PHI);
}
// Loop over all of the return instructions adding entries to the PHI node as
// appropriate.
- if (!PHIs.empty()) {
- // There is atleast one return value.
- unsigned NumRetVals = 1;
- if (STy)
- NumRetVals = STy->getNumElements();
- for (unsigned j = 0; j < NumRetVals; ++j) {
- PHINode *PHI = PHIs[j];
- // Each PHI node will receive one value from each return instruction.
- for(unsigned i = 0, e = Returns.size(); i != e; ++i) {
- ReturnInst *RI = Returns[i];
- assert(RI->getReturnValue(j)->getType() == PHI->getType() &&
- "Ret value not consistent in function!");
- PHI->addIncoming(RI->getReturnValue(j /*PHI number matches operand number*/),
- RI->getParent());
- }
+ if (PHI) {
+ for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
+ ReturnInst *RI = Returns[i];
+ assert(RI->getReturnValue()->getType() == PHI->getType() &&
+ "Ret value not consistent in function!");
+ PHI->addIncoming(RI->getReturnValue(), RI->getParent());
}
}
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp
index d94cd594ba..55d7a48593 100644
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -217,27 +217,7 @@ void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L,
}
if (*BB != UserBB && !inLoop(UserBB)) {
- const StructType *STy = dyn_cast<StructType>(I->getType());
- if (STy) {
- // I is a call or an invoke that returns multiple values.
- // These values are accessible through getresult only.
- // If the getresult value is not in the BB then move it
- // immediately here. It will be processed in next iteration.
- BasicBlock::iterator InsertPoint;
- if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
- InsertPoint = II->getNormalDest()->getFirstNonPHI();
- } else {
- InsertPoint = I;
- InsertPoint++;
- }
- for (Value::use_iterator TmpI = I->use_begin(),
- TmpE = I->use_end(); TmpI != TmpE; ++TmpI) {
- GetResultInst *GR = cast<GetResultInst>(TmpI);
- if (GR->getParent() != *BB)
- GR->moveBefore(InsertPoint);
- }
- } else
- AffectedValues.insert(I);
+ AffectedValues.insert(I);
break;
}
}
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 2fc859e88d..d04fce6892 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1357,40 +1357,31 @@ static bool SimplifyCondBranchToTwoReturns(BranchInst *BI) {
return true;
}
- // Otherwise, build up the result values for the new return.
- SmallVector<Value*, 4> TrueResult;
- SmallVector<Value*, 4> FalseResult;
+ // Otherwise, figure out what the true and false return values are
+ // so we can insert a new select instruction.
+ Value *TrueValue = TrueRet->getReturnValue();
+ Value *FalseValue = FalseRet->getReturnValue();
+
+ // Unwrap any PHI nodes in the return blocks.
+ if (PHINode *TVPN = dyn_cast_or_null<PHINode>(TrueValue))
+ if (TVPN->getParent() == TrueSucc)
+ TrueValue = TVPN->getIncomingValueForBlock(BI->getParent());
+ if (PHINode *FVPN = dyn_cast_or_null<PHINode>(FalseValue))
+ if (FVPN->getParent() == FalseSucc)
+ FalseValue = FVPN->getIncomingValueForBlock(BI->getParent());
+
+ // In order for this transformation to be safe, we must be able to
+ // unconditionally execute both operands to the return. This is
+ // normally the case, but we could have a potentially-trapping
+ // constant expression that prevents this transformation from being
+ // safe.
+ if (ConstantExpr *TCV = dyn_cast_or_null<ConstantExpr>(TrueValue))
+ if (TCV->canTrap())
+ return false;
+ if (ConstantExpr *FCV = dyn_cast_or_null<ConstantExpr>(FalseValue))
+ if (FCV->canTrap())
+ return false;
- for (unsigned i = 0, e = TrueRet->getNumOperands(); i != e; ++i) {
- // Otherwise, figure out what the true and false return values are
- // so we can insert a new select instruction.
- Value *TrueValue = TrueRet->getOperand(i);
- Value *FalseValue = FalseRet->getOperand(i);
-
- // Unwrap any PHI nodes in the return blocks.
- if (PHINode *TVPN = dyn_cast<PHINode>(TrueValue))
- if (TVPN->getParent() == TrueSucc)
- TrueValue = TVPN->getIncomingValueForBlock(BI->getParent());
- if (PHINode *FVPN = dyn_cast<PHINode>(FalseValue))
- if (FVPN->getParent() == FalseSucc)
- FalseValue = FVPN->getIncomingValueForBlock(BI->getParent());
-
- // In order for this transformation to be safe, we must be able to
- // unconditionally execute both operands to the return. This is
- // normally the case, but we could have a potentially-trapping
- // constant expression that prevents this transformation from being
- // safe.
- if (ConstantExpr *TCV = dyn_cast<ConstantExpr>(TrueValue))
- if (TCV->canTrap())
- return false;
- if (ConstantExpr *FCV = dyn_cast<ConstantExpr>(FalseValue))
- if (FCV->canTrap())
- return false;
-
- TrueResult.push_back(TrueValue);
- FalseResult.push_back(FalseValue);
- }
-
// Okay, we collected all the mapped values and checked them for sanity, and
// defined to really do this transformation. First, update the CFG.
TrueSucc->removePredecessor(BI->getParent());
@@ -1398,20 +1389,20 @@ static bool SimplifyCondBranchToTwoReturns(BranchInst *BI) {
// Insert select instructions where needed.
Value *BrCond = BI->getCondition();
- for (unsigned i = 0, e = TrueRet->getNumOperands(); i != e; ++i) {
+ if (TrueValue) {
// Insert a select if the results differ.
- if (TrueResult[i] == FalseResult[i] || isa<UndefValue>(FalseResult[i]))
- continue;
- if (isa<UndefValue>(TrueResult[i])) {
- TrueResult[i] = FalseResult[i];
- continue;
+ if (TrueValue == FalseValue || isa<UndefValue>(FalseValue)) {
+ } else if (isa<UndefValue>(TrueValue)) {
+ TrueValue = FalseValue;
+ } else {
+ TrueValue = SelectInst::Create(BrCond, TrueValue,
+ FalseValue, "retval", BI);
}
-
- TrueResult[i] = SelectInst::Create(BrCond, TrueResult[i],
- FalseResult[i], "retval", BI);
}
- Value *RI = ReturnInst::Create(&TrueResult[0], TrueResult.size(), BI);
+ Value *RI = !TrueValue ?
+ ReturnInst::Create(BI) :
+ ReturnInst::Create(TrueValue, BI);
DOUT << "\nCHANGING BRANCH TO TWO RETURNS INTO SELECT:"
<< "\n " << *BI << "NewRet = " << *RI
diff --git a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
index c024d32374..ba58fbd987 100644
--- a/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
+++ b/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
@@ -110,32 +110,13 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
//
BasicBlock *NewRetBlock = BasicBlock::Create("UnifiedReturnBlock", &F);
- SmallVector<Value *, 4> Phis;
- unsigned NumRetVals = ReturningBlocks[0]->getTerminator()->getNumOperands();
- if (NumRetVals == 0)
+ PHINode *PN = 0;
+ if (F.getReturnType() == Type::VoidTy) {
ReturnInst::Create(NULL, NewRetBlock);
- else if (const StructType *STy = dyn_cast<StructType>(F.getReturnType())) {
- Instruction *InsertPt = NULL;
- if (NumRetVals == 0)
- InsertPt = NewRetBlock->getFirstNonPHI();
- PHINode *PN = NULL;
- for (unsigned i = 0; i < NumRetVals; ++i) {
- if (InsertPt)
- PN = PHINode::Create(STy->getElementType(i), "UnifiedRetVal."
- + utostr(i), InsertPt);
- else
- PN = PHINode::Create(STy->getElementType(i), "UnifiedRetVal."
- + utostr(i), NewRetBlock);
- Phis.push_back(PN);
- InsertPt = PN;
- }
- ReturnInst::Create(&Phis[0], NumRetVals, NewRetBlock);
- }
- else {
+ } else {
// If the function doesn't return void... add a PHI node to the block...
- PHINode *PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
+ PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
NewRetBlock->getInstList().push_back(PN);
- Phis.push_back(PN);
ReturnInst::Create(PN, NewRetBlock);
}
@@ -148,11 +129,8 @@ bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
// Add an incoming element to the PHI node for every return instruction that
// is merging into this new block...
- if (!Phis.empty()) {
- for (unsigned i = 0; i < NumRetVals; ++i)
- cast<PHINode>(Phis[i])->addIncoming(BB->getTerminator()->getOperand(i),
- BB);
- }
+ if (PN)
+ PN->addIncoming(BB->getTerminator()->getOperand(0), BB);
BB->getInstList().pop_back(); // Remove the return insn
BranchInst::Create(NewRetBlock, BB);