LiveIntervalUnion.cpp (224145) | LiveIntervalUnion.cpp (226633) |
---|---|
1//===-- LiveIntervalUnion.cpp - Live interval union data structure --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 77 unchanged lines hidden (view full) --- 86 } 87 for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) { 88 OS << " [" << SI.start() << ' ' << SI.stop() << "):" 89 << PrintReg(SI.value()->reg, TRI); 90 } 91 OS << '\n'; 92} 93 | 1//===-- LiveIntervalUnion.cpp - Live interval union data structure --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// --- 77 unchanged lines hidden (view full) --- 86 } 87 for (LiveSegments::const_iterator SI = Segments.begin(); SI.valid(); ++SI) { 88 OS << " [" << SI.start() << ' ' << SI.stop() << "):" 89 << PrintReg(SI.value()->reg, TRI); 90 } 91 OS << '\n'; 92} 93 |
94void LiveIntervalUnion::InterferenceResult::print(raw_ostream &OS, 95 const TargetRegisterInfo *TRI) const { 96 OS << '[' << start() << ';' << stop() << "):" 97 << PrintReg(interference()->reg, TRI); 98} 99 100void LiveIntervalUnion::Query::print(raw_ostream &OS, 101 const TargetRegisterInfo *TRI) { 102 OS << "Interferences with "; 103 LiveUnion->print(OS, TRI); 104 InterferenceResult IR = firstInterference(); 105 while (isInterference(IR)) { 106 OS << " "; 107 IR.print(OS, TRI); 108 OS << '\n'; 109 nextInterference(IR); 110 } 111} 112 | |
113#ifndef NDEBUG 114// Verify the live intervals in this union and add them to the visited set. 115void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) { 116 for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI) 117 VisitedVRegs.set(SI.value()->reg); 118} 119#endif //!NDEBUG 120 | 94#ifndef NDEBUG 95// Verify the live intervals in this union and add them to the visited set. 96void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) { 97 for (SegmentIter SI = Segments.begin(); SI.valid(); ++SI) 98 VisitedVRegs.set(SI.value()->reg); 99} 100#endif //!NDEBUG 101 |
121// Private interface accessed by Query. 122// 123// Find a pair of segments that intersect, one in the live virtual register 124// (LiveInterval), and the other in this LiveIntervalUnion. The caller (Query) 125// is responsible for advancing the LiveIntervalUnion segments to find a 126// "notable" intersection, which requires query-specific logic. 127// 128// This design assumes only a fast mechanism for intersecting a single live 129// virtual register segment with a set of LiveIntervalUnion segments. This may 130// be ok since most virtual registers have very few segments. If we had a data 131// structure that optimizd MxN intersection of segments, then we would bypass 132// the loop that advances within the LiveInterval. 133// 134// If no intersection exists, set VirtRegI = VirtRegEnd, and set SI to the first 135// segment whose start point is greater than LiveInterval's end point. 136// 137// Assumes that segments are sorted by start position in both 138// LiveInterval and LiveSegments. 139void LiveIntervalUnion::Query::findIntersection(InterferenceResult &IR) const { 140 // Search until reaching the end of the LiveUnion segments. 141 LiveInterval::iterator VirtRegEnd = VirtReg->end(); 142 if (IR.VirtRegI == VirtRegEnd) 143 return; 144 while (IR.LiveUnionI.valid()) { 145 // Slowly advance the live virtual reg iterator until we surpass the next 146 // segment in LiveUnion. 147 // 148 // Note: If this is ever used for coalescing of fixed registers and we have 149 // a live vreg with thousands of segments, then change this code to use 150 // upperBound instead. 151 IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start()); 152 if (IR.VirtRegI == VirtRegEnd) 153 break; // Retain current (nonoverlapping) LiveUnionI 154 155 // VirtRegI may have advanced far beyond LiveUnionI, catch up. 156 IR.LiveUnionI.advanceTo(IR.VirtRegI->start); 157 158 // Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end 159 if (!IR.LiveUnionI.valid()) 160 break; 161 if (IR.LiveUnionI.start() < IR.VirtRegI->end) { 162 assert(overlap(*IR.VirtRegI, IR.LiveUnionI) && 163 "upperBound postcondition"); 164 break; 165 } 166 } 167 if (!IR.LiveUnionI.valid()) 168 IR.VirtRegI = VirtRegEnd; 169} 170 171// Find the first intersection, and cache interference info 172// (retain segment iterators into both VirtReg and LiveUnion). 173const LiveIntervalUnion::InterferenceResult & 174LiveIntervalUnion::Query::firstInterference() { 175 if (CheckedFirstInterference) 176 return FirstInterference; 177 CheckedFirstInterference = true; 178 InterferenceResult &IR = FirstInterference; 179 IR.LiveUnionI.setMap(LiveUnion->getMap()); 180 181 // Quickly skip interference check for empty sets. 182 if (VirtReg->empty() || LiveUnion->empty()) { 183 IR.VirtRegI = VirtReg->end(); 184 } else if (VirtReg->beginIndex() < LiveUnion->startIndex()) { 185 // VirtReg starts first, perform double binary search. 186 IR.VirtRegI = VirtReg->find(LiveUnion->startIndex()); 187 if (IR.VirtRegI != VirtReg->end()) 188 IR.LiveUnionI.find(IR.VirtRegI->start); 189 } else { 190 // LiveUnion starts first, perform double binary search. 191 IR.LiveUnionI.find(VirtReg->beginIndex()); 192 if (IR.LiveUnionI.valid()) 193 IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start()); 194 else 195 IR.VirtRegI = VirtReg->end(); 196 } 197 findIntersection(FirstInterference); 198 assert((IR.VirtRegI == VirtReg->end() || IR.LiveUnionI.valid()) 199 && "Uninitialized iterator"); 200 return FirstInterference; 201} 202 203// Treat the result as an iterator and advance to the next interfering pair 204// of segments. This is a plain iterator with no filter. 205bool LiveIntervalUnion::Query::nextInterference(InterferenceResult &IR) const { 206 assert(isInterference(IR) && "iteration past end of interferences"); 207 208 // Advance either the VirtReg or LiveUnion segment to ensure that we visit all 209 // unique overlapping pairs. 210 if (IR.VirtRegI->end < IR.LiveUnionI.stop()) { 211 if (++IR.VirtRegI == VirtReg->end()) 212 return false; 213 } 214 else { 215 if (!(++IR.LiveUnionI).valid()) { 216 IR.VirtRegI = VirtReg->end(); 217 return false; 218 } 219 } 220 // Short-circuit findIntersection() if possible. 221 if (overlap(*IR.VirtRegI, IR.LiveUnionI)) 222 return true; 223 224 // Find the next intersection. 225 findIntersection(IR); 226 return isInterference(IR); 227} 228 | |
229// Scan the vector of interfering virtual registers in this union. Assume it's 230// quite small. 231bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const { 232 SmallVectorImpl<LiveInterval*>::const_iterator I = 233 std::find(InterferingVRegs.begin(), InterferingVRegs.end(), VirtReg); 234 return I != InterferingVRegs.end(); 235} 236 | 102// Scan the vector of interfering virtual registers in this union. Assume it's 103// quite small. 104bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const { 105 SmallVectorImpl<LiveInterval*>::const_iterator I = 106 std::find(InterferingVRegs.begin(), InterferingVRegs.end(), VirtReg); 107 return I != InterferingVRegs.end(); 108} 109 |
237// Count the number of virtual registers in this union that interfere with this | 110// Collect virtual registers in this union that interfere with this |
238// query's live virtual register. 239// | 111// query's live virtual register. 112// |
240// The number of times that we either advance IR.VirtRegI or call 241// LiveUnion.upperBound() will be no more than the number of holes in 242// VirtReg. So each invocation of collectInterferingVRegs() takes 243// time proportional to |VirtReg Holes| * time(LiveUnion.upperBound()). | 113// The query state is one of: |
244// | 114// |
245// For comments on how to speed it up, see Query::findIntersection(). | 115// 1. CheckedFirstInterference == false: Iterators are uninitialized. 116// 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused. 117// 3. Iterators left at the last seen intersection. 118// |
246unsigned LiveIntervalUnion::Query:: 247collectInterferingVRegs(unsigned MaxInterferingRegs) { | 119unsigned LiveIntervalUnion::Query:: 120collectInterferingVRegs(unsigned MaxInterferingRegs) { |
248 InterferenceResult IR = firstInterference(); 249 LiveInterval::iterator VirtRegEnd = VirtReg->end(); 250 LiveInterval *RecentInterferingVReg = NULL; 251 if (IR.VirtRegI != VirtRegEnd) while (IR.LiveUnionI.valid()) { 252 // Advance the union's iterator to reach an unseen interfering vreg. 253 do { 254 if (IR.LiveUnionI.value() == RecentInterferingVReg) 255 continue; | 121 // Fast path return if we already have the desired information. 122 if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs) 123 return InterferingVRegs.size(); |
256 | 124 |
257 if (!isSeenInterference(IR.LiveUnionI.value())) 258 break; | 125 // Set up iterators on the first call. 126 if (!CheckedFirstInterference) { 127 CheckedFirstInterference = true; |
259 | 128 |
260 // Cache the most recent interfering vreg to bypass isSeenInterference. 261 RecentInterferingVReg = IR.LiveUnionI.value(); | 129 // Quickly skip interference check for empty sets. 130 if (VirtReg->empty() || LiveUnion->empty()) { 131 SeenAllInterferences = true; 132 return 0; 133 } |
262 | 134 |
263 } while ((++IR.LiveUnionI).valid()); 264 if (!IR.LiveUnionI.valid()) 265 break; | 135 // In most cases, the union will start before VirtReg. 136 VirtRegI = VirtReg->begin(); 137 LiveUnionI.setMap(LiveUnion->getMap()); 138 LiveUnionI.find(VirtRegI->start); 139 } |
266 | 140 |
267 // Advance the VirtReg iterator until surpassing the next segment in 268 // LiveUnion. 269 IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start()); 270 if (IR.VirtRegI == VirtRegEnd) 271 break; | 141 LiveInterval::iterator VirtRegEnd = VirtReg->end(); 142 LiveInterval *RecentReg = 0; 143 while (LiveUnionI.valid()) { 144 assert(VirtRegI != VirtRegEnd && "Reached end of VirtReg"); |
272 | 145 |
273 // Check for intersection with the union's segment. 274 if (overlap(*IR.VirtRegI, IR.LiveUnionI)) { | 146 // Check for overlapping interference. 147 while (VirtRegI->start < LiveUnionI.stop() && 148 VirtRegI->end > LiveUnionI.start()) { 149 // This is an overlap, record the interfering register. 150 LiveInterval *VReg = LiveUnionI.value(); 151 if (VReg != RecentReg && !isSeenInterference(VReg)) { 152 RecentReg = VReg; 153 InterferingVRegs.push_back(VReg); 154 if (InterferingVRegs.size() >= MaxInterferingRegs) 155 return InterferingVRegs.size(); 156 } 157 // This LiveUnion segment is no longer interesting. 158 if (!(++LiveUnionI).valid()) { 159 SeenAllInterferences = true; 160 return InterferingVRegs.size(); 161 } 162 } |
275 | 163 |
276 if (!IR.LiveUnionI.value()->isSpillable()) 277 SeenUnspillableVReg = true; | 164 // The iterators are now not overlapping, LiveUnionI has been advanced 165 // beyond VirtRegI. 166 assert(VirtRegI->end <= LiveUnionI.start() && "Expected non-overlap"); |
278 | 167 |
279 if (InterferingVRegs.size() == MaxInterferingRegs) 280 // Leave SeenAllInterferences set to false to indicate that at least one 281 // interference exists beyond those we collected. 282 return MaxInterferingRegs; | 168 // Advance the iterator that ends first. 169 VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start()); 170 if (VirtRegI == VirtRegEnd) 171 break; |
283 | 172 |
284 InterferingVRegs.push_back(IR.LiveUnionI.value()); 285 286 // Cache the most recent interfering vreg to bypass isSeenInterference. 287 RecentInterferingVReg = IR.LiveUnionI.value(); 288 ++IR.LiveUnionI; 289 | 173 // Detect overlap, handle above. 174 if (VirtRegI->start < LiveUnionI.stop()) |
290 continue; | 175 continue; |
291 } 292 // VirtRegI may have advanced far beyond LiveUnionI, 293 // do a fast intersection test to "catch up" 294 IR.LiveUnionI.advanceTo(IR.VirtRegI->start); | 176 177 // Still not overlapping. Catch up LiveUnionI. 178 LiveUnionI.advanceTo(VirtRegI->start); |
295 } 296 SeenAllInterferences = true; 297 return InterferingVRegs.size(); 298} 299 300bool LiveIntervalUnion::Query::checkLoopInterference(MachineLoopRange *Loop) { 301 // VirtReg is likely live throughout the loop, so start by checking LIU-Loop 302 // overlaps. --- 23 unchanged lines hidden --- | 179 } 180 SeenAllInterferences = true; 181 return InterferingVRegs.size(); 182} 183 184bool LiveIntervalUnion::Query::checkLoopInterference(MachineLoopRange *Loop) { 185 // VirtReg is likely live throughout the loop, so start by checking LIU-Loop 186 // overlaps. --- 23 unchanged lines hidden --- |