[llvm-commits] [llvm] r121201 - in /llvm/trunk/lib/CodeGen: LiveIntervalUnion.cpp LiveIntervalUnion.h RegAllocBase.h RegAllocBasic.cpp
Jakob Stoklund Olesen
stoklund at 2pi.dk
Tue Dec 7 15:18:47 PST 2010
Author: stoklund
Date: Tue Dec 7 17:18:47 2010
New Revision: 121201
URL: http://llvm.org/viewvc/llvm-project?rev=121201&view=rev
Log:
Switch LiveIntervalUnion from std::set to IntervalMap.
This speeds up RegAllocBasic by 20%, not counting releaseMemory which becomes
way faster.
Modified:
llvm/trunk/lib/CodeGen/LiveIntervalUnion.cpp
llvm/trunk/lib/CodeGen/LiveIntervalUnion.h
llvm/trunk/lib/CodeGen/RegAllocBase.h
llvm/trunk/lib/CodeGen/RegAllocBasic.cpp
Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalUnion.cpp?rev=121201&r1=121200&r2=121201&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalUnion.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalUnion.cpp Tue Dec 7 17:18:47 2010
@@ -21,98 +21,50 @@
#include <algorithm>
using namespace llvm;
-// Find the first segment in the range [SegBegin,Segments.end()) that
-// intersects with LS. If no intersection is found, return the first SI
-// such that SI.start >= LS.End.
-//
-// This logic is tied to the underlying LiveSegments data structure. For now, we
-// use set::upper_bound to find the nearest starting position,
-// then reverse iterate to find the first overlap.
-//
-// Upon entry we have SegBegin.Start < LS.End
-// SegBegin |--...
-// \ .
-// LS ...-|
-//
-// After set::upper_bound, we have SI.start >= LS.start:
-// SI |--...
-// /
-// LS |--...
-//
-// Assuming intervals are disjoint, if an intersection exists, it must be the
-// segment found or the one immediately preceeding it. We continue reverse
-// iterating to return the first overlapping segment.
-LiveIntervalUnion::SegmentIter
-LiveIntervalUnion::upperBound(SegmentIter SegBegin,
- const LiveSegment &LS) {
- assert(LS.End > SegBegin->Start && "segment iterator precondition");
-
- // Get the next LIU segment such that segI->Start is not less than seg.Start
- //
- // FIXME: Once we have a B+tree, we can make good use of SegBegin as a hint to
- // upper_bound. For now, we're forced to search again from the root each time.
- SegmentIter SI = Segments.upper_bound(LS);
- while (SI != SegBegin) {
- --SI;
- if (LS.Start >= SI->End)
- return ++SI;
- }
- return SI;
-}
// Merge a LiveInterval's segments. Guarantee no overlaps.
-//
-// After implementing B+tree, segments will be coalesced.
void LiveIntervalUnion::unify(LiveInterval &VirtReg) {
+ if (VirtReg.empty())
+ return;
// Insert each of the virtual register's live segments into the map.
- SegmentIter SegPos = Segments.begin();
- for (LiveInterval::iterator VirtRegI = VirtReg.begin(),
- VirtRegEnd = VirtReg.end();
- VirtRegI != VirtRegEnd; ++VirtRegI ) {
-
- LiveSegment Seg(*VirtRegI, &VirtReg);
- SegPos = Segments.insert(SegPos, Seg);
-
- assert(*SegPos == Seg && "need equal val for equal key");
-#ifndef NDEBUG
- // Check for overlap (inductively).
- if (SegPos != Segments.begin()) {
- assert(llvm::prior(SegPos)->End <= Seg.Start && "overlapping segments" );
- }
- SegmentIter NextPos = llvm::next(SegPos);
- if (NextPos != Segments.end())
- assert(Seg.End <= NextPos->Start && "overlapping segments" );
-#endif // NDEBUG
+ LiveInterval::iterator RegPos = VirtReg.begin();
+ LiveInterval::iterator RegEnd = VirtReg.end();
+ SegmentIter SegPos = Segments.find(RegPos->start);
+
+ for (;;) {
+ SegPos.insert(RegPos->start, RegPos->end, &VirtReg);
+ if (++RegPos == RegEnd)
+ return;
+ SegPos.advanceTo(RegPos->start);
}
}
// Remove a live virtual register's segments from this union.
-void LiveIntervalUnion::extract(const LiveInterval &VirtReg) {
+void LiveIntervalUnion::extract(LiveInterval &VirtReg) {
+ if (VirtReg.empty())
+ return;
// Remove each of the virtual register's live segments from the map.
- SegmentIter SegPos = Segments.begin();
- for (LiveInterval::const_iterator VirtRegI = VirtReg.begin(),
- VirtRegEnd = VirtReg.end();
- VirtRegI != VirtRegEnd; ++VirtRegI) {
-
- LiveSegment Seg(*VirtRegI, const_cast<LiveInterval*>(&VirtReg));
- SegPos = upperBound(SegPos, Seg);
- assert(SegPos != Segments.end() && "missing VirtReg segment");
+ LiveInterval::iterator RegPos = VirtReg.begin();
+ LiveInterval::iterator RegEnd = VirtReg.end();
+ SegmentIter SegPos = Segments.find(RegPos->start);
+
+ for (;;) {
+ assert(SegPos.value() == &VirtReg && "Inconsistent LiveInterval");
+ SegPos.erase();
+ if (!SegPos.valid())
+ return;
+
+ // Skip all segments that may have been coalesced.
+ RegPos = VirtReg.advanceTo(RegPos, SegPos.start());
+ if (RegPos == RegEnd)
+ return;
- Segments.erase(SegPos++);
+ SegPos.advanceTo(RegPos->start);
}
}
-raw_ostream& llvm::operator<<(raw_ostream& OS, const LiveSegment &LS) {
- return OS << '[' << LS.Start << ',' << LS.End << ':' <<
- LS.VirtReg->reg << ")";
-}
-
-void LiveSegment::dump() const {
- dbgs() << *this << "\n";
-}
-
void
LiveIntervalUnion::print(raw_ostream &OS,
const AbstractRegisterDescription *RegDesc) const {
@@ -122,10 +74,9 @@
else {
OS << RepReg;
}
- for (LiveSegments::const_iterator SI = Segments.begin(),
- SegEnd = Segments.end(); SI != SegEnd; ++SI) {
- dbgs() << " " << *SI;
- }
+ for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI)
+ dbgs() << " [" << SI.start() << ' ' << SI.stop() << "):%reg"
+ << SI.value()->reg;
OS << "\n";
}
@@ -136,14 +87,8 @@
#ifndef NDEBUG
// Verify the live intervals in this union and add them to the visited set.
void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) {
- SegmentIter SI = Segments.begin();
- SegmentIter SegEnd = Segments.end();
- if (SI == SegEnd) return;
- VisitedVRegs.set(SI->VirtReg->reg);
- for (++SI; SI != SegEnd; ++SI) {
- VisitedVRegs.set(SI->VirtReg->reg);
- assert(llvm::prior(SI)->End <= SI->Start && "overlapping segments" );
- }
+ for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI)
+ VisitedVRegs.set(SI.value()->reg);
}
#endif //!NDEBUG
@@ -169,36 +114,30 @@
// Search until reaching the end of the LiveUnion segments.
LiveInterval::iterator VirtRegEnd = VirtReg->end();
- SegmentIter LiveUnionEnd = LiveUnion->end();
- while (IR.LiveUnionI != LiveUnionEnd) {
-
+ while (IR.LiveUnionI.valid()) {
// Slowly advance the live virtual reg iterator until we surpass the next
// segment in LiveUnion.
//
// Note: If this is ever used for coalescing of fixed registers and we have
// a live vreg with thousands of segments, then change this code to use
// upperBound instead.
- while (IR.VirtRegI != VirtRegEnd &&
- IR.VirtRegI->end <= IR.LiveUnionI->Start)
- ++IR.VirtRegI;
+ IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
if (IR.VirtRegI == VirtRegEnd)
break; // Retain current (nonoverlapping) LiveUnionI
- // VirtRegI may have advanced far beyond LiveUnionI,
- // do a fast intersection test to "catch up"
- LiveSegment Seg(*IR.VirtRegI, VirtReg);
- IR.LiveUnionI = LiveUnion->upperBound(IR.LiveUnionI, Seg);
+ // VirtRegI may have advanced far beyond LiveUnionI, catch up.
+ IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
// Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end
- if (IR.LiveUnionI == LiveUnionEnd)
+ if (!IR.LiveUnionI.valid())
break;
- if (IR.LiveUnionI->Start < IR.VirtRegI->end) {
- assert(overlap(*IR.VirtRegI, *IR.LiveUnionI) &&
+ if (IR.LiveUnionI.start() < IR.VirtRegI->end) {
+ assert(overlap(*IR.VirtRegI, IR.LiveUnionI) &&
"upperBound postcondition");
break;
}
}
- if (IR.LiveUnionI == LiveUnionEnd)
+ if (!IR.LiveUnionI.valid())
IR.VirtRegI = VirtRegEnd;
}
@@ -221,18 +160,18 @@
// Advance either the VirtReg or LiveUnion segment to ensure that we visit all
// unique overlapping pairs.
- if (IR.VirtRegI->end < IR.LiveUnionI->End) {
+ if (IR.VirtRegI->end < IR.LiveUnionI.stop()) {
if (++IR.VirtRegI == VirtReg->end())
return false;
}
else {
- if (++IR.LiveUnionI == LiveUnion->end()) {
+ if (!(++IR.LiveUnionI).valid()) {
IR.VirtRegI = VirtReg->end();
return false;
}
}
// Short-circuit findIntersection() if possible.
- if (overlap(*IR.VirtRegI, *IR.LiveUnionI))
+ if (overlap(*IR.VirtRegI, IR.LiveUnionI))
return true;
// Find the next intersection.
@@ -261,55 +200,47 @@
collectInterferingVRegs(unsigned MaxInterferingRegs) {
InterferenceResult IR = firstInterference();
LiveInterval::iterator VirtRegEnd = VirtReg->end();
- SegmentIter LiveUnionEnd = LiveUnion->end();
LiveInterval *RecentInterferingVReg = NULL;
- while (IR.LiveUnionI != LiveUnionEnd) {
+ while (IR.LiveUnionI.valid()) {
// Advance the union's iterator to reach an unseen interfering vreg.
do {
- if (IR.LiveUnionI->VirtReg == RecentInterferingVReg)
+ if (IR.LiveUnionI.value() == RecentInterferingVReg)
continue;
- if (!isSeenInterference(IR.LiveUnionI->VirtReg))
+ if (!isSeenInterference(IR.LiveUnionI.value()))
break;
// Cache the most recent interfering vreg to bypass isSeenInterference.
- RecentInterferingVReg = IR.LiveUnionI->VirtReg;
+ RecentInterferingVReg = IR.LiveUnionI.value();
- } while( ++IR.LiveUnionI != LiveUnionEnd);
- if (IR.LiveUnionI == LiveUnionEnd)
+ } while ((++IR.LiveUnionI).valid());
+ if (!IR.LiveUnionI.valid())
break;
// Advance the VirtReg iterator until surpassing the next segment in
// LiveUnion.
- //
- // Note: If this is ever used for coalescing of fixed registers and we have
- // a live virtual register with thousands of segments, then use upperBound
- // instead.
- while (IR.VirtRegI != VirtRegEnd &&
- IR.VirtRegI->end <= IR.LiveUnionI->Start)
- ++IR.VirtRegI;
+ IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start());
if (IR.VirtRegI == VirtRegEnd)
break;
// Check for intersection with the union's segment.
- if (overlap(*IR.VirtRegI, *IR.LiveUnionI)) {
+ if (overlap(*IR.VirtRegI, IR.LiveUnionI)) {
- if (!IR.LiveUnionI->VirtReg->isSpillable())
+ if (!IR.LiveUnionI.value()->isSpillable())
SeenUnspillableVReg = true;
- InterferingVRegs.push_back(IR.LiveUnionI->VirtReg);
+ InterferingVRegs.push_back(IR.LiveUnionI.value());
if (InterferingVRegs.size() == MaxInterferingRegs)
return MaxInterferingRegs;
// Cache the most recent interfering vreg to bypass isSeenInterference.
- RecentInterferingVReg = IR.LiveUnionI->VirtReg;
+ RecentInterferingVReg = IR.LiveUnionI.value();
++IR.LiveUnionI;
continue;
}
// VirtRegI may have advanced far beyond LiveUnionI,
// do a fast intersection test to "catch up"
- LiveSegment Seg(*IR.VirtRegI, VirtReg);
- IR.LiveUnionI = LiveUnion->upperBound(IR.LiveUnionI, Seg);
+ IR.LiveUnionI.advanceTo(IR.VirtRegI->start);
}
SeenAllInterferences = true;
return InterferingVRegs.size();
Modified: llvm/trunk/lib/CodeGen/LiveIntervalUnion.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalUnion.h?rev=121201&r1=121200&r2=121201&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalUnion.h (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalUnion.h Tue Dec 7 17:18:47 2010
@@ -17,8 +17,8 @@
#ifndef LLVM_CODEGEN_LIVEINTERVALUNION
#define LLVM_CODEGEN_LIVEINTERVALUNION
+#include "llvm/ADT/IntervalMap.h"
#include "llvm/CodeGen/LiveInterval.h"
-#include <set>
namespace llvm {
@@ -28,58 +28,6 @@
typedef SparseBitVector<128> LiveVirtRegBitSet;
#endif
-/// A LiveSegment is a copy of a LiveRange object used within
-/// LiveIntervalUnion. LiveSegment additionally contains a pointer to its
-/// original live virtual register (LiveInterval). This allows quick lookup of
-/// the live virtual register as we iterate over live segments in a union. Note
-/// that LiveRange is misnamed and actually represents only a single contiguous
-/// interval within a virtual register's liveness. To limit confusion, in this
-/// file we refer it as a live segment.
-///
-/// Note: This currently represents a half-open interval [Start,End).
-/// If LiveRange is modified to represent a closed interval, so should this.
-struct LiveSegment {
- SlotIndex Start;
- SlotIndex End;
- LiveInterval *VirtReg;
-
- LiveSegment(const LiveRange& LR, LiveInterval *VReg)
- : Start(LR.start), End(LR.end), VirtReg(VReg) {}
-
- bool operator==(const LiveSegment &LS) const {
- return Start == LS.Start && End == LS.End && VirtReg == LS.VirtReg;
- }
-
- bool operator!=(const LiveSegment &LS) const {
- return !operator==(LS);
- }
-
- // Order segments by starting point only--we expect them to be disjoint.
- bool operator<(const LiveSegment &LS) const { return Start < LS.Start; }
-
- void dump() const;
- void print(raw_ostream &OS) const;
-};
-
-inline bool operator<(SlotIndex Idx, const LiveSegment &LS) {
- return Idx < LS.Start;
-}
-
-inline bool operator<(const LiveSegment &LS, SlotIndex Idx) {
- return LS.Start < Idx;
-}
-
-/// Compare a live virtual register segment to a LiveIntervalUnion segment.
-inline bool overlap(const LiveRange &VirtRegSegment,
- const LiveSegment &LiveUnionSegment) {
- return VirtRegSegment.start < LiveUnionSegment.End &&
- LiveUnionSegment.Start < VirtRegSegment.end;
-}
-
-template <> struct isPodLike<LiveSegment> { static const bool value = true; };
-
-raw_ostream& operator<<(raw_ostream& OS, const LiveSegment &LS);
-
/// Abstraction to provide info for the representative register.
class AbstractRegisterDescription {
public:
@@ -87,6 +35,13 @@
virtual ~AbstractRegisterDescription() {}
};
+/// Compare a live virtual register segment to a LiveIntervalUnion segment.
+inline bool
+overlap(const LiveRange &VRSeg,
+ const IntervalMap<SlotIndex, LiveInterval*>::const_iterator &LUSeg) {
+ return VRSeg.start < LUSeg.stop() && LUSeg.start() < VRSeg.end;
+}
+
/// Union of live intervals that are strong candidates for coalescing into a
/// single register (either physical or virtual depending on the context). We
/// expect the constituent live intervals to be disjoint, although we may
@@ -94,10 +49,8 @@
class LiveIntervalUnion {
// A set of live virtual register segments that supports fast insertion,
// intersection, and removal.
- //
- // FIXME: std::set is a placeholder until we decide how to
- // efficiently represent it. Probably need to roll our own B-tree.
- typedef std::set<LiveSegment> LiveSegments;
+ // Mapping SlotIndex intervals to virtual register numbers.
+ typedef IntervalMap<SlotIndex, LiveInterval*> LiveSegments;
public:
// SegmentIter can advance to the next segment ordered by starting position
@@ -105,36 +58,29 @@
// to reach the current segment's containing virtual register.
typedef LiveSegments::iterator SegmentIter;
+ // LiveIntervalUnions share an external allocator.
+ typedef LiveSegments::Allocator Allocator;
+
class InterferenceResult;
class Query;
private:
- unsigned RepReg; // representative register number
- LiveSegments Segments; // union of virtual reg segements
+ const unsigned RepReg; // representative register number
+ LiveSegments Segments; // union of virtual reg segments
public:
- // default ctor avoids placement new
- LiveIntervalUnion() : RepReg(0) {}
-
- // Initialize the union by associating it with a representative register
- // number.
- void init(unsigned Reg) { RepReg = Reg; }
+ LiveIntervalUnion(unsigned r, Allocator &a) : RepReg(r), Segments(a) {}
// Iterate over all segments in the union of live virtual registers ordered
// by their starting position.
SegmentIter begin() { return Segments.begin(); }
SegmentIter end() { return Segments.end(); }
- // Return an iterator to the first segment after or including begin that
- // intersects with LS.
- SegmentIter upperBound(SegmentIter SegBegin, const LiveSegment &LS);
-
// Add a live virtual register to this union and merge its segments.
- // Holds a nonconst reference to the VirtReg for later maniplution.
void unify(LiveInterval &VirtReg);
// Remove a live virtual register's segments from this union.
- void extract(const LiveInterval &VirtReg);
+ void extract(LiveInterval &VirtReg);
void dump(const AbstractRegisterDescription *RegDesc) const;
@@ -171,7 +117,7 @@
LiveInterval::iterator virtRegPos() const { return VirtRegI; }
// Access the LiveUnion segment.
- SegmentIter liveUnionPos() const { return LiveUnionI; }
+ const SegmentIter &liveUnionPos() const { return LiveUnionI; }
bool operator==(const InterferenceResult &IR) const {
return VirtRegI == IR.VirtRegI && LiveUnionI == IR.LiveUnionI;
@@ -228,7 +174,7 @@
bool isInterference(const InterferenceResult &IR) const {
if (IR.VirtRegI != VirtReg->end()) {
- assert(overlap(*IR.VirtRegI, *IR.LiveUnionI) &&
+ assert(overlap(*IR.VirtRegI, IR.LiveUnionI) &&
"invalid segment iterators");
return true;
}
Modified: llvm/trunk/lib/CodeGen/RegAllocBase.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBase.h?rev=121201&r1=121200&r2=121201&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocBase.h (original)
+++ llvm/trunk/lib/CodeGen/RegAllocBase.h Tue Dec 7 17:18:47 2010
@@ -38,6 +38,7 @@
#define LLVM_CODEGEN_REGALLOCBASE
#include "llvm/ADT/OwningPtr.h"
+#include "LiveIntervalUnion.h"
namespace llvm {
@@ -69,17 +70,19 @@
/// live range splitting. LessSpillWeightPriority is provided as a standard
/// comparator, but we may add an interface to override it if necessary.
class RegAllocBase {
+ LiveIntervalUnion::Allocator UnionAllocator;
protected:
// Array of LiveIntervalUnions indexed by physical register.
class LiveUnionArray {
unsigned NumRegs;
- OwningArrayPtr<LiveIntervalUnion> Array;
+ LiveIntervalUnion *Array;
public:
- LiveUnionArray(): NumRegs(0) {}
+ LiveUnionArray(): NumRegs(0), Array(0) {}
+ ~LiveUnionArray() { clear(); }
unsigned numRegs() const { return NumRegs; }
- void init(unsigned NRegs);
+ void init(LiveIntervalUnion::Allocator &, unsigned NRegs);
void clear();
Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBasic.cpp?rev=121201&r1=121200&r2=121201&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegAllocBasic.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Tue Dec 7 17:18:47 2010
@@ -19,6 +19,7 @@
#include "Spiller.h"
#include "VirtRegMap.h"
#include "VirtRegRewriter.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Function.h"
#include "llvm/PassAnalysisSupport.h"
@@ -44,6 +45,7 @@
#include <vector>
#include <queue>
+#include <cstdlib>
using namespace llvm;
@@ -198,12 +200,13 @@
//===----------------------------------------------------------------------===//
// Instantiate a LiveIntervalUnion for each physical register.
-void RegAllocBase::LiveUnionArray::init(unsigned NRegs) {
- Array.reset(new LiveIntervalUnion[NRegs]);
+void RegAllocBase::LiveUnionArray::init(LiveIntervalUnion::Allocator &allocator,
+ unsigned NRegs) {
NumRegs = NRegs;
- for (unsigned RegNum = 0; RegNum < NRegs; ++RegNum) {
- Array[RegNum].init(RegNum);
- }
+ Array =
+ static_cast<LiveIntervalUnion*>(malloc(sizeof(LiveIntervalUnion)*NRegs));
+ for (unsigned r = 0; r != NRegs; ++r)
+ new(Array + r) LiveIntervalUnion(r, allocator);
}
void RegAllocBase::init(const TargetRegisterInfo &tri, VirtRegMap &vrm,
@@ -211,14 +214,19 @@
TRI = &tri;
VRM = &vrm;
LIS = &lis;
- PhysReg2LiveUnion.init(TRI->getNumRegs());
+ PhysReg2LiveUnion.init(UnionAllocator, TRI->getNumRegs());
// Cache an interferece query for each physical reg
Queries.reset(new LiveIntervalUnion::Query[PhysReg2LiveUnion.numRegs()]);
}
void RegAllocBase::LiveUnionArray::clear() {
+ if (!Array)
+ return;
+ for (unsigned r = 0; r != NumRegs; ++r)
+ Array[r].~LiveIntervalUnion();
+ free(Array);
NumRegs = 0;
- Array.reset(0);
+ Array = 0;
}
void RegAllocBase::releaseMemory() {
@@ -427,7 +435,7 @@
return PhysReg;
}
LiveInterval *interferingVirtReg =
- Queries[interfReg].firstInterference().liveUnionPos()->VirtReg;
+ Queries[interfReg].firstInterference().liveUnionPos().value();
// The current VirtReg must either spillable, or one of its interferences
// must have less spill weight.
@@ -474,7 +482,7 @@
// Find the set of basic blocks which this range is live into...
liveInMBBs.clear();
- if (!LIS->findLiveInMBBs(SI->Start, SI->End, liveInMBBs)) continue;
+ if (!LIS->findLiveInMBBs(SI.start(), SI.stop(), liveInMBBs)) continue;
// And add the physreg for this interval to their live-in sets.
for (MBBVec::iterator I = liveInMBBs.begin(), E = liveInMBBs.end();
More information about the llvm-commits
mailing list