[llvm] r300345 - [RDF] Switch RegisterAggr to a bit vector of register units
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 14 10:25:14 PDT 2017
Author: kparzysz
Date: Fri Apr 14 12:25:13 2017
New Revision: 300345
URL: http://llvm.org/viewvc/llvm-project?rev=300345&view=rev
Log:
[RDF] Switch RegisterAggr to a bit vector of register units
This avoids many complications related to the complex register
aliasing schemes.
Modified:
llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
Modified: llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp Fri Apr 14 12:25:13 2017
@@ -259,7 +259,7 @@ void HexagonOptAddrMode::getAllRealUses(
<< Print<Liveness::RefMap>(phiUse, *DFG) << "\n");
if (!phiUse.empty()) {
for (auto I : phiUse) {
- if (DR.Reg != I.first)
+ if (!DFG->getPRI().alias(RegisterRef(I.first), DR))
continue;
auto phiUseSet = I.second;
for (auto phiUI : phiUseSet) {
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Fri Apr 14 12:25:13 2017
@@ -913,10 +913,11 @@ void DataFlowGraph::build(unsigned Optio
}
// Add function-entry phi nodes for the live-in registers.
- for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
+ //for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
+ for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
+ RegisterRef RR = *I;
NodeAddr<PhiNode*> PA = newPhi(EA);
uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
- RegisterRef RR(P.first, P.second);
NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
PA.Addr->addMember(DA, *this);
}
@@ -993,9 +994,9 @@ RegisterRef DataFlowGraph::restrictRef(R
return M.any() ? RegisterRef(AR.Reg, M) : RegisterRef();
}
#ifndef NDEBUG
- RegisterRef NAR = PRI.normalize(AR);
- RegisterRef NBR = PRI.normalize(BR);
- assert(NAR.Reg != NBR.Reg);
+// RegisterRef NAR = PRI.normalize(AR);
+// RegisterRef NBR = PRI.normalize(BR);
+// assert(NAR.Reg != NBR.Reg);
#endif
// This isn't strictly correct, because the overlap may happen in the
// part masked out.
Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Fri Apr 14 12:25:13 2017
@@ -797,19 +797,9 @@ void Liveness::computeLiveIns() {
//dbgs() << "\tcomp = " << Print<RegisterAggr>(LiveMap[&B], DFG) << '\n';
LV.clear();
- for (std::pair<RegisterId,LaneBitmask> P : LiveMap[&B]) {
- MCSubRegIndexIterator S(P.first, &TRI);
- if (!S.isValid()) {
- LV.push_back(RegisterRef(P.first));
- continue;
- }
- do {
- LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
- if ((M & P.second).any())
- LV.push_back(RegisterRef(S.getSubReg()));
- ++S;
- } while (S.isValid());
- }
+ const RegisterAggr &LG = LiveMap[&B];
+ for (auto I = LG.rr_begin(), E = LG.rr_end(); I != E; ++I)
+ LV.push_back(*I);
std::sort(LV.begin(), LV.end());
dbgs() << "\tcomp = {";
for (auto I : LV)
@@ -830,9 +820,10 @@ void Liveness::resetLiveIns() {
for (auto I : T)
B.removeLiveIn(I);
// Add the newly computed live-ins.
- auto &LiveIns = LiveMap[&B];
- for (auto I : LiveIns) {
- B.addLiveIn({MCPhysReg(I.first), I.second});
+ const RegisterAggr &LiveIns = LiveMap[&B];
+ for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
+ RegisterRef R = *I;
+ B.addLiveIn({MCPhysReg(R.Reg), R.Mask});
}
}
}
@@ -1032,10 +1023,9 @@ void Liveness::traverse(MachineBasicBloc
// registers are not covering LRef. The first def from the
// upward chain will be live.
// Subtract all accumulated defs (RRs) from LRef.
- RegisterAggr L(PRI);
- L.insert(LRef).clear(RRs);
- assert(!L.empty());
- NewDefs.insert({TA.Id,L.begin()->second});
+ RegisterRef T = RRs.clearIn(LRef);
+ assert(T);
+ NewDefs.insert({TA.Id,T.Mask});
break;
}
Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp Fri Apr 14 12:25:13 2017
@@ -33,22 +33,33 @@ PhysicalRegisterInfo::PhysicalRegisterIn
}
}
- 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())
@@ -61,22 +72,7 @@ PhysicalRegisterInfo::PhysicalRegisterIn
}
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 {
@@ -217,19 +213,11 @@ bool RegisterAggr::hasAliasOf(RegisterRe
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;
}
@@ -247,25 +235,13 @@ bool RegisterAggr::hasCoverOf(RegisterRe
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) {
@@ -280,99 +256,34 @@ RegisterAggr &RegisterAggr::insert(Regis
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;
}
@@ -381,22 +292,75 @@ RegisterRef RegisterAggr::intersectWith(
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();
+
+ 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();
- return RegisterRef(T.begin()->first, T.begin()->second);
+
+ 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;
+}
+
Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.h?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.h Fri Apr 14 12:25:13 2017
@@ -103,21 +103,25 @@ namespace rdf {
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;
@@ -128,10 +132,10 @@ namespace rdf {
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,
@@ -148,21 +152,45 @@ namespace rdf {
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;
};
More information about the llvm-commits
mailing list