From c313c6b9fffa58e88c166e50a759d689686f17f0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 20 May 2012 02:44:30 +0000 Subject: [PATCH] Add a LiveRangeQuery class. This class is meant to be the primary interface for examining a live range in the vicinity on a given instruction. It avoids all the messy dealings with iterators and early clobbers. This is a more abstract interface to live ranges, hiding the implementation as a vector of segments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157141 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LiveInterval.h | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 3170952dd2d..96680e500d6 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -500,6 +500,91 @@ namespace llvm { return OS; } + /// LiveRangeQuery - Query information about a live range around a given + /// instruction. This class hides the implementation details of live ranges, + /// and it should be used as the primary interface for examining live ranges + /// around instructions. + /// + class LiveRangeQuery { + VNInfo *EarlyVal; + VNInfo *LateVal; + SlotIndex EndPoint; + bool Kill; + + public: + /// Create a LiveRangeQuery for the given live range and instruction index. + /// The sub-instruction slot of Idx doesn't matter, only the instruction it + /// refers to is considered. + LiveRangeQuery(const LiveInterval &LI, SlotIndex Idx) + : EarlyVal(0), LateVal(0), Kill(false) { + // Find the segment that enters the instruction. + LiveInterval::const_iterator I = LI.find(Idx.getBaseIndex()); + LiveInterval::const_iterator E = LI.end(); + if (I == E) + return; + // Is this an instruction live-in segment? + if (SlotIndex::isEarlierInstr(I->start, Idx)) { + EarlyVal = I->valno; + EndPoint = I->end; + // Move to the potentially live-out segment. + if (SlotIndex::isSameInstr(Idx, I->end)) { + Kill = true; + if (++I == E) + return; + } + } + // I now points to the segment that may be live-through, or defined by + // this instr. Ignore segments starting after the current instr. + if (SlotIndex::isEarlierInstr(Idx, I->start)) + return; + LateVal = I->valno; + EndPoint = I->end; + } + + /// Return the value that is live-in to the instruction. This is the value + /// that will be read by the instruction's use operands. Return NULL if no + /// value is live-in. + VNInfo *valueIn() const { + return EarlyVal; + } + + /// Return true if the live-in value is killed by this instruction. This + /// means that either the live range ends at the instruction, or it changes + /// value. + bool isKill() const { + return Kill; + } + + /// Return true if this instruction has a dead def. + bool isDeadDef() const { + return EndPoint.isDead(); + } + + /// Return the value leaving the instruction, if any. This can be a + /// live-through value, or a live def. A dead def returns NULL. + VNInfo *valueOut() const { + return isDeadDef() ? 0 : LateVal; + } + + /// Return the value defined by this instruction, if any. This includes + /// dead defs, it is the value created by the instruction's def operands. + VNInfo *valueDefined() const { + return EarlyVal == LateVal ? 0 : LateVal; + } + + /// Return the end point of the last live range segment to interact with + /// the instruction, if any. + /// + /// The end point is an invalid SlotIndex only if the live range doesn't + /// intersect the instruction at all. + /// + /// The end point may be at or past the end of the instruction's basic + /// block. That means the value was live out of the block. + SlotIndex endPoint() const { + return EndPoint; + } + }; + /// ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a /// LiveInterval into equivalence clases of connected components. A /// LiveInterval that has multiple connected components can be broken into