}
}
- auto HasPartialOverlaps = [this] (uint32_t Reg) -> bool {
- for (MCRegAliasIterator A(Reg, &TRI, false); A.isValid(); ++A)
- if (!TRI.isSubRegister(Reg, *A) && !TRI.isSubRegister(*A, Reg))
- return true;
- return false;
- };
-
- for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R)
- RegInfos[R].Partial = HasPartialOverlaps(R);
+ UnitInfos.resize(TRI.getNumRegUnits());
- for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R) {
- MCPhysReg SuperR = R;
- for (MCSuperRegIterator S(R, &TRI, false); S.isValid(); ++S)
- if (!RegInfos[*S].Partial)
- SuperR = *S;
- RegInfos[R].MaxSuper = SuperR;
+ for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
+ if (UnitInfos[U].Reg != 0)
+ continue;
+ MCRegUnitRootIterator R(U, &TRI);
+ assert(R.isValid());
+ RegisterId F = *R;
+ ++R;
+ if (R.isValid()) {
+ UnitInfos[U].Mask = LaneBitmask::getAll();
+ UnitInfos[U].Reg = F;
+ } else {
+ for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
+ std::pair<uint32_t,LaneBitmask> P = *I;
+ UnitInfo &UI = UnitInfos[P.first];
+ UI.Reg = F;
+ if (P.second.any()) {
+ UI.Mask = P.second;
+ } else {
+ if (const TargetRegisterClass *RC = RegInfos[F].RegClass)
+ UI.Mask = RC->LaneMask;
+ else
+ UI.Mask = LaneBitmask::getAll();
+ }
+ }
+ }
}
for (const uint32_t *RM : TRI.getRegMasks())
}
RegisterRef PhysicalRegisterInfo::normalize(RegisterRef RR) const {
- if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
- return RR;
- RegisterId SuperReg = RegInfos[RR.Reg].MaxSuper;
- if (RR.Reg == SuperReg)
- return RR;
-
- const TargetRegisterClass *RC = RegInfos[RR.Reg].RegClass;
- LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x00000001);
- LaneBitmask Common = RR.Mask & RCMask;
-
-// Ex: IP/EIP/RIP
-// assert(RC != nullptr || RR.Reg == SuperReg);
- uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
- LaneBitmask SuperMask = TRI.composeSubRegIndexLaneMask(Sub, Common);
- assert(RR.Mask.none() || SuperMask.any());
- return RegisterRef(SuperReg, SuperMask);
+ return RR;
}
std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
return false;
}
- RegisterRef NR = PRI.normalize(RR);
- auto F = Masks.find(NR.Reg);
- if (F != Masks.end()) {
- if ((F->second & NR.Mask).any())
- return true;
- }
- if (CheckUnits || PRI.hasPartialOverlaps(NR.Reg)) {
- for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
- std::pair<RegisterId,LaneBitmask> P = *U;
- if (P.second.none() || (P.second & RR.Mask).any())
- if (ExpUnits.test(P.first))
- return true;
- }
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<uint32_t,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).any())
+ if (Units.test(P.first))
+ return true;
}
return false;
}
return true;
}
- // Always have a cover for empty lane mask.
- RegisterRef NR = PRI.normalize(RR);
- if (NR.Mask.none())
- return true;
- auto F = Masks.find(NR.Reg);
- if (F != Masks.end()) {
- if ((NR.Mask & F->second) == NR.Mask)
- return true;
- }
- if (CheckUnits || PRI.hasPartialOverlaps(NR.Reg)) {
- for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
- std::pair<RegisterId,LaneBitmask> P = *U;
- if (P.second.none() || (P.second & RR.Mask).any())
- if (!ExpUnits.test(P.first))
- return false;
- }
- return true;
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<uint32_t,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).any())
+ if (!Units.test(P.first))
+ return false;
}
- return false;
+ return true;
}
RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
return *this;
}
- RegisterRef NR = PRI.normalize(RR);
- auto F = Masks.find(NR.Reg);
- if (F == Masks.end())
- Masks.insert({NR.Reg, NR.Mask});
- else
- F->second |= NR.Mask;
-
- // If the register has any partial overlaps, the mask will not be sufficient
- // to accurately represent aliasing/covering information. Add all units to
- // the bit vector.
- if (PRI.hasPartialOverlaps(NR.Reg)) {
- for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
- std::pair<RegisterId,LaneBitmask> P = *U;
- if (P.second.none() || (P.second & RR.Mask).none())
- continue;
- ExpUnits.set(P.first);
- CheckUnits = true;
- }
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<uint32_t,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).any())
+ Units.set(P.first);
}
return *this;
}
RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
- for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
- insert(RegisterRef(P.first, P.second));
+ Units |= RG.Units;
return *this;
}
RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
- if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
- return intersect(RegisterAggr(PRI).insert(RR));
-
- RegisterRef NR = PRI.normalize(RR);
- auto F = Masks.find(NR.Reg);
- LaneBitmask M;
- if (F != Masks.end())
- M = NR.Mask & F->second;
- Masks.clear();
- ExpUnits.clear();
- CheckUnits = false;
- if (M.any())
- insert(RegisterRef(NR.Reg, M));
- return *this;
+ return intersect(RegisterAggr(PRI).insert(RR));
}
RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
- for (auto I = Masks.begin(); I != Masks.end(); ) {
- auto F = RG.Masks.find(I->first);
- if (F == RG.Masks.end()) {
- I = Masks.erase(I);
- } else {
- I->second &= F->second;
- ++I;
- }
- }
- if (CheckUnits && RG.CheckUnits) {
- ExpUnits &= RG.ExpUnits;
- if (ExpUnits.empty())
- CheckUnits = false;
- } else {
- ExpUnits.clear();
- CheckUnits = false;
- }
+ Units &= RG.Units;
return *this;
}
RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
- if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) {
- // XXX SLOW
- const uint32_t *MB = PRI.getRegMaskBits(RR.Reg);
- for (unsigned i = 1, e = PRI.getTRI().getNumRegs(); i != e; ++i) {
- if (MB[i/32] & (1u << (i%32)))
- continue;
- clear(RegisterRef(i, LaneBitmask::getAll()));
- }
- return *this;
- }
-
- RegisterRef NR = PRI.normalize(RR);
- auto F = Masks.find(NR.Reg);
- if (F == Masks.end())
- return *this;
- LaneBitmask NewM = F->second & ~NR.Mask;
- if (NewM.none())
- Masks.erase(F);
- else
- F->second = NewM;
- return *this;
+ return clear(RegisterAggr(PRI).insert(RR));
}
RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
- for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
- clear(RegisterRef(P.first, P.second));
+ Units.reset(RG.Units);
return *this;
}
T.insert(RR).intersect(*this);
if (T.empty())
return RegisterRef();
- return RegisterRef(T.begin()->first, T.begin()->second);
+ RegisterRef NR = T.makeRegRef();
+ assert(NR);
+ return NR;
}
RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
- RegisterAggr T(PRI);
- T.insert(RR).clear(*this);
- if (T.empty())
+ return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
+}
+
+RegisterRef RegisterAggr::makeRegRef() const {
+ int U = Units.find_first();
+ if (U < 0)
return RegisterRef();
- return RegisterRef(T.begin()->first, T.begin()->second);
+
+ auto AliasedRegs = [this] (uint32_t Unit, BitVector &Regs) {
+ for (MCRegUnitRootIterator R(Unit, &PRI.getTRI()); R.isValid(); ++R)
+ for (MCSuperRegIterator S(*R, &PRI.getTRI(), true); S.isValid(); ++S)
+ Regs.set(*S);
+ };
+
+ // Find the set of all registers that are aliased to all the units
+ // in this aggregate.
+
+ // Get all the registers aliased to the first unit in the bit vector.
+ BitVector Regs(PRI.getTRI().getNumRegs());
+ AliasedRegs(U, Regs);
+ U = Units.find_next(U);
+
+ // For each other unit, intersect it with the set of all registers
+ // aliased that unit.
+ while (U >= 0) {
+ BitVector AR(PRI.getTRI().getNumRegs());
+ AliasedRegs(U, AR);
+ Regs &= AR;
+ U = Units.find_next(U);
+ }
+
+ // If there is at least one register remaining, pick the first one,
+ // and consolidate the masks of all of its units contained in this
+ // aggregate.
+
+ int F = Regs.find_first();
+ if (F <= 0)
+ return RegisterRef();
+
+ LaneBitmask M;
+ for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
+ std::pair<uint32_t,LaneBitmask> P = *I;
+ if (Units.test(P.first))
+ M |= P.second.none() ? LaneBitmask::getAll() : P.second;
+ }
+ return RegisterRef(F, M);
}
void RegisterAggr::print(raw_ostream &OS) const {
OS << '{';
- for (auto I : Masks)
- OS << ' ' << PrintReg(I.first, &PRI.getTRI())
- << PrintLaneMaskOpt(I.second);
+ for (int U = Units.find_first(); U >= 0; U = Units.find_next(U))
+ OS << ' ' << PrintRegUnit(U, &PRI.getTRI());
OS << " }";
}
+RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG,
+ bool End)
+ : Owner(&RG) {
+ for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
+ RegisterRef R = RG.PRI.getRefForUnit(U);
+ Masks[R.Reg] |= R.Mask;
+ }
+ Pos = End ? Masks.end() : Masks.begin();
+ Index = End ? Masks.size() : 0;
+}
+
return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
}
std::set<RegisterId> getAliasSet(RegisterId Reg) const;
- bool hasPartialOverlaps(RegisterId Reg) const {
- return RegInfos[Reg].Partial;
+
+ RegisterRef getRefForUnit(uint32_t U) const {
+ return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
}
const TargetRegisterInfo &getTRI() const { return TRI; }
private:
struct RegInfo {
- unsigned MaxSuper = 0;
const TargetRegisterClass *RegClass = nullptr;
- bool Partial = false;
+ };
+ struct UnitInfo {
+ RegisterId Reg = 0;
+ LaneBitmask Mask;
};
const TargetRegisterInfo &TRI;
std::vector<RegInfo> RegInfos;
+ std::vector<UnitInfo> UnitInfos;
IndexedSet<const uint32_t*> RegMasks;
bool aliasRR(RegisterRef RA, RegisterRef RB) const;
struct RegisterAggr {
RegisterAggr(const PhysicalRegisterInfo &pri)
- : ExpUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
+ : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
RegisterAggr(const RegisterAggr &RG) = default;
- bool empty() const { return Masks.empty(); }
+ bool empty() const { return Units.empty(); }
bool hasAliasOf(RegisterRef RR) const;
bool hasCoverOf(RegisterRef RR) const;
static bool isCoverOf(RegisterRef RA, RegisterRef RB,
RegisterRef intersectWith(RegisterRef RR) const;
RegisterRef clearIn(RegisterRef RR) const;
+ RegisterRef makeRegRef() const;
void print(raw_ostream &OS) const;
- private:
- typedef std::unordered_map<RegisterId, LaneBitmask> MapType;
+ struct rr_iterator {
+ typedef std::map<RegisterId,LaneBitmask> MapType;
+ private:
+ MapType Masks;
+ MapType::iterator Pos;
+ unsigned Index;
+ const RegisterAggr *Owner;
+ public:
+ rr_iterator(const RegisterAggr &RG, bool End);
+ RegisterRef operator*() const {
+ return RegisterRef(Pos->first, Pos->second);
+ }
+ rr_iterator &operator++() {
+ ++Pos;
+ ++Index;
+ return *this;
+ }
+ bool operator==(const rr_iterator &I) const {
+ assert(Owner == I.Owner);
+ return Index == I.Index;
+ }
+ bool operator!=(const rr_iterator &I) const {
+ return !(*this == I);
+ }
+ };
- public:
- typedef MapType::const_iterator iterator;
- iterator begin() const { return Masks.begin(); }
- iterator end() const { return Masks.end(); }
+ rr_iterator rr_begin() const {
+ return rr_iterator(*this, false);
+ }
+ rr_iterator rr_end() const {
+ return rr_iterator(*this, true);
+ }
private:
- MapType Masks;
- BitVector ExpUnits; // Register units for explicit checks.
- bool CheckUnits = false;
+ BitVector Units;
const PhysicalRegisterInfo &PRI;
};