Allow readonly functions to unwind exceptions. Teach
the optimizers about this. For example, a readonly
function with no uses cannot be removed unless it is
also marked nounwind.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71071 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/ADCE.cpp b/lib/Transforms/Scalar/ADCE.cpp
index bfea2b2..9c55f66 100644
--- a/lib/Transforms/Scalar/ADCE.cpp
+++ b/lib/Transforms/Scalar/ADCE.cpp
@@ -57,7 +57,7 @@
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
if (isa<TerminatorInst>(I.getInstructionIterator()) ||
isa<DbgInfoIntrinsic>(I.getInstructionIterator()) ||
- I->mayWriteToMemory()) {
+ I->mayHaveSideEffects()) {
alive.insert(I.getInstructionIterator());
worklist.push_back(I.getInstructionIterator());
}
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index d605ffb..260bbed 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -1479,13 +1479,13 @@
for (BasicBlock::iterator BI = CurrentBlock->begin(),
BE = CurrentBlock->end(); BI != BE; ) {
Instruction *CurInst = BI++;
-
+
if (isa<AllocationInst>(CurInst) || isa<TerminatorInst>(CurInst) ||
isa<PHINode>(CurInst) || (CurInst->getType() == Type::VoidTy) ||
- CurInst->mayReadFromMemory() || CurInst->mayWriteToMemory() ||
+ CurInst->mayReadFromMemory() || CurInst->mayHaveSideEffects() ||
isa<DbgInfoIntrinsic>(CurInst))
continue;
-
+
uint32_t valno = VN.lookup(CurInst);
// Look for the predecessors for PRE opportunities. We're
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index eebac00..9feb442 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -12579,7 +12579,7 @@
assert(I->hasOneUse() && "Invariants didn't hold!");
// Cannot move control-flow-involving, volatile loads, vaarg, etc.
- if (isa<PHINode>(I) || I->mayWriteToMemory() || isa<TerminatorInst>(I))
+ if (isa<PHINode>(I) || I->mayHaveSideEffects() || isa<TerminatorInst>(I))
return false;
// Do not sink alloca instructions out of the entry block.
diff --git a/lib/Transforms/Scalar/LoopDeletion.cpp b/lib/Transforms/Scalar/LoopDeletion.cpp
index 96b7a52..6512672 100644
--- a/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -136,11 +136,8 @@
LI != LE; ++LI) {
for (BasicBlock::iterator BI = (*LI)->begin(), BE = (*LI)->end();
BI != BE; ++BI) {
- if (BI->mayWriteToMemory())
+ if (BI->mayHaveSideEffects())
return false;
- else if (LoadInst* L = dyn_cast<LoadInst>(BI))
- if (L->isVolatile())
- return false;
}
}
diff --git a/lib/Transforms/Scalar/LoopIndexSplit.cpp b/lib/Transforms/Scalar/LoopIndexSplit.cpp
index ffa1d90..40d2e4a 100644
--- a/lib/Transforms/Scalar/LoopIndexSplit.cpp
+++ b/lib/Transforms/Scalar/LoopIndexSplit.cpp
@@ -1148,7 +1148,7 @@
|| isa<DbgInfoIntrinsic>(I))
continue;
- if (I->mayWriteToMemory())
+ if (I->mayHaveSideEffects())
return false;
// I is used only inside this block then it is OK.
diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp
index 2afb3c8..e3e881f 100644
--- a/lib/Transforms/Scalar/LoopUnswitch.cpp
+++ b/lib/Transforms/Scalar/LoopUnswitch.cpp
@@ -300,7 +300,7 @@
// Okay, everything after this looks good, check to make sure that this block
// doesn't include any side effects.
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
- if (I->mayWriteToMemory())
+ if (I->mayHaveSideEffects())
return false;
return true;
@@ -383,7 +383,7 @@
// part of the loop that the code *would* execute. We already checked the
// tail, check the header now.
for (BasicBlock::iterator I = Header->begin(), E = Header->end(); I != E; ++I)
- if (I->mayWriteToMemory())
+ if (I->mayHaveSideEffects())
return false;
return true;
}
diff --git a/lib/Transforms/Scalar/TailDuplication.cpp b/lib/Transforms/Scalar/TailDuplication.cpp
index 7869069..99a7dee 100644
--- a/lib/Transforms/Scalar/TailDuplication.cpp
+++ b/lib/Transforms/Scalar/TailDuplication.cpp
@@ -258,7 +258,7 @@
while (!isa<TerminatorInst>(BBI)) {
Instruction *I = BBI++;
- bool CanHoist = !I->isTrapping() && !I->mayWriteToMemory();
+ bool CanHoist = !I->isTrapping() && !I->mayHaveSideEffects();
if (CanHoist) {
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)
if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(op)))
diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp
index e1234ef..682d069 100644
--- a/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -201,7 +201,7 @@
bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) {
// FIXME: We can move load/store/call/free instructions above the call if the
// call does not mod/ref the memory location being processed.
- if (I->mayWriteToMemory() || isa<LoadInst>(I))
+ if (I->mayHaveSideEffects() || isa<LoadInst>(I))
return false;
// Otherwise, if this is a side-effect free instruction, check to make sure
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index fea739c..4f2bb1e 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -164,17 +164,15 @@
// We don't want debug info removed by anything this general.
if (isa<DbgInfoIntrinsic>(I)) return false;
-
- if (!I->mayWriteToMemory())
- return true;
- // Special case intrinsics that "may write to memory" but can be deleted when
- // dead.
+ if (!I->mayHaveSideEffects()) return true;
+
+ // Special case intrinsics that "may have side effects" but can be deleted
+ // when dead.
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
// Safe to delete llvm.stacksave if dead.
if (II->getIntrinsicID() == Intrinsic::stacksave)
return true;
-
return false;
}
@@ -230,7 +228,7 @@
SmallPtrSet<PHINode *, 4> PHIs;
PHIs.insert(PN);
for (Instruction *J = cast<Instruction>(*PN->use_begin());
- J->hasOneUse() && !J->mayWriteToMemory();
+ J->hasOneUse() && !J->mayHaveSideEffects();
J = cast<Instruction>(*J->use_begin()))
// If we find a PHI more than once, we're on a cycle that
// won't prove fruitful.
diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp
index f33c1a2..9e030b7 100644
--- a/lib/VMCore/Instruction.cpp
+++ b/lib/VMCore/Instruction.cpp
@@ -320,6 +320,14 @@
}
}
+/// mayThrow - Return true if this instruction may throw an exception.
+///
+bool Instruction::mayThrow() const {
+ if (const CallInst *CI = dyn_cast<CallInst>(this))
+ return !CI->doesNotThrow();
+ return false;
+}
+
/// isAssociative - Return true if the instruction is associative:
///
/// Associative operators satisfy: x op (y op z) === (x op y) op z)