aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-03-28 08:38:27 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-03-28 08:38:27 +0000
commitafff33001a4fd3049d97cb40eea459d5c87ae5cc (patch)
tree795e1c7331514e6f5a7ce5e03405b011826c4bc4
parent9fc5c83fb7b86862d4a29bf416842a4f1a0084d5 (diff)
downloadexternal_llvm-afff33001a4fd3049d97cb40eea459d5c87ae5cc.zip
external_llvm-afff33001a4fd3049d97cb40eea459d5c87ae5cc.tar.gz
external_llvm-afff33001a4fd3049d97cb40eea459d5c87ae5cc.tar.bz2
Switch to WeakVHs in the value mapper, and aggressively prune dead basic
blocks in the function cloner. This removes the last case of trivially dead code that I've been seeing in the wild getting inlined, analyzed, re-inlined, optimized, only to be deleted. Nukes a FIXME from the cleanup tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153572 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Transforms/Utils/ValueMapper.h2
-rw-r--r--lib/Transforms/Utils/CloneFunction.cpp26
-rw-r--r--test/Transforms/Inline/inline_cleanup.ll10
3 files changed, 24 insertions, 14 deletions
diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h
index 0384656..8594707 100644
--- a/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/include/llvm/Transforms/Utils/ValueMapper.h
@@ -20,7 +20,7 @@
namespace llvm {
class Value;
class Instruction;
- typedef ValueMap<const Value *, TrackingVH<Value> > ValueToValueMapTy;
+ typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
/// ValueMapTypeRemapper - This is a class that can be implemented by clients
/// to remap types when cloning constants and instructions.
diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp
index 021f263..fe00600 100644
--- a/lib/Transforms/Utils/CloneFunction.cpp
+++ b/lib/Transforms/Utils/CloneFunction.cpp
@@ -23,6 +23,8 @@
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/InstructionSimplify.h"
@@ -226,7 +228,7 @@ namespace {
/// anything that it can reach.
void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
std::vector<const BasicBlock*> &ToClone){
- TrackingVH<Value> &BBEntry = VMap[BB];
+ WeakVH &BBEntry = VMap[BB];
// Have we already cloned this block?
if (BBEntry) return;
@@ -503,7 +505,7 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
// Make a second pass over the PHINodes now that all of them have been
// remapped into the new function, simplifying the PHINode and performing any
// recursive simplifications exposed. This will transparently update the
- // TrackingVH in the VMap. Notably, we rely on that so that if we coalesce
+ // WeakVH in the VMap. Notably, we rely on that so that if we coalesce
// two PHINodes, the iteration over the old PHIs remains valid, and the
// mapping will just map us to the new node (which may not even be a PHI
// node).
@@ -515,8 +517,26 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
// and zap unconditional fall-through branches. This happen all the time when
// specializing code: code specialization turns conditional branches into
// uncond branches, and this code folds them.
- Function::iterator I = cast<BasicBlock>(VMap[&OldFunc->getEntryBlock()]);
+ Function::iterator Begin = cast<BasicBlock>(VMap[&OldFunc->getEntryBlock()]);
+ Function::iterator I = Begin;
while (I != NewFunc->end()) {
+ // Check if this block has become dead during inlining or other
+ // simplifications. Note that the first block will appear dead, as it has
+ // not yet been wired up properly.
+ if (I != Begin && (pred_begin(I) == pred_end(I) ||
+ I->getSinglePredecessor() == I)) {
+ BasicBlock *DeadBB = I++;
+ DeleteDeadBlock(DeadBB);
+ continue;
+ }
+
+ // We need to simplify conditional branches and switches with a constant
+ // operand. We try to prune these out when cloning, but if the
+ // simplification required looking through PHI nodes, those are only
+ // available after forming the full basic block. That may leave some here,
+ // and we still want to prune the dead code as early as possible.
+ ConstantFoldTerminator(I);
+
BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
if (!BI || BI->isConditional()) { ++I; continue; }
diff --git a/test/Transforms/Inline/inline_cleanup.ll b/test/Transforms/Inline/inline_cleanup.ll
index cf57cf0..27ee617 100644
--- a/test/Transforms/Inline/inline_cleanup.ll
+++ b/test/Transforms/Inline/inline_cleanup.ll
@@ -130,16 +130,6 @@ define void @outer2(i32 %z, i1 %b) {
; make it through inlining.
; CHECK: define void @outer2
; CHECK-NOT: call
-;
-; FIXME: Currently, we aren't smart enough to delete the last dead basic block.
-; However, we do make the condition a constant. Check that at least until we can
-; start removing the block itself.
-; CHECK: br i1 false, label %[[LABEL:[a-z0-9_.]+]],
-; CHECK-NOT: call
-; CHECK: [[LABEL]]:
-; CHECK-NEXT: call void @f(i32 10)
-; CHECK-NOT: call
-;
; CHECK: ret void
entry: