1 //===- RegisterPressure.h - Dynamic Register Pressure -----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the RegisterPressure class which can be used to track
10 // MachineInstr level register pressure.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_REGISTERPRESSURE_H
15 #define LLVM_CODEGEN_REGISTERPRESSURE_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/ADT/SparseSet.h"
20 #include "llvm/CodeGen/MachineBasicBlock.h"
21 #include "llvm/CodeGen/SlotIndexes.h"
22 #include "llvm/CodeGen/TargetRegisterInfo.h"
23 #include "llvm/MC/LaneBitmask.h"
24 #include <cassert>
25 #include <cstdint>
26 #include <cstdlib>
27 #include <limits>
28 #include <vector>
29 
30 namespace llvm {
31 
32 class LiveIntervals;
33 class MachineFunction;
34 class MachineInstr;
35 class MachineRegisterInfo;
36 class RegisterClassInfo;
37 
38 struct RegisterMaskPair {
39   Register RegUnit; ///< Virtual register or register unit.
40   LaneBitmask LaneMask;
41 
RegisterMaskPairRegisterMaskPair42   RegisterMaskPair(Register RegUnit, LaneBitmask LaneMask)
43       : RegUnit(RegUnit), LaneMask(LaneMask) {}
44 };
45 
46 /// Base class for register pressure results.
47 struct RegisterPressure {
48   /// Map of max reg pressure indexed by pressure set ID, not class ID.
49   std::vector<unsigned> MaxSetPressure;
50 
51   /// List of live in virtual registers or physical register units.
52   SmallVector<RegisterMaskPair,8> LiveInRegs;
53   SmallVector<RegisterMaskPair,8> LiveOutRegs;
54 
55   void dump(const TargetRegisterInfo *TRI) const;
56 };
57 
58 /// RegisterPressure computed within a region of instructions delimited by
59 /// TopIdx and BottomIdx.  During pressure computation, the maximum pressure per
60 /// register pressure set is increased. Once pressure within a region is fully
61 /// computed, the live-in and live-out sets are recorded.
62 ///
63 /// This is preferable to RegionPressure when LiveIntervals are available,
64 /// because delimiting regions by SlotIndex is more robust and convenient than
65 /// holding block iterators. The block contents can change without invalidating
66 /// the pressure result.
67 struct IntervalPressure : RegisterPressure {
68   /// Record the boundary of the region being tracked.
69   SlotIndex TopIdx;
70   SlotIndex BottomIdx;
71 
72   void reset();
73 
74   void openTop(SlotIndex NextTop);
75 
76   void openBottom(SlotIndex PrevBottom);
77 };
78 
79 /// RegisterPressure computed within a region of instructions delimited by
80 /// TopPos and BottomPos. This is a less precise version of IntervalPressure for
81 /// use when LiveIntervals are unavailable.
82 struct RegionPressure : RegisterPressure {
83   /// Record the boundary of the region being tracked.
84   MachineBasicBlock::const_iterator TopPos;
85   MachineBasicBlock::const_iterator BottomPos;
86 
87   void reset();
88 
89   void openTop(MachineBasicBlock::const_iterator PrevTop);
90 
91   void openBottom(MachineBasicBlock::const_iterator PrevBottom);
92 };
93 
94 /// Capture a change in pressure for a single pressure set. UnitInc may be
95 /// expressed in terms of upward or downward pressure depending on the client
96 /// and will be dynamically adjusted for current liveness.
97 ///
98 /// Pressure increments are tiny, typically 1-2 units, and this is only for
99 /// heuristics, so we don't check UnitInc overflow. Instead, we may have a
100 /// higher level assert that pressure is consistent within a region. We also
101 /// effectively ignore dead defs which don't affect heuristics much.
102 class PressureChange {
103   uint16_t PSetID = 0; // ID+1. 0=Invalid.
104   int16_t UnitInc = 0;
105 
106 public:
107   PressureChange() = default;
PressureChange(unsigned id)108   PressureChange(unsigned id): PSetID(id + 1) {
109     assert(id < std::numeric_limits<uint16_t>::max() && "PSetID overflow.");
110   }
111 
isValid()112   bool isValid() const { return PSetID > 0; }
113 
getPSet()114   unsigned getPSet() const {
115     assert(isValid() && "invalid PressureChange");
116     return PSetID - 1;
117   }
118 
119   // If PSetID is invalid, return UINT16_MAX to give it lowest priority.
getPSetOrMax()120   unsigned getPSetOrMax() const {
121     return (PSetID - 1) & std::numeric_limits<uint16_t>::max();
122   }
123 
getUnitInc()124   int getUnitInc() const { return UnitInc; }
125 
setUnitInc(int Inc)126   void setUnitInc(int Inc) { UnitInc = Inc; }
127 
128   bool operator==(const PressureChange &RHS) const {
129     return PSetID == RHS.PSetID && UnitInc == RHS.UnitInc;
130   }
131 
132   void dump() const;
133 };
134 
135 /// List of PressureChanges in order of increasing, unique PSetID.
136 ///
137 /// Use a small fixed number, because we can fit more PressureChanges in an
138 /// empty SmallVector than ever need to be tracked per register class. If more
139 /// PSets are affected, then we only track the most constrained.
140 class PressureDiff {
141   // The initial design was for MaxPSets=4, but that requires PSet partitions,
142   // which are not yet implemented. (PSet partitions are equivalent PSets given
143   // the register classes actually in use within the scheduling region.)
144   enum { MaxPSets = 16 };
145 
146   PressureChange PressureChanges[MaxPSets];
147 
148   using iterator = PressureChange *;
149 
nonconst_begin()150   iterator nonconst_begin() { return &PressureChanges[0]; }
nonconst_end()151   iterator nonconst_end() { return &PressureChanges[MaxPSets]; }
152 
153 public:
154   using const_iterator = const PressureChange *;
155 
begin()156   const_iterator begin() const { return &PressureChanges[0]; }
end()157   const_iterator end() const { return &PressureChanges[MaxPSets]; }
158 
159   void addPressureChange(Register RegUnit, bool IsDec,
160                          const MachineRegisterInfo *MRI);
161 
162   void dump(const TargetRegisterInfo &TRI) const;
163 };
164 
165 /// List of registers defined and used by a machine instruction.
166 class RegisterOperands {
167 public:
168   /// List of virtual registers and register units read by the instruction.
169   SmallVector<RegisterMaskPair, 8> Uses;
170   /// List of virtual registers and register units defined by the
171   /// instruction which are not dead.
172   SmallVector<RegisterMaskPair, 8> Defs;
173   /// List of virtual registers and register units defined by the
174   /// instruction but dead.
175   SmallVector<RegisterMaskPair, 8> DeadDefs;
176 
177   /// Analyze the given instruction \p MI and fill in the Uses, Defs and
178   /// DeadDefs list based on the MachineOperand flags.
179   void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI,
180                const MachineRegisterInfo &MRI, bool TrackLaneMasks,
181                bool IgnoreDead);
182 
183   /// Use liveness information to find dead defs not marked with a dead flag
184   /// and move them to the DeadDefs vector.
185   void detectDeadDefs(const MachineInstr &MI, const LiveIntervals &LIS);
186 
187   /// Use liveness information to find out which uses/defs are partially
188   /// undefined/dead and adjust the RegisterMaskPairs accordingly.
189   /// If \p AddFlagsMI is given then missing read-undef and dead flags will be
190   /// added to the instruction.
191   void adjustLaneLiveness(const LiveIntervals &LIS,
192                           const MachineRegisterInfo &MRI, SlotIndex Pos,
193                           MachineInstr *AddFlagsMI = nullptr);
194 };
195 
196 /// Array of PressureDiffs.
197 class PressureDiffs {
198   PressureDiff *PDiffArray = nullptr;
199   unsigned Size = 0;
200   unsigned Max = 0;
201 
202 public:
203   PressureDiffs() = default;
~PressureDiffs()204   ~PressureDiffs() { free(PDiffArray); }
205 
clear()206   void clear() { Size = 0; }
207 
208   void init(unsigned N);
209 
210   PressureDiff &operator[](unsigned Idx) {
211     assert(Idx < Size && "PressureDiff index out of bounds");
212     return PDiffArray[Idx];
213   }
214   const PressureDiff &operator[](unsigned Idx) const {
215     return const_cast<PressureDiffs*>(this)->operator[](Idx);
216   }
217 
218   /// Record pressure difference induced by the given operand list to
219   /// node with index \p Idx.
220   void addInstruction(unsigned Idx, const RegisterOperands &RegOpers,
221                       const MachineRegisterInfo &MRI);
222 };
223 
224 /// Store the effects of a change in pressure on things that MI scheduler cares
225 /// about.
226 ///
227 /// Excess records the value of the largest difference in register units beyond
228 /// the target's pressure limits across the affected pressure sets, where
229 /// largest is defined as the absolute value of the difference. Negative
230 /// ExcessUnits indicates a reduction in pressure that had already exceeded the
231 /// target's limits.
232 ///
233 /// CriticalMax records the largest increase in the tracker's max pressure that
234 /// exceeds the critical limit for some pressure set determined by the client.
235 ///
236 /// CurrentMax records the largest increase in the tracker's max pressure that
237 /// exceeds the current limit for some pressure set determined by the client.
238 struct RegPressureDelta {
239   PressureChange Excess;
240   PressureChange CriticalMax;
241   PressureChange CurrentMax;
242 
243   RegPressureDelta() = default;
244 
245   bool operator==(const RegPressureDelta &RHS) const {
246     return Excess == RHS.Excess && CriticalMax == RHS.CriticalMax
247       && CurrentMax == RHS.CurrentMax;
248   }
249   bool operator!=(const RegPressureDelta &RHS) const {
250     return !operator==(RHS);
251   }
252   void dump() const;
253 };
254 
255 /// A set of live virtual registers and physical register units.
256 ///
257 /// This is a wrapper around a SparseSet which deals with mapping register unit
258 /// and virtual register indexes to an index usable by the sparse set.
259 class LiveRegSet {
260 private:
261   struct IndexMaskPair {
262     unsigned Index;
263     LaneBitmask LaneMask;
264 
IndexMaskPairIndexMaskPair265     IndexMaskPair(unsigned Index, LaneBitmask LaneMask)
266         : Index(Index), LaneMask(LaneMask) {}
267 
getSparseSetIndexIndexMaskPair268     unsigned getSparseSetIndex() const {
269       return Index;
270     }
271   };
272 
273   using RegSet = SparseSet<IndexMaskPair>;
274   RegSet Regs;
275   unsigned NumRegUnits;
276 
getSparseIndexFromReg(Register Reg)277   unsigned getSparseIndexFromReg(Register Reg) const {
278     if (Reg.isVirtual())
279       return Register::virtReg2Index(Reg) + NumRegUnits;
280     assert(Reg < NumRegUnits);
281     return Reg;
282   }
283 
getRegFromSparseIndex(unsigned SparseIndex)284   Register getRegFromSparseIndex(unsigned SparseIndex) const {
285     if (SparseIndex >= NumRegUnits)
286       return Register::index2VirtReg(SparseIndex - NumRegUnits);
287     return Register(SparseIndex);
288   }
289 
290 public:
291   void clear();
292   void init(const MachineRegisterInfo &MRI);
293 
contains(Register Reg)294   LaneBitmask contains(Register Reg) const {
295     unsigned SparseIndex = getSparseIndexFromReg(Reg);
296     RegSet::const_iterator I = Regs.find(SparseIndex);
297     if (I == Regs.end())
298       return LaneBitmask::getNone();
299     return I->LaneMask;
300   }
301 
302   /// Mark the \p Pair.LaneMask lanes of \p Pair.Reg as live.
303   /// Returns the previously live lanes of \p Pair.Reg.
insert(RegisterMaskPair Pair)304   LaneBitmask insert(RegisterMaskPair Pair) {
305     unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
306     auto InsertRes = Regs.insert(IndexMaskPair(SparseIndex, Pair.LaneMask));
307     if (!InsertRes.second) {
308       LaneBitmask PrevMask = InsertRes.first->LaneMask;
309       InsertRes.first->LaneMask |= Pair.LaneMask;
310       return PrevMask;
311     }
312     return LaneBitmask::getNone();
313   }
314 
315   /// Clears the \p Pair.LaneMask lanes of \p Pair.Reg (mark them as dead).
316   /// Returns the previously live lanes of \p Pair.Reg.
erase(RegisterMaskPair Pair)317   LaneBitmask erase(RegisterMaskPair Pair) {
318     unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
319     RegSet::iterator I = Regs.find(SparseIndex);
320     if (I == Regs.end())
321       return LaneBitmask::getNone();
322     LaneBitmask PrevMask = I->LaneMask;
323     I->LaneMask &= ~Pair.LaneMask;
324     return PrevMask;
325   }
326 
size()327   size_t size() const {
328     return Regs.size();
329   }
330 
331   template<typename ContainerT>
appendTo(ContainerT & To)332   void appendTo(ContainerT &To) const {
333     for (const IndexMaskPair &P : Regs) {
334       Register Reg = getRegFromSparseIndex(P.Index);
335       if (P.LaneMask.any())
336         To.push_back(RegisterMaskPair(Reg, P.LaneMask));
337     }
338   }
339 };
340 
341 /// Track the current register pressure at some position in the instruction
342 /// stream, and remember the high water mark within the region traversed. This
343 /// does not automatically consider live-through ranges. The client may
344 /// independently adjust for global liveness.
345 ///
346 /// Each RegPressureTracker only works within a MachineBasicBlock. Pressure can
347 /// be tracked across a larger region by storing a RegisterPressure result at
348 /// each block boundary and explicitly adjusting pressure to account for block
349 /// live-in and live-out register sets.
350 ///
351 /// RegPressureTracker holds a reference to a RegisterPressure result that it
352 /// computes incrementally. During downward tracking, P.BottomIdx or P.BottomPos
353 /// is invalid until it reaches the end of the block or closeRegion() is
354 /// explicitly called. Similarly, P.TopIdx is invalid during upward
355 /// tracking. Changing direction has the side effect of closing region, and
356 /// traversing past TopIdx or BottomIdx reopens it.
357 class RegPressureTracker {
358   const MachineFunction *MF = nullptr;
359   const TargetRegisterInfo *TRI = nullptr;
360   const RegisterClassInfo *RCI = nullptr;
361   const MachineRegisterInfo *MRI;
362   const LiveIntervals *LIS = nullptr;
363 
364   /// We currently only allow pressure tracking within a block.
365   const MachineBasicBlock *MBB = nullptr;
366 
367   /// Track the max pressure within the region traversed so far.
368   RegisterPressure &P;
369 
370   /// Run in two modes dependending on whether constructed with IntervalPressure
371   /// or RegisterPressure. If requireIntervals is false, LIS are ignored.
372   bool RequireIntervals;
373 
374   /// True if UntiedDefs will be populated.
375   bool TrackUntiedDefs = false;
376 
377   /// True if lanemasks should be tracked.
378   bool TrackLaneMasks = false;
379 
380   /// Register pressure corresponds to liveness before this instruction
381   /// iterator. It may point to the end of the block or a DebugValue rather than
382   /// an instruction.
383   MachineBasicBlock::const_iterator CurrPos;
384 
385   /// Pressure map indexed by pressure set ID, not class ID.
386   std::vector<unsigned> CurrSetPressure;
387 
388   /// Set of live registers.
389   LiveRegSet LiveRegs;
390 
391   /// Set of vreg defs that start a live range.
392   SparseSet<Register, VirtReg2IndexFunctor> UntiedDefs;
393   /// Live-through pressure.
394   std::vector<unsigned> LiveThruPressure;
395 
396 public:
RegPressureTracker(IntervalPressure & rp)397   RegPressureTracker(IntervalPressure &rp) : P(rp), RequireIntervals(true) {}
RegPressureTracker(RegionPressure & rp)398   RegPressureTracker(RegionPressure &rp) : P(rp), RequireIntervals(false) {}
399 
400   void reset();
401 
402   void init(const MachineFunction *mf, const RegisterClassInfo *rci,
403             const LiveIntervals *lis, const MachineBasicBlock *mbb,
404             MachineBasicBlock::const_iterator pos,
405             bool TrackLaneMasks, bool TrackUntiedDefs);
406 
407   /// Force liveness of virtual registers or physical register
408   /// units. Particularly useful to initialize the livein/out state of the
409   /// tracker before the first call to advance/recede.
410   void addLiveRegs(ArrayRef<RegisterMaskPair> Regs);
411 
412   /// Get the MI position corresponding to this register pressure.
getPos()413   MachineBasicBlock::const_iterator getPos() const { return CurrPos; }
414 
415   // Reset the MI position corresponding to the register pressure. This allows
416   // schedulers to move instructions above the RegPressureTracker's
417   // CurrPos. Since the pressure is computed before CurrPos, the iterator
418   // position changes while pressure does not.
setPos(MachineBasicBlock::const_iterator Pos)419   void setPos(MachineBasicBlock::const_iterator Pos) { CurrPos = Pos; }
420 
421   /// Recede across the previous instruction.
422   void recede(SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr);
423 
424   /// Recede across the previous instruction.
425   /// This "low-level" variant assumes that recedeSkipDebugValues() was
426   /// called previously and takes precomputed RegisterOperands for the
427   /// instruction.
428   void recede(const RegisterOperands &RegOpers,
429               SmallVectorImpl<RegisterMaskPair> *LiveUses = nullptr);
430 
431   /// Recede until we find an instruction which is not a DebugValue.
432   void recedeSkipDebugValues();
433 
434   /// Advance across the current instruction.
435   void advance();
436 
437   /// Advance across the current instruction.
438   /// This is a "low-level" variant of advance() which takes precomputed
439   /// RegisterOperands of the instruction.
440   void advance(const RegisterOperands &RegOpers);
441 
442   /// Finalize the region boundaries and recored live ins and live outs.
443   void closeRegion();
444 
445   /// Initialize the LiveThru pressure set based on the untied defs found in
446   /// RPTracker.
447   void initLiveThru(const RegPressureTracker &RPTracker);
448 
449   /// Copy an existing live thru pressure result.
initLiveThru(ArrayRef<unsigned> PressureSet)450   void initLiveThru(ArrayRef<unsigned> PressureSet) {
451     LiveThruPressure.assign(PressureSet.begin(), PressureSet.end());
452   }
453 
getLiveThru()454   ArrayRef<unsigned> getLiveThru() const { return LiveThruPressure; }
455 
456   /// Get the resulting register pressure over the traversed region.
457   /// This result is complete if closeRegion() was explicitly invoked.
getPressure()458   RegisterPressure &getPressure() { return P; }
getPressure()459   const RegisterPressure &getPressure() const { return P; }
460 
461   /// Get the register set pressure at the current position, which may be less
462   /// than the pressure across the traversed region.
getRegSetPressureAtPos()463   const std::vector<unsigned> &getRegSetPressureAtPos() const {
464     return CurrSetPressure;
465   }
466 
467   bool isTopClosed() const;
468   bool isBottomClosed() const;
469 
470   void closeTop();
471   void closeBottom();
472 
473   /// Consider the pressure increase caused by traversing this instruction
474   /// bottom-up. Find the pressure set with the most change beyond its pressure
475   /// limit based on the tracker's current pressure, and record the number of
476   /// excess register units of that pressure set introduced by this instruction.
477   void getMaxUpwardPressureDelta(const MachineInstr *MI,
478                                  PressureDiff *PDiff,
479                                  RegPressureDelta &Delta,
480                                  ArrayRef<PressureChange> CriticalPSets,
481                                  ArrayRef<unsigned> MaxPressureLimit);
482 
483   void getUpwardPressureDelta(const MachineInstr *MI,
484                               /*const*/ PressureDiff &PDiff,
485                               RegPressureDelta &Delta,
486                               ArrayRef<PressureChange> CriticalPSets,
487                               ArrayRef<unsigned> MaxPressureLimit) const;
488 
489   /// Consider the pressure increase caused by traversing this instruction
490   /// top-down. Find the pressure set with the most change beyond its pressure
491   /// limit based on the tracker's current pressure, and record the number of
492   /// excess register units of that pressure set introduced by this instruction.
493   void getMaxDownwardPressureDelta(const MachineInstr *MI,
494                                    RegPressureDelta &Delta,
495                                    ArrayRef<PressureChange> CriticalPSets,
496                                    ArrayRef<unsigned> MaxPressureLimit);
497 
498   /// Find the pressure set with the most change beyond its pressure limit after
499   /// traversing this instruction either upward or downward depending on the
500   /// closed end of the current region.
getMaxPressureDelta(const MachineInstr * MI,RegPressureDelta & Delta,ArrayRef<PressureChange> CriticalPSets,ArrayRef<unsigned> MaxPressureLimit)501   void getMaxPressureDelta(const MachineInstr *MI,
502                            RegPressureDelta &Delta,
503                            ArrayRef<PressureChange> CriticalPSets,
504                            ArrayRef<unsigned> MaxPressureLimit) {
505     if (isTopClosed())
506       return getMaxDownwardPressureDelta(MI, Delta, CriticalPSets,
507                                          MaxPressureLimit);
508 
509     assert(isBottomClosed() && "Uninitialized pressure tracker");
510     return getMaxUpwardPressureDelta(MI, nullptr, Delta, CriticalPSets,
511                                      MaxPressureLimit);
512   }
513 
514   /// Get the pressure of each PSet after traversing this instruction bottom-up.
515   void getUpwardPressure(const MachineInstr *MI,
516                          std::vector<unsigned> &PressureResult,
517                          std::vector<unsigned> &MaxPressureResult);
518 
519   /// Get the pressure of each PSet after traversing this instruction top-down.
520   void getDownwardPressure(const MachineInstr *MI,
521                            std::vector<unsigned> &PressureResult,
522                            std::vector<unsigned> &MaxPressureResult);
523 
getPressureAfterInst(const MachineInstr * MI,std::vector<unsigned> & PressureResult,std::vector<unsigned> & MaxPressureResult)524   void getPressureAfterInst(const MachineInstr *MI,
525                             std::vector<unsigned> &PressureResult,
526                             std::vector<unsigned> &MaxPressureResult) {
527     if (isTopClosed())
528       return getUpwardPressure(MI, PressureResult, MaxPressureResult);
529 
530     assert(isBottomClosed() && "Uninitialized pressure tracker");
531     return getDownwardPressure(MI, PressureResult, MaxPressureResult);
532   }
533 
hasUntiedDef(Register VirtReg)534   bool hasUntiedDef(Register VirtReg) const {
535     return UntiedDefs.count(VirtReg);
536   }
537 
538   void dump() const;
539 
540   void increaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
541                            LaneBitmask NewMask);
542   void decreaseRegPressure(Register RegUnit, LaneBitmask PreviousMask,
543                            LaneBitmask NewMask);
544 
545 protected:
546   /// Add Reg to the live out set and increase max pressure.
547   void discoverLiveOut(RegisterMaskPair Pair);
548   /// Add Reg to the live in set and increase max pressure.
549   void discoverLiveIn(RegisterMaskPair Pair);
550 
551   /// Get the SlotIndex for the first nondebug instruction including or
552   /// after the current position.
553   SlotIndex getCurrSlot() const;
554 
555   void bumpDeadDefs(ArrayRef<RegisterMaskPair> DeadDefs);
556 
557   void bumpUpwardPressure(const MachineInstr *MI);
558   void bumpDownwardPressure(const MachineInstr *MI);
559 
560   void discoverLiveInOrOut(RegisterMaskPair Pair,
561                            SmallVectorImpl<RegisterMaskPair> &LiveInOrOut);
562 
563   LaneBitmask getLastUsedLanes(Register RegUnit, SlotIndex Pos) const;
564   LaneBitmask getLiveLanesAt(Register RegUnit, SlotIndex Pos) const;
565   LaneBitmask getLiveThroughAt(Register RegUnit, SlotIndex Pos) const;
566 };
567 
568 void dumpRegSetPressure(ArrayRef<unsigned> SetPressure,
569                         const TargetRegisterInfo *TRI);
570 
571 } // end namespace llvm
572 
573 #endif // LLVM_CODEGEN_REGISTERPRESSURE_H
574