summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-07-22 00:04:14 +0000
committerChris Lattner <sabre@nondot.org>2004-07-22 00:04:14 +0000
commit6ff60217123d497e8d0ccfa0d629b3221a92900a (patch)
tree66c6766c0672411890daa28794c634d6fa4fdfc4 /llvm/lib
parentadbbc62f82ba14ace6a37a7407031d312101c73f (diff)
downloadbcm5719-llvm-6ff60217123d497e8d0ccfa0d629b3221a92900a.tar.gz
bcm5719-llvm-6ff60217123d497e8d0ccfa0d629b3221a92900a.zip
That funny 2-address lowering pass can also cause multiple definitions,
fortunately, they are easy to handle if we know about them. This patch fixes some serious pessimization of code produced by the linscan register allocator. llvm-svn: 15092
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/LiveIntervals.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index dc9aab5cd37..2ef1ccae6d7 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -291,10 +291,10 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
// Virtual registers may be defined multiple times (due to phi
- // elimination). Much of what we do only has to be done once for the vreg.
- // We use an empty interval to detect the first time we see a vreg.
+ // elimination and 2-addr elimination). Much of what we do only has to be
+ // done once for the vreg. We use an empty interval to detect the first
+ // time we see a vreg.
if (interval.empty()) {
-
// Get the Idx of the defining instructions.
unsigned defIndex = getDefIndex(getInstructionIndex(mi));
@@ -351,11 +351,21 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock* mbb,
} else {
// If this is the second time we see a virtual register definition, it
- // must be due to phi elimination. In this case, the defined value will
- // be live until the end of the basic block it is defined in.
- unsigned defIndex = getDefIndex(getInstructionIndex(mi));
- interval.addRange(defIndex,
- getInstructionIndex(&mbb->back()) + InstrSlots::NUM);
+ // must be due to phi elimination or two addr elimination. If this is
+ // the result of two address elimination, then the vreg is the first
+ // operand, and is a def-and-use.
+ if (mi->getOperand(0).isRegister() &&
+ mi->getOperand(0).getReg() == interval.reg &&
+ mi->getOperand(0).isDef() && mi->getOperand(0).isUse()) {
+ // If this is a two-address definition, just ignore it.
+ } else {
+ // Otherwise, this must be because of phi elimination. In this case,
+ // the defined value will be live until the end of the basic block it
+ // is defined in.
+ unsigned defIndex = getDefIndex(getInstructionIndex(mi));
+ interval.addRange(defIndex,
+ getInstructionIndex(&mbb->back()) + InstrSlots::NUM);
+ }
}
DEBUG(std::cerr << '\n');
OpenPOWER on IntegriCloud