1080dd10fSScott Constable //===- RDFRegisters.cpp ---------------------------------------------------===//
2080dd10fSScott Constable //
3080dd10fSScott Constable // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4080dd10fSScott Constable // See https://llvm.org/LICENSE.txt for license information.
5080dd10fSScott Constable // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6080dd10fSScott Constable //
7080dd10fSScott Constable //===----------------------------------------------------------------------===//
8080dd10fSScott Constable
9080dd10fSScott Constable #include "llvm/ADT/BitVector.h"
10080dd10fSScott Constable #include "llvm/CodeGen/MachineFunction.h"
11080dd10fSScott Constable #include "llvm/CodeGen/MachineInstr.h"
12080dd10fSScott Constable #include "llvm/CodeGen/MachineOperand.h"
13080dd10fSScott Constable #include "llvm/CodeGen/RDFRegisters.h"
14080dd10fSScott Constable #include "llvm/CodeGen/TargetRegisterInfo.h"
15080dd10fSScott Constable #include "llvm/MC/LaneBitmask.h"
16080dd10fSScott Constable #include "llvm/MC/MCRegisterInfo.h"
17080dd10fSScott Constable #include "llvm/Support/ErrorHandling.h"
18080dd10fSScott Constable #include "llvm/Support/raw_ostream.h"
19080dd10fSScott Constable #include <cassert>
20080dd10fSScott Constable #include <cstdint>
21080dd10fSScott Constable #include <set>
22080dd10fSScott Constable #include <utility>
23080dd10fSScott Constable
24080dd10fSScott Constable using namespace llvm;
25080dd10fSScott Constable using namespace rdf;
26080dd10fSScott Constable
PhysicalRegisterInfo(const TargetRegisterInfo & tri,const MachineFunction & mf)27080dd10fSScott Constable PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
28080dd10fSScott Constable const MachineFunction &mf)
29080dd10fSScott Constable : TRI(tri) {
30080dd10fSScott Constable RegInfos.resize(TRI.getNumRegs());
31080dd10fSScott Constable
32080dd10fSScott Constable BitVector BadRC(TRI.getNumRegs());
33080dd10fSScott Constable for (const TargetRegisterClass *RC : TRI.regclasses()) {
34080dd10fSScott Constable for (MCPhysReg R : *RC) {
35080dd10fSScott Constable RegInfo &RI = RegInfos[R];
36080dd10fSScott Constable if (RI.RegClass != nullptr && !BadRC[R]) {
37080dd10fSScott Constable if (RC->LaneMask != RI.RegClass->LaneMask) {
38080dd10fSScott Constable BadRC.set(R);
39080dd10fSScott Constable RI.RegClass = nullptr;
40080dd10fSScott Constable }
41080dd10fSScott Constable } else
42080dd10fSScott Constable RI.RegClass = RC;
43080dd10fSScott Constable }
44080dd10fSScott Constable }
45080dd10fSScott Constable
46080dd10fSScott Constable UnitInfos.resize(TRI.getNumRegUnits());
47080dd10fSScott Constable
48080dd10fSScott Constable for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
49080dd10fSScott Constable if (UnitInfos[U].Reg != 0)
50080dd10fSScott Constable continue;
51080dd10fSScott Constable MCRegUnitRootIterator R(U, &TRI);
52080dd10fSScott Constable assert(R.isValid());
53080dd10fSScott Constable RegisterId F = *R;
54080dd10fSScott Constable ++R;
55080dd10fSScott Constable if (R.isValid()) {
56080dd10fSScott Constable UnitInfos[U].Mask = LaneBitmask::getAll();
57080dd10fSScott Constable UnitInfos[U].Reg = F;
58080dd10fSScott Constable } else {
59080dd10fSScott Constable for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
60080dd10fSScott Constable std::pair<uint32_t,LaneBitmask> P = *I;
61080dd10fSScott Constable UnitInfo &UI = UnitInfos[P.first];
62080dd10fSScott Constable UI.Reg = F;
63080dd10fSScott Constable if (P.second.any()) {
64080dd10fSScott Constable UI.Mask = P.second;
65080dd10fSScott Constable } else {
66080dd10fSScott Constable if (const TargetRegisterClass *RC = RegInfos[F].RegClass)
67080dd10fSScott Constable UI.Mask = RC->LaneMask;
68080dd10fSScott Constable else
69080dd10fSScott Constable UI.Mask = LaneBitmask::getAll();
70080dd10fSScott Constable }
71080dd10fSScott Constable }
72080dd10fSScott Constable }
73080dd10fSScott Constable }
74080dd10fSScott Constable
75080dd10fSScott Constable for (const uint32_t *RM : TRI.getRegMasks())
76080dd10fSScott Constable RegMasks.insert(RM);
77080dd10fSScott Constable for (const MachineBasicBlock &B : mf)
78080dd10fSScott Constable for (const MachineInstr &In : B)
79080dd10fSScott Constable for (const MachineOperand &Op : In.operands())
80080dd10fSScott Constable if (Op.isRegMask())
81080dd10fSScott Constable RegMasks.insert(Op.getRegMask());
82080dd10fSScott Constable
83080dd10fSScott Constable MaskInfos.resize(RegMasks.size()+1);
84080dd10fSScott Constable for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
85080dd10fSScott Constable BitVector PU(TRI.getNumRegUnits());
86080dd10fSScott Constable const uint32_t *MB = RegMasks.get(M);
87*e24537d4SMircea Trofin for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
88*e24537d4SMircea Trofin if (!(MB[I / 32] & (1u << (I % 32))))
89080dd10fSScott Constable continue;
90*e24537d4SMircea Trofin for (MCRegUnitIterator U(MCRegister::from(I), &TRI); U.isValid(); ++U)
91080dd10fSScott Constable PU.set(*U);
92080dd10fSScott Constable }
93080dd10fSScott Constable MaskInfos[M].Units = PU.flip();
94080dd10fSScott Constable }
95f0f467aeSKrzysztof Parzyszek
96f0f467aeSKrzysztof Parzyszek AliasInfos.resize(TRI.getNumRegUnits());
97f0f467aeSKrzysztof Parzyszek for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
98f0f467aeSKrzysztof Parzyszek BitVector AS(TRI.getNumRegs());
99f0f467aeSKrzysztof Parzyszek for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
100f0f467aeSKrzysztof Parzyszek for (MCSuperRegIterator S(*R, &TRI, true); S.isValid(); ++S)
101f0f467aeSKrzysztof Parzyszek AS.set(*S);
102f0f467aeSKrzysztof Parzyszek AliasInfos[U].Regs = AS;
103f0f467aeSKrzysztof Parzyszek }
104080dd10fSScott Constable }
105080dd10fSScott Constable
getAliasSet(RegisterId Reg) const106080dd10fSScott Constable std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
107080dd10fSScott Constable // Do not include RR in the alias set.
108080dd10fSScott Constable std::set<RegisterId> AS;
109080dd10fSScott Constable assert(isRegMaskId(Reg) || Register::isPhysicalRegister(Reg));
110080dd10fSScott Constable if (isRegMaskId(Reg)) {
111080dd10fSScott Constable // XXX SLOW
112080dd10fSScott Constable const uint32_t *MB = getRegMaskBits(Reg);
113080dd10fSScott Constable for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
114080dd10fSScott Constable if (MB[i/32] & (1u << (i%32)))
115080dd10fSScott Constable continue;
116080dd10fSScott Constable AS.insert(i);
117080dd10fSScott Constable }
118080dd10fSScott Constable for (const uint32_t *RM : RegMasks) {
119080dd10fSScott Constable RegisterId MI = getRegMaskId(RM);
120080dd10fSScott Constable if (MI != Reg && aliasMM(RegisterRef(Reg), RegisterRef(MI)))
121080dd10fSScott Constable AS.insert(MI);
122080dd10fSScott Constable }
123080dd10fSScott Constable return AS;
124080dd10fSScott Constable }
125080dd10fSScott Constable
126080dd10fSScott Constable for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
127080dd10fSScott Constable AS.insert(*AI);
128080dd10fSScott Constable for (const uint32_t *RM : RegMasks) {
129080dd10fSScott Constable RegisterId MI = getRegMaskId(RM);
130080dd10fSScott Constable if (aliasRM(RegisterRef(Reg), RegisterRef(MI)))
131080dd10fSScott Constable AS.insert(MI);
132080dd10fSScott Constable }
133080dd10fSScott Constable return AS;
134080dd10fSScott Constable }
135080dd10fSScott Constable
aliasRR(RegisterRef RA,RegisterRef RB) const136080dd10fSScott Constable bool PhysicalRegisterInfo::aliasRR(RegisterRef RA, RegisterRef RB) const {
137080dd10fSScott Constable assert(Register::isPhysicalRegister(RA.Reg));
138080dd10fSScott Constable assert(Register::isPhysicalRegister(RB.Reg));
139080dd10fSScott Constable
140080dd10fSScott Constable MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
141080dd10fSScott Constable MCRegUnitMaskIterator UMB(RB.Reg, &TRI);
142080dd10fSScott Constable // Reg units are returned in the numerical order.
143080dd10fSScott Constable while (UMA.isValid() && UMB.isValid()) {
144080dd10fSScott Constable // Skip units that are masked off in RA.
145080dd10fSScott Constable std::pair<RegisterId,LaneBitmask> PA = *UMA;
146080dd10fSScott Constable if (PA.second.any() && (PA.second & RA.Mask).none()) {
147080dd10fSScott Constable ++UMA;
148080dd10fSScott Constable continue;
149080dd10fSScott Constable }
150080dd10fSScott Constable // Skip units that are masked off in RB.
151080dd10fSScott Constable std::pair<RegisterId,LaneBitmask> PB = *UMB;
152080dd10fSScott Constable if (PB.second.any() && (PB.second & RB.Mask).none()) {
153080dd10fSScott Constable ++UMB;
154080dd10fSScott Constable continue;
155080dd10fSScott Constable }
156080dd10fSScott Constable
157080dd10fSScott Constable if (PA.first == PB.first)
158080dd10fSScott Constable return true;
159080dd10fSScott Constable if (PA.first < PB.first)
160080dd10fSScott Constable ++UMA;
161080dd10fSScott Constable else if (PB.first < PA.first)
162080dd10fSScott Constable ++UMB;
163080dd10fSScott Constable }
164080dd10fSScott Constable return false;
165080dd10fSScott Constable }
166080dd10fSScott Constable
aliasRM(RegisterRef RR,RegisterRef RM) const167080dd10fSScott Constable bool PhysicalRegisterInfo::aliasRM(RegisterRef RR, RegisterRef RM) const {
168080dd10fSScott Constable assert(Register::isPhysicalRegister(RR.Reg) && isRegMaskId(RM.Reg));
169080dd10fSScott Constable const uint32_t *MB = getRegMaskBits(RM.Reg);
170080dd10fSScott Constable bool Preserved = MB[RR.Reg/32] & (1u << (RR.Reg%32));
171080dd10fSScott Constable // If the lane mask information is "full", e.g. when the given lane mask
172080dd10fSScott Constable // is a superset of the lane mask from the register class, check the regmask
173080dd10fSScott Constable // bit directly.
174080dd10fSScott Constable if (RR.Mask == LaneBitmask::getAll())
175080dd10fSScott Constable return !Preserved;
176080dd10fSScott Constable const TargetRegisterClass *RC = RegInfos[RR.Reg].RegClass;
177080dd10fSScott Constable if (RC != nullptr && (RR.Mask & RC->LaneMask) == RC->LaneMask)
178080dd10fSScott Constable return !Preserved;
179080dd10fSScott Constable
180080dd10fSScott Constable // Otherwise, check all subregisters whose lane mask overlaps the given
181080dd10fSScott Constable // mask. For each such register, if it is preserved by the regmask, then
182080dd10fSScott Constable // clear the corresponding bits in the given mask. If at the end, all
183080dd10fSScott Constable // bits have been cleared, the register does not alias the regmask (i.e.
184080dd10fSScott Constable // is it preserved by it).
185080dd10fSScott Constable LaneBitmask M = RR.Mask;
186080dd10fSScott Constable for (MCSubRegIndexIterator SI(RR.Reg, &TRI); SI.isValid(); ++SI) {
187080dd10fSScott Constable LaneBitmask SM = TRI.getSubRegIndexLaneMask(SI.getSubRegIndex());
188080dd10fSScott Constable if ((SM & RR.Mask).none())
189080dd10fSScott Constable continue;
190080dd10fSScott Constable unsigned SR = SI.getSubReg();
191080dd10fSScott Constable if (!(MB[SR/32] & (1u << (SR%32))))
192080dd10fSScott Constable continue;
193080dd10fSScott Constable // The subregister SR is preserved.
194080dd10fSScott Constable M &= ~SM;
195080dd10fSScott Constable if (M.none())
196080dd10fSScott Constable return false;
197080dd10fSScott Constable }
198080dd10fSScott Constable
199080dd10fSScott Constable return true;
200080dd10fSScott Constable }
201080dd10fSScott Constable
aliasMM(RegisterRef RM,RegisterRef RN) const202080dd10fSScott Constable bool PhysicalRegisterInfo::aliasMM(RegisterRef RM, RegisterRef RN) const {
203080dd10fSScott Constable assert(isRegMaskId(RM.Reg) && isRegMaskId(RN.Reg));
204080dd10fSScott Constable unsigned NumRegs = TRI.getNumRegs();
205080dd10fSScott Constable const uint32_t *BM = getRegMaskBits(RM.Reg);
206080dd10fSScott Constable const uint32_t *BN = getRegMaskBits(RN.Reg);
207080dd10fSScott Constable
208080dd10fSScott Constable for (unsigned w = 0, nw = NumRegs/32; w != nw; ++w) {
209080dd10fSScott Constable // Intersect the negations of both words. Disregard reg=0,
210080dd10fSScott Constable // i.e. 0th bit in the 0th word.
211080dd10fSScott Constable uint32_t C = ~BM[w] & ~BN[w];
212080dd10fSScott Constable if (w == 0)
213080dd10fSScott Constable C &= ~1;
214080dd10fSScott Constable if (C)
215080dd10fSScott Constable return true;
216080dd10fSScott Constable }
217080dd10fSScott Constable
218080dd10fSScott Constable // Check the remaining registers in the last word.
219080dd10fSScott Constable unsigned TailRegs = NumRegs % 32;
220080dd10fSScott Constable if (TailRegs == 0)
221080dd10fSScott Constable return false;
222080dd10fSScott Constable unsigned TW = NumRegs / 32;
223080dd10fSScott Constable uint32_t TailMask = (1u << TailRegs) - 1;
224080dd10fSScott Constable if (~BM[TW] & ~BN[TW] & TailMask)
225080dd10fSScott Constable return true;
226080dd10fSScott Constable
227080dd10fSScott Constable return false;
228080dd10fSScott Constable }
229080dd10fSScott Constable
mapTo(RegisterRef RR,unsigned R) const230080dd10fSScott Constable RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
231080dd10fSScott Constable if (RR.Reg == R)
232080dd10fSScott Constable return RR;
233080dd10fSScott Constable if (unsigned Idx = TRI.getSubRegIndex(R, RR.Reg))
234080dd10fSScott Constable return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
235080dd10fSScott Constable if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) {
236080dd10fSScott Constable const RegInfo &RI = RegInfos[R];
237080dd10fSScott Constable LaneBitmask RCM = RI.RegClass ? RI.RegClass->LaneMask
238080dd10fSScott Constable : LaneBitmask::getAll();
239080dd10fSScott Constable LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
240080dd10fSScott Constable return RegisterRef(R, M & RCM);
241080dd10fSScott Constable }
242080dd10fSScott Constable llvm_unreachable("Invalid arguments: unrelated registers?");
243080dd10fSScott Constable }
244080dd10fSScott Constable
hasAliasOf(RegisterRef RR) const245080dd10fSScott Constable bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
246080dd10fSScott Constable if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
247080dd10fSScott Constable return Units.anyCommon(PRI.getMaskUnits(RR.Reg));
248080dd10fSScott Constable
249080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
250080dd10fSScott Constable std::pair<uint32_t,LaneBitmask> P = *U;
251080dd10fSScott Constable if (P.second.none() || (P.second & RR.Mask).any())
252080dd10fSScott Constable if (Units.test(P.first))
253080dd10fSScott Constable return true;
254080dd10fSScott Constable }
255080dd10fSScott Constable return false;
256080dd10fSScott Constable }
257080dd10fSScott Constable
hasCoverOf(RegisterRef RR) const258080dd10fSScott Constable bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
259080dd10fSScott Constable if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) {
260080dd10fSScott Constable BitVector T(PRI.getMaskUnits(RR.Reg));
261080dd10fSScott Constable return T.reset(Units).none();
262080dd10fSScott Constable }
263080dd10fSScott Constable
264080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
265080dd10fSScott Constable std::pair<uint32_t,LaneBitmask> P = *U;
266080dd10fSScott Constable if (P.second.none() || (P.second & RR.Mask).any())
267080dd10fSScott Constable if (!Units.test(P.first))
268080dd10fSScott Constable return false;
269080dd10fSScott Constable }
270080dd10fSScott Constable return true;
271080dd10fSScott Constable }
272080dd10fSScott Constable
insert(RegisterRef RR)273080dd10fSScott Constable RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
274080dd10fSScott Constable if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) {
275080dd10fSScott Constable Units |= PRI.getMaskUnits(RR.Reg);
276080dd10fSScott Constable return *this;
277080dd10fSScott Constable }
278080dd10fSScott Constable
279080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
280080dd10fSScott Constable std::pair<uint32_t,LaneBitmask> P = *U;
281080dd10fSScott Constable if (P.second.none() || (P.second & RR.Mask).any())
282080dd10fSScott Constable Units.set(P.first);
283080dd10fSScott Constable }
284080dd10fSScott Constable return *this;
285080dd10fSScott Constable }
286080dd10fSScott Constable
insert(const RegisterAggr & RG)287080dd10fSScott Constable RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
288080dd10fSScott Constable Units |= RG.Units;
289080dd10fSScott Constable return *this;
290080dd10fSScott Constable }
291080dd10fSScott Constable
intersect(RegisterRef RR)292080dd10fSScott Constable RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
293080dd10fSScott Constable return intersect(RegisterAggr(PRI).insert(RR));
294080dd10fSScott Constable }
295080dd10fSScott Constable
intersect(const RegisterAggr & RG)296080dd10fSScott Constable RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
297080dd10fSScott Constable Units &= RG.Units;
298080dd10fSScott Constable return *this;
299080dd10fSScott Constable }
300080dd10fSScott Constable
clear(RegisterRef RR)301080dd10fSScott Constable RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
302080dd10fSScott Constable return clear(RegisterAggr(PRI).insert(RR));
303080dd10fSScott Constable }
304080dd10fSScott Constable
clear(const RegisterAggr & RG)305080dd10fSScott Constable RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
306080dd10fSScott Constable Units.reset(RG.Units);
307080dd10fSScott Constable return *this;
308080dd10fSScott Constable }
309080dd10fSScott Constable
intersectWith(RegisterRef RR) const310080dd10fSScott Constable RegisterRef RegisterAggr::intersectWith(RegisterRef RR) const {
311080dd10fSScott Constable RegisterAggr T(PRI);
312080dd10fSScott Constable T.insert(RR).intersect(*this);
313080dd10fSScott Constable if (T.empty())
314080dd10fSScott Constable return RegisterRef();
315080dd10fSScott Constable RegisterRef NR = T.makeRegRef();
316080dd10fSScott Constable assert(NR);
317080dd10fSScott Constable return NR;
318080dd10fSScott Constable }
319080dd10fSScott Constable
clearIn(RegisterRef RR) const320080dd10fSScott Constable RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
321080dd10fSScott Constable return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
322080dd10fSScott Constable }
323080dd10fSScott Constable
makeRegRef() const324080dd10fSScott Constable RegisterRef RegisterAggr::makeRegRef() const {
325080dd10fSScott Constable int U = Units.find_first();
326080dd10fSScott Constable if (U < 0)
327080dd10fSScott Constable return RegisterRef();
328080dd10fSScott Constable
329080dd10fSScott Constable // Find the set of all registers that are aliased to all the units
330080dd10fSScott Constable // in this aggregate.
331080dd10fSScott Constable
332080dd10fSScott Constable // Get all the registers aliased to the first unit in the bit vector.
333f0f467aeSKrzysztof Parzyszek BitVector Regs = PRI.getUnitAliases(U);
334080dd10fSScott Constable U = Units.find_next(U);
335080dd10fSScott Constable
336080dd10fSScott Constable // For each other unit, intersect it with the set of all registers
337080dd10fSScott Constable // aliased that unit.
338080dd10fSScott Constable while (U >= 0) {
339f0f467aeSKrzysztof Parzyszek Regs &= PRI.getUnitAliases(U);
340080dd10fSScott Constable U = Units.find_next(U);
341080dd10fSScott Constable }
342080dd10fSScott Constable
343080dd10fSScott Constable // If there is at least one register remaining, pick the first one,
344080dd10fSScott Constable // and consolidate the masks of all of its units contained in this
345080dd10fSScott Constable // aggregate.
346080dd10fSScott Constable
347080dd10fSScott Constable int F = Regs.find_first();
348080dd10fSScott Constable if (F <= 0)
349080dd10fSScott Constable return RegisterRef();
350080dd10fSScott Constable
351080dd10fSScott Constable LaneBitmask M;
352080dd10fSScott Constable for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
353080dd10fSScott Constable std::pair<uint32_t,LaneBitmask> P = *I;
354080dd10fSScott Constable if (Units.test(P.first))
355080dd10fSScott Constable M |= P.second.none() ? LaneBitmask::getAll() : P.second;
356080dd10fSScott Constable }
357080dd10fSScott Constable return RegisterRef(F, M);
358080dd10fSScott Constable }
359080dd10fSScott Constable
print(raw_ostream & OS) const360080dd10fSScott Constable void RegisterAggr::print(raw_ostream &OS) const {
361080dd10fSScott Constable OS << '{';
362080dd10fSScott Constable for (int U = Units.find_first(); U >= 0; U = Units.find_next(U))
363080dd10fSScott Constable OS << ' ' << printRegUnit(U, &PRI.getTRI());
364080dd10fSScott Constable OS << " }";
365080dd10fSScott Constable }
366080dd10fSScott Constable
rr_iterator(const RegisterAggr & RG,bool End)367080dd10fSScott Constable RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG,
368080dd10fSScott Constable bool End)
369080dd10fSScott Constable : Owner(&RG) {
370080dd10fSScott Constable for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
371080dd10fSScott Constable RegisterRef R = RG.PRI.getRefForUnit(U);
372080dd10fSScott Constable Masks[R.Reg] |= R.Mask;
373080dd10fSScott Constable }
374080dd10fSScott Constable Pos = End ? Masks.end() : Masks.begin();
375080dd10fSScott Constable Index = End ? Masks.size() : 0;
376080dd10fSScott Constable }
37706d42573SKrzysztof Parzyszek
operator <<(raw_ostream & OS,const RegisterAggr & A)37806d42573SKrzysztof Parzyszek raw_ostream &rdf::operator<<(raw_ostream &OS, const RegisterAggr &A) {
37906d42573SKrzysztof Parzyszek A.print(OS);
38006d42573SKrzysztof Parzyszek return OS;
38106d42573SKrzysztof Parzyszek }
382