diff options
Diffstat (limited to 'lib/Transforms/Utils')
-rw-r--r-- | lib/Transforms/Utils/InlineFunction.cpp | 74 | ||||
-rw-r--r-- | lib/Transforms/Utils/LCSSA.cpp | 22 | ||||
-rw-r--r-- | lib/Transforms/Utils/SimplifyCFG.cpp | 77 | ||||
-rw-r--r-- | lib/Transforms/Utils/UnifyFunctionExitNodes.cpp | 34 |
4 files changed, 55 insertions, 152 deletions
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); |