aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-04-23 05:59:23 +0000
committerChris Lattner <sabre@nondot.org>2008-04-23 05:59:23 +0000
commit7f295eaf991a6117c50fea44069dbb55bc231889 (patch)
treedd0b983c509114a6ad3a98259dce8b3fb7825e3c /lib/Transforms
parentcd73be0d00098fcbeecb9607461f01e4a1456a8e (diff)
downloadexternal_llvm-7f295eaf991a6117c50fea44069dbb55bc231889.zip
external_llvm-7f295eaf991a6117c50fea44069dbb55bc231889.tar.gz
external_llvm-7f295eaf991a6117c50fea44069dbb55bc231889.tar.bz2
Fix a number of bugs in ipconstantprop, simplify the code, fit in 80 cols,
fix read after free bug (PR2238). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50141 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp80
1 files changed, 39 insertions, 41 deletions
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index 8632cd1..ad812fd 100644
--- a/lib/Transforms/IPO/IPConstantPropagation.cpp
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -152,20 +152,20 @@ bool IPCP::PropagateConstantReturn(Function &F) {
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
- unsigned RetValsSize = RetVals.size();
- assert (RetValsSize == RI->getNumOperands() && "Invalid ReturnInst operands!");
- for (unsigned i = 0; i < RetValsSize; ++i) {
- if (isa<UndefValue>(RI->getOperand(i))) {
- // Ignore
- } else if (Constant *C = dyn_cast<Constant>(RI->getOperand(i))) {
- Value *RV = RetVals[i];
- if (RV == 0)
- RetVals[i] = C;
- else if (RV != C)
- return false; // Does not return the same constant.
- } else {
+ assert(RetVals.size() == RI->getNumOperands() &&
+ "Invalid ReturnInst operands!");
+ for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
+ if (isa<UndefValue>(RI->getOperand(i)))
+ continue; // Ignore
+ Constant *C = dyn_cast<Constant>(RI->getOperand(i));
+ if (C == 0)
return false; // Does not return a constant.
- }
+
+ Value *RV = RetVals[i];
+ if (RV == 0)
+ RetVals[i] = C;
+ else if (RV != C)
+ return false; // Does not return the same constant.
}
}
@@ -174,43 +174,41 @@ bool IPCP::PropagateConstantReturn(Function &F) {
if (RetVals[i] == 0)
RetVals[i] = UndefValue::get(STy->getElementType(i));
} else {
- if (RetVals.size() == 1)
- if (RetVals[0] == 0)
- RetVals[0] = UndefValue::get(F.getReturnType());
+ assert(RetVals.size() == 1);
+ if (RetVals[0] == 0)
+ RetVals[0] = UndefValue::get(F.getReturnType());
}
// If we got here, the function returns a constant value. Loop over all
// users, replacing any uses of the return value with the returned constant.
bool ReplacedAllUsers = true;
bool MadeChange = false;
- for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
- if (!isa<Instruction>(*I))
+ for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
+ // Make sure this is an invoke or call and that the use is for the callee.
+ if (!(isa<InvokeInst>(*UI) || isa<CallInst>(*UI)) ||
+ UI.getOperandNo() != 0) {
ReplacedAllUsers = false;
- else {
- CallSite CS = CallSite::get(cast<Instruction>(*I));
- if (CS.getInstruction() == 0 ||
- CS.getCalledFunction() != &F) {
- ReplacedAllUsers = false;
- } else {
- Instruction *Call = CS.getInstruction();
- if (!Call->use_empty()) {
- if (RetVals.size() == 1)
- Call->replaceAllUsesWith(RetVals[0]);
- else {
- for(Value::use_iterator CUI = Call->use_begin(), CUE = Call->use_end();
- CUI != CUE; ++CUI) {
- GetResultInst *GR = cast<GetResultInst>(CUI);
- if (RetVals[GR->getIndex()]) {
- GR->replaceAllUsesWith(RetVals[GR->getIndex()]);
- GR->eraseFromParent();
- }
- }
- }
- MadeChange = true;
- }
- }
+ continue;
}
+
+ Instruction *Call = cast<Instruction>(*UI);
+ if (Call->use_empty())
+ continue;
+
+ MadeChange = true;
+ if (STy == 0) {
+ Call->replaceAllUsesWith(RetVals[0]);
+ continue;
+ }
+
+ while (!Call->use_empty()) {
+ GetResultInst *GR = cast<GetResultInst>(Call->use_back());
+ GR->replaceAllUsesWith(RetVals[GR->getIndex()]);
+ GR->eraseFromParent();
+ }
+ }
+
// If we replace all users with the returned constant, and there can be no
// other callers of the function, replace the constant being returned in the
// function with an undef value.