[llvm-commits] [llvm] r70636 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicBlockUtils.h include/llvm/Transforms/Utils/Local.h lib/Transforms/Scalar/LoopStrengthReduce.cpp lib/Transforms/Utils/BasicBlockUtils.cpp lib/Transforms/Utils/Local.cpp test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll test/CodeGen/X86/mmx-vzmovl-2.ll test/CodeGen/X86/pre-split4.ll test/Transforms/LoopStrengthReduce/pr2570.ll
Dan Gohman
gohman at apple.com
Sat May 2 11:29:23 PDT 2009
Author: djg
Date: Sat May 2 13:29:22 2009
New Revision: 70636
URL: http://llvm.org/viewvc/llvm-project?rev=70636&view=rev
Log:
Previously, RecursivelyDeleteDeadInstructions provided an option
of returning a list of pointers to Values that are deleted. This was
unsafe, because the pointers in the list are, by nature of what
RecursivelyDeleteDeadInstructions does, always dangling. Replace this
with a simple callback mechanism. This may eventually be removed if
all clients can reasonably be expected to use CallbackVH.
Use this to factor out the dead-phi-cycle-elimination code from LSR
utility function, and generalize it to use the
RecursivelyDeleteTriviallyDeadInstructions utility function.
This makes LSR more aggressive about eliminating dead PHI cycles;
adjust tests to either be less trivial or to simply expect fewer
instructions.
Modified:
llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
llvm/trunk/include/llvm/Transforms/Utils/Local.h
llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/trunk/lib/Transforms/Utils/Local.cpp
llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll
llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll
llvm/trunk/test/CodeGen/X86/pre-split4.ll
llvm/trunk/test/Transforms/LoopStrengthReduce/pr2570.ll
Modified: llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicBlockUtils.h Sat May 2 13:29:22 2009
@@ -25,6 +25,7 @@
class Instruction;
class Pass;
class AliasAnalysis;
+class ValueDeletionListener;
/// DeleteDeadBlock - Delete the specified block, which must have no
/// predecessors.
@@ -36,8 +37,14 @@
/// when all entries to the PHI nodes in a block are guaranteed equal, such as
/// when the block has exactly one predecessor.
void FoldSingleEntryPHINodes(BasicBlock *BB);
-
-
+
+/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
+/// is dead. Also recursively delete any operands that become dead as
+/// a result. This includes tracing the def-use list from the PHI to see if
+/// it is ultimately unused or if it reaches an unused cycle. If a
+/// ValueDeletionListener is specified, it is notified of the deletions.
+void DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL = 0);
+
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure.
bool MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P = 0);
Modified: llvm/trunk/include/llvm/Transforms/Utils/Local.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Local.h?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/Local.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/Local.h Sat May 2 13:29:22 2009
@@ -50,16 +50,41 @@
///
bool isInstructionTriviallyDead(Instruction *I);
-
+/// ValueDeletionListener - A simple abstract interface for delivering
+/// notifications when Values are deleted.
+///
+/// @todo Consider whether ValueDeletionListener can be made obsolete by
+/// requiring clients to use CallbackVH instead.
+class ValueDeletionListener {
+public:
+ /// ValueWillBeDeleted - This method is called shortly before the specified
+ /// value will be deleted.
+ virtual void ValueWillBeDeleted(Value *V) = 0;
+
+protected:
+ virtual ~ValueDeletionListener();
+};
+
/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
/// trivially dead instruction, delete it. If that makes any of its operands
/// trivially dead, delete them too, recursively.
///
-/// If DeadInst is specified, the vector is filled with the instructions that
-/// are actually deleted.
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
void RecursivelyDeleteTriviallyDeadInstructions(Value *V,
- SmallVectorImpl<Instruction*> *DeadInst = 0);
-
+ ValueDeletionListener *VDL = 0);
+
+/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
+/// dead PHI node, due to being a def-use chain of single-use nodes that
+/// either forms a cycle or is terminated by a trivially dead instruction,
+/// delete it. If that makes any of its operands trivially dead, delete them
+/// too, recursively.
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
+void RecursivelyDeleteDeadPHINode(PHINode *PN,
+ ValueDeletionListener *VDL = 0);
+
//===----------------------------------------------------------------------===//
// Control Flow Graph Restructuring.
//
Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sat May 2 13:29:22 2009
@@ -32,6 +32,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/Target/TargetLowering.h"
#include <algorithm>
using namespace llvm;
@@ -2138,6 +2139,7 @@
CondUse = &IVUsesByStride[*NewStride].Users.back();
CondStride = NewStride;
++NumEliminated;
+ Changed = true;
}
return Cond;
@@ -2501,44 +2503,21 @@
StrideOrder.clear();
// Clean up after ourselves
- if (!DeadInsts.empty()) {
+ if (!DeadInsts.empty())
DeleteTriviallyDeadInstructions();
- BasicBlock::iterator I = L->getHeader()->begin();
- while (PHINode *PN = dyn_cast<PHINode>(I++)) {
- // At this point, we know that we have killed one or more IV users.
- // It is worth checking to see if the cannonical indvar is also
- // dead, so that we can remove it as well.
- //
- // We can remove a PHI if it is on a cycle in the def-use graph
- // where each node in the cycle has degree one, i.e. only one use,
- // and is an instruction with no side effects.
- //
- // FIXME: this needs to eliminate an induction variable even if it's being
- // compared against some value to decide loop termination.
- if (!PN->hasOneUse())
- continue;
-
- SmallPtrSet<PHINode *, 4> PHIs;
- for (Instruction *J = dyn_cast<Instruction>(*PN->use_begin());
- J && J->hasOneUse() && !J->mayWriteToMemory();
- J = dyn_cast<Instruction>(*J->use_begin())) {
- // If we find the original PHI, we've discovered a cycle.
- if (J == PN) {
- // Break the cycle and mark the PHI for deletion.
- SE->deleteValueFromRecords(PN);
- PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
- DeadInsts.push_back(PN);
- Changed = true;
- break;
- }
- // If we find a PHI more than once, we're on a cycle that
- // won't prove fruitful.
- if (isa<PHINode>(J) && !PHIs.insert(cast<PHINode>(J)))
- break;
- }
+ // At this point, it is worth checking to see if any recurrence PHIs are also
+ // dead, so that we can remove them as well. To keep ScalarEvolution
+ // current, use a ValueDeletionListener class.
+ struct LSRListener : public ValueDeletionListener {
+ ScalarEvolution &SE;
+ explicit LSRListener(ScalarEvolution &se) : SE(se) {}
+
+ virtual void ValueWillBeDeleted(Value *V) {
+ SE.deleteValueFromRecords(V);
}
- DeleteTriviallyDeadInstructions();
- }
+ } VDL(*SE);
+ DeleteDeadPHIs(L->getHeader(), &VDL);
+
return Changed;
}
Modified: llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/BasicBlockUtils.cpp Sat May 2 13:29:22 2009
@@ -22,6 +22,8 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/Support/ValueHandle.h"
#include <algorithm>
using namespace llvm;
@@ -73,6 +75,24 @@
}
+/// DeleteDeadPHIs - Examine each PHI in the given block and delete it if it
+/// is dead. Also recursively delete any operands that become dead as
+/// a result. This includes tracing the def-use list from the PHI to see if
+/// it is ultimately unused or if it reaches an unused cycle. If a
+/// ValueDeletionListener is specified, it is notified of the deletions.
+void llvm::DeleteDeadPHIs(BasicBlock *BB, ValueDeletionListener *VDL) {
+ // Recursively deleting a PHI may cause multiple PHIs to be deleted
+ // or RAUW'd undef, so use an array of WeakVH for the PHIs to delete.
+ SmallVector<WeakVH, 8> PHIs;
+ for (BasicBlock::iterator I = BB->begin();
+ PHINode *PN = dyn_cast<PHINode>(I); ++I)
+ PHIs.push_back(PN);
+
+ for (unsigned i = 0, e = PHIs.size(); i != e; ++i)
+ if (PHINode *PN = dyn_cast_or_null<PHINode>(PHIs[i].operator Value*()))
+ RecursivelyDeleteDeadPHINode(PN, VDL);
+}
+
/// MergeBlockIntoPredecessor - Attempts to merge a block into its predecessor,
/// if possible. The return value indicates success or failure.
bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Local.cpp Sat May 2 13:29:22 2009
@@ -19,6 +19,7 @@
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetData.h"
@@ -177,14 +178,18 @@
return false;
}
+/// ~ValueDeletionListener - A trivial dtor, defined out of line to give the
+/// class a home.
+llvm::ValueDeletionListener::~ValueDeletionListener() {}
+
/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
/// trivially dead instruction, delete it. If that makes any of its operands
/// trivially dead, delete them too, recursively.
///
-/// If DeadInst is specified, the vector is filled with the instructions that
-/// are actually deleted.
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V,
- SmallVectorImpl<Instruction*> *DeadInst) {
+ ValueDeletionListener *VDL) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I || !I->use_empty() || !isInstructionTriviallyDead(I))
return;
@@ -197,8 +202,8 @@
DeadInsts.pop_back();
// If the client wanted to know, tell it about deleted instructions.
- if (DeadInst)
- DeadInst->push_back(I);
+ if (VDL)
+ VDL->ValueWillBeDeleted(I);
// Null out all of the instruction's operands to see if any operand becomes
// dead as we go.
@@ -220,6 +225,38 @@
}
}
+/// RecursivelyDeleteDeadPHINode - If the specified value is an effectively
+/// dead PHI node, due to being a def-use chain of single-use nodes that
+/// either forms a cycle or is terminated by a trivially dead instruction,
+/// delete it. If that makes any of its operands trivially dead, delete them
+/// too, recursively.
+///
+/// If a ValueDeletionListener is specified, it is notified of instructions that
+/// are actually deleted (before they are actually deleted).
+void
+llvm::RecursivelyDeleteDeadPHINode(PHINode *PN, ValueDeletionListener *VDL) {
+
+ // We can remove a PHI if it is on a cycle in the def-use graph
+ // where each node in the cycle has degree one, i.e. only one use,
+ // and is an instruction with no side effects.
+ if (!PN->hasOneUse())
+ return;
+
+ SmallPtrSet<PHINode *, 4> PHIs;
+ PHIs.insert(PN);
+ for (Instruction *J = cast<Instruction>(*PN->use_begin());
+ J->hasOneUse() && !J->mayWriteToMemory();
+ J = cast<Instruction>(*J->use_begin()))
+ // If we find a PHI more than once, we're on a cycle that
+ // won't prove fruitful.
+ if (PHINode *JP = dyn_cast<PHINode>(J))
+ if (!PHIs.insert(cast<PHINode>(JP))) {
+ // Break the cycle and delete the PHI and its operands.
+ JP->replaceAllUsesWith(UndefValue::get(JP->getType()));
+ RecursivelyDeleteTriviallyDeadInstructions(JP, VDL);
+ break;
+ }
+}
//===----------------------------------------------------------------------===//
// Control Flow Graph Restructuring...
Modified: llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/2008-11-19-ScavengerAssert.ll Sat May 2 13:29:22 2009
@@ -1,5 +1,4 @@
-; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9
-; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 -stats |& grep asm-printer | grep 186
+; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin9 -stats |& grep asm-printer | grep 184
%"struct.Adv5::Ekin<3>" = type <{ i8 }>
%"struct.Adv5::X::Energyflux<3>" = type { double }
Modified: llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll (original)
+++ llvm/trunk/test/CodeGen/X86/mmx-vzmovl-2.ll Sat May 2 13:29:22 2009
@@ -17,6 +17,7 @@
%tmp555 = and <2 x i32> %1, < i32 -1, i32 0 > ; <<2 x i32>> [#uses=1]
%2 = bitcast <2 x i32> %tmp555 to <1 x i64> ; <<1 x i64>> [#uses=1]
%3 = call <1 x i64> @llvm.x86.mmx.psrli.q(<1 x i64> %0, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1]
+ store <1 x i64> %sum.0.reg2mem.0, <1 x i64>* null
%tmp558 = add <1 x i64> %sum.0.reg2mem.0, %2 ; <<1 x i64>> [#uses=1]
%4 = call <1 x i64> @llvm.x86.mmx.psrli.q(<1 x i64> %tmp558, i32 32) nounwind readnone ; <<1 x i64>> [#uses=1]
%tmp562 = add <1 x i64> %4, %3 ; <<1 x i64>> [#uses=1]
Modified: llvm/trunk/test/CodeGen/X86/pre-split4.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pre-split4.ll?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pre-split4.ll (original)
+++ llvm/trunk/test/CodeGen/X86/pre-split4.ll Sat May 2 13:29:22 2009
@@ -14,6 +14,8 @@
%2 = tail call double @sin(double %k.0.reg2mem.0) nounwind readonly ; <double> [#uses=1]
%3 = mul double 0.000000e+00, %2 ; <double> [#uses=1]
%4 = fdiv double 1.000000e+00, %3 ; <double> [#uses=1]
+ store double %Flint.0.reg2mem.0, double* null
+ store double %twoThrd.0.reg2mem.0, double* null
%5 = add double %4, %Flint.0.reg2mem.0 ; <double> [#uses=1]
%6 = add double %k.0.reg2mem.0, 1.000000e+00 ; <double> [#uses=1]
br label %bb
Modified: llvm/trunk/test/Transforms/LoopStrengthReduce/pr2570.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/pr2570.ll?rev=70636&r1=70635&r2=70636&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopStrengthReduce/pr2570.ll (original)
+++ llvm/trunk/test/Transforms/LoopStrengthReduce/pr2570.ll Sat May 2 13:29:22 2009
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep {phi\\>} | count 14
+; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep {phi\\>} | count 10
; PR2570
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
More information about the llvm-commits
mailing list