summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorJohannes Doerfert <jdoerfert@anl.gov>2019-08-05 21:35:02 +0000
committerJohannes Doerfert <jdoerfert@anl.gov>2019-08-05 21:35:02 +0000
commit3d7bbc6f9c4fdcbc29ac2da147151911b0983c85 (patch)
treeb67d0863047306a652f66c9140afb86e27e31d2c /llvm/lib/Transforms
parenteac86ec25f5cd5d7a973c913d3c2ca8c90b24115 (diff)
downloadbcm5719-llvm-3d7bbc6f9c4fdcbc29ac2da147151911b0983c85.tar.gz
bcm5719-llvm-3d7bbc6f9c4fdcbc29ac2da147151911b0983c85.zip
[Attributor][Fix] Do not remove instructions during manifestation
When we remove instructions cached references could still be live. This patch avoids removing invoke instructions that are replaced by calls and instead keeps them around but in a dead block. llvm-svn: 367933
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp26
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp18
2 files changed, 32 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 1ae8ac77de0..3ecad8b03eb 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -1577,6 +1577,11 @@ struct AAIsDeadFunction : AAIsDead, BooleanState {
Instruction *SplitPos = I->getNextNode();
if (auto *II = dyn_cast<InvokeInst>(I)) {
+ // If we keep the invoke the split position is at the beginning of the
+ // normal desitination block (it invokes a noreturn function after all).
+ BasicBlock *NormalDestBB = II->getNormalDest();
+ SplitPos = &NormalDestBB->front();
+
/// Invoke is replaced with a call and unreachable is placed after it if
/// the callee is nounwind and noreturn. Otherwise, we keep the invoke
/// and only place an unreachable in the normal successor.
@@ -1587,17 +1592,26 @@ struct AAIsDeadFunction : AAIsDead, BooleanState {
(AANoUnw && AANoUnw->isAssumedNoUnwind())) {
LLVM_DEBUG(dbgs()
<< "[AAIsDead] Replace invoke with call inst\n");
- changeToCall(II);
- changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
- continue;
+ // We do not need an invoke (II) but instead want a call followed
+ // by an unreachable. However, we do not remove II as other
+ // abstract attributes might have it cached as part of their
+ // results. Given that we modify the CFG anyway, we simply keep II
+ // around but in a new dead block. To avoid II being live through
+ // a different edge we have to ensure the block we place it in is
+ // only reached from the current block of II and then not reached
+ // at all when we insert the unreachable.
+ SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
+ CallInst *CI = createCallMatchingInvoke(II);
+ CI->insertBefore(II);
+ CI->takeName(II);
+ II->replaceAllUsesWith(CI);
+ SplitPos = CI->getNextNode();
}
}
}
-
- BB = II->getNormalDest();
- SplitPos = &BB->front();
}
+ BB = SplitPos->getParent();
SplitBlock(BB, SplitPos);
changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
HasChanged = ChangeStatus::CHANGED;
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 68443c15a78..a1d1b3ec84f 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1933,18 +1933,24 @@ unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap,
return NumInstrsRemoved;
}
-/// changeToCall - Convert the specified invoke into a normal call.
-void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
- SmallVector<Value*, 8> Args(II->arg_begin(), II->arg_end());
+CallInst *llvm::createCallMatchingInvoke(InvokeInst *II) {
+ SmallVector<Value *, 8> Args(II->arg_begin(), II->arg_end());
SmallVector<OperandBundleDef, 1> OpBundles;
II->getOperandBundlesAsDefs(OpBundles);
- CallInst *NewCall = CallInst::Create(
- II->getFunctionType(), II->getCalledValue(), Args, OpBundles, "", II);
- NewCall->takeName(II);
+ CallInst *NewCall = CallInst::Create(II->getFunctionType(),
+ II->getCalledValue(), Args, OpBundles);
NewCall->setCallingConv(II->getCallingConv());
NewCall->setAttributes(II->getAttributes());
NewCall->setDebugLoc(II->getDebugLoc());
NewCall->copyMetadata(*II);
+ return NewCall;
+}
+
+/// changeToCall - Convert the specified invoke into a normal call.
+void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
+ CallInst *NewCall = createCallMatchingInvoke(II);
+ NewCall->takeName(II);
+ NewCall->insertBefore(II);
II->replaceAllUsesWith(NewCall);
// Follow the call by a branch to the normal destination.
OpenPOWER on IntegriCloud