[llvm] r293510 - [RDF] Extract the physical register information into a separate class
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 30 09:46:57 PST 2017
Author: kparzysz
Date: Mon Jan 30 11:46:56 2017
New Revision: 293510
URL: http://llvm.org/viewvc/llvm-project?rev=293510&view=rev
Log:
[RDF] Extract the physical register information into a separate class
Added:
llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
Modified:
llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
llvm/trunk/lib/Target/Hexagon/RDFGraph.h
llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
llvm/trunk/lib/Target/Hexagon/RDFLiveness.h
Modified: llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/CMakeLists.txt?rev=293510&r1=293509&r2=293510&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/Hexagon/CMakeLists.txt Mon Jan 30 11:46:56 2017
@@ -59,6 +59,7 @@ add_llvm_target(HexagonCodeGen
RDFDeadCode.cpp
RDFGraph.cpp
RDFLiveness.cpp
+ RDFRegisters.cpp
)
add_subdirectory(AsmParser)
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=293510&r1=293509&r2=293510&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Mon Jan 30 11:46:56 2017
@@ -654,109 +654,6 @@ bool TargetOperandInfo::isFixedReg(const
return false;
}
-RegisterRef RegisterAggr::normalize(RegisterRef RR) const {
- RegisterId SuperReg = RR.Reg;
- while (true) {
- MCSuperRegIterator SR(SuperReg, &TRI, false);
- if (!SR.isValid())
- break;
- SuperReg = *SR;
- }
-
- const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg);
- LaneBitmask Common = RR.Mask & RC.LaneMask;
- uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
- LaneBitmask SuperMask = TRI.composeSubRegIndexLaneMask(Sub, Common);
- return RegisterRef(SuperReg, SuperMask);
-}
-
-bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
- RegisterRef NR = normalize(RR);
- auto F = Masks.find(NR.Reg);
- if (F != Masks.end()) {
- if ((F->second & NR.Mask).any())
- return true;
- }
- if (CheckUnits) {
- for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U)
- if (ExpAliasUnits.test(*U))
- return true;
- }
- return false;
-}
-
-bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
- // Always have a cover for empty lane mask.
- RegisterRef NR = normalize(RR);
- if (NR.Mask.none())
- return true;
- auto F = Masks.find(NR.Reg);
- if (F == Masks.end())
- return false;
- return (NR.Mask & F->second) == NR.Mask;
-}
-
-RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
- RegisterRef NR = normalize(RR);
- auto F = Masks.find(NR.Reg);
- if (F == Masks.end())
- Masks.insert({NR.Reg, NR.Mask});
- else
- F->second |= NR.Mask;
-
- // Visit all register units to see if there are any that were created
- // by explicit aliases. Add those that were to the bit vector.
- for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U) {
- MCRegUnitRootIterator R(*U, &TRI);
- ++R;
- if (!R.isValid())
- continue;
- ExpAliasUnits.set(*U);
- CheckUnits = true;
- }
- return *this;
-}
-
-RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
- for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
- insert(RegisterRef(P.first, P.second));
- return *this;
-}
-
-RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
- RegisterRef NR = 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;
-}
-
-RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
- for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
- clear(RegisterRef(P.first, P.second));
- return *this;
-}
-
-RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
- RegisterAggr T(TRI);
- T.insert(RR).clear(*this);
- if (T.empty())
- return RegisterRef();
- return RegisterRef(T.begin()->first, T.begin()->second);
-}
-
-void RegisterAggr::print(raw_ostream &OS) const {
- OS << '{';
- for (auto I : Masks)
- OS << ' ' << PrintReg(I.first, &TRI) << PrintLaneMaskOpt(I.second);
- OS << " }";
-}
-
//
// The data flow graph construction.
//
@@ -764,7 +661,8 @@ void RegisterAggr::print(raw_ostream &OS
DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
- : MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi), LiveIns(TRI) {
+ : MF(mf), TII(tii), TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
+ LiveIns(PRI) {
}
// The implementation of the definition stack.
@@ -1211,59 +1109,6 @@ NodeList DataFlowGraph::getRelatedRefs(N
return Refs;
}
-// Return true if RA and RB overlap, false otherwise.
-bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
- assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg));
- assert(TargetRegisterInfo::isPhysicalRegister(RB.Reg));
-
- MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
- MCRegUnitMaskIterator UMB(RB.Reg, &TRI);
- // Reg units are returned in the numerical order.
- while (UMA.isValid() && UMB.isValid()) {
- std::pair<uint32_t,LaneBitmask> PA = *UMA;
- std::pair<uint32_t,LaneBitmask> PB = *UMB;
- if (PA.first == PB.first) {
- // Lane mask of 0 (given by the iterator) should be treated as "full".
- // This can happen when the register has only one unit, or when the
- // unit corresponds to explicit aliasing. In such cases, the lane mask
- // from RegisterRef should be ignored.
- if (PA.second.none() || PB.second.none())
- return true;
-
- // At this point the common unit corresponds to a subregister. The lane
- // masks correspond to the lane mask of that unit within the original
- // register, for example assuming register quadruple q0 = r3:0, and
- // a register pair d1 = r3:2, the lane mask of r2 in q0 may be 0b0100,
- // while the lane mask of r2 in d1 may be 0b0001.
- LaneBitmask LA = PA.second & RA.Mask;
- LaneBitmask LB = PB.second & RB.Mask;
- if (LA.any() && LB.any()) {
- unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
- // If register units were guaranteed to only have 1 bit in any lane
- // mask, the code below would not be necessary. This is because LA
- // and LB would have at most 1 bit set each, and that bit would be
- // guaranteed to correspond to the given register unit.
- uint32_t SubA = TRI.getSubRegIndex(RA.Reg, Root);
- uint32_t SubB = TRI.getSubRegIndex(RB.Reg, Root);
- const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Root);
- LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
- LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
- if ((MaskA & MaskB & RC.LaneMask).any())
- return true;
- }
-
- ++UMA;
- ++UMB;
- continue;
- }
- if (PA.first < PB.first)
- ++UMA;
- else if (PB.first < PA.first)
- ++UMB;
- }
- return false;
-}
-
// Clear all information in the graph.
void DataFlowGraph::reset() {
Memory.clear();
@@ -1392,7 +1237,7 @@ void DataFlowGraph::buildStmt(NodeAddr<B
if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
continue;
RegisterRef UR = makeRegRef(UseOp.getReg(), UseOp.getSubReg());
- if (alias(DR, UR))
+ if (PRI.alias(DR, UR))
return false;
}
return true;
@@ -1578,7 +1423,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
for (RegisterRef I : RRs)
- if (I != RR && RegisterAggr::isCoverOf(I, RR, TRI))
+ if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
RR = I;
return RR;
};
@@ -1605,7 +1450,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
auto Aliased = [this,&MaxRefs](RegisterRef RR,
std::vector<unsigned> &Closure) -> bool {
for (unsigned I : Closure)
- if (alias(RR, MaxRefs[I]))
+ if (PRI.alias(RR, MaxRefs[I]))
return true;
return false;
};
@@ -1716,7 +1561,7 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
NodeAddr<T> TAP;
// References from the def stack that have been examined so far.
- RegisterAggr Defs(TRI);
+ RegisterAggr Defs(PRI);
for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
RegisterRef QR = I->Addr->getRegRef(*this);
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=293510&r1=293509&r2=293510&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Mon Jan 30 11:46:56 2017
@@ -225,6 +225,7 @@
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
#define LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
+#include "RDFRegisters.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/LaneBitmask.h"
@@ -260,7 +261,6 @@ namespace llvm {
namespace rdf {
typedef uint32_t NodeId;
- typedef uint32_t RegisterId;
struct DataFlowGraph;
@@ -412,25 +412,6 @@ namespace rdf {
AllocatorTy MemPool;
};
- struct RegisterRef {
- RegisterId Reg;
- LaneBitmask Mask;
-
- RegisterRef() : RegisterRef(0) {}
- explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
- : Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
-
- operator bool() const { return Reg != 0 && Mask.any(); }
- bool operator== (const RegisterRef &RR) const {
- return Reg == RR.Reg && Mask == RR.Mask;
- }
- bool operator!= (const RegisterRef &RR) const {
- return !operator==(RR);
- }
- bool operator< (const RegisterRef &RR) const {
- return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
- }
- };
typedef std::set<RegisterRef> RegisterSet;
struct TargetOperandInfo {
@@ -497,55 +478,6 @@ namespace rdf {
assert(LM.any());
return LM.all() ? 0 : find(LM);
}
-
- PackedRegisterRef pack(RegisterRef RR) {
- return { RR.Reg, getIndexForLaneMask(RR.Mask) };
- }
- PackedRegisterRef pack(RegisterRef RR) const {
- return { RR.Reg, getIndexForLaneMask(RR.Mask) };
- }
-
- RegisterRef unpack(PackedRegisterRef PR) const {
- return RegisterRef(PR.Reg, getLaneMaskForIndex(PR.MaskId));
- }
- };
-
- struct RegisterAggr {
- RegisterAggr(const TargetRegisterInfo &tri)
- : ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false), TRI(tri) {}
- RegisterAggr(const RegisterAggr &RG) = default;
-
- bool empty() const { return Masks.empty(); }
- bool hasAliasOf(RegisterRef RR) const;
- bool hasCoverOf(RegisterRef RR) const;
- static bool isCoverOf(RegisterRef RA, RegisterRef RB,
- const TargetRegisterInfo &TRI) {
- return RegisterAggr(TRI).insert(RA).hasCoverOf(RB);
- }
-
- RegisterAggr &insert(RegisterRef RR);
- RegisterAggr &insert(const RegisterAggr &RG);
- RegisterAggr &clear(RegisterRef RR);
- RegisterAggr &clear(const RegisterAggr &RG);
-
- RegisterRef clearIn(RegisterRef RR) const;
-
- void print(raw_ostream &OS) const;
-
- private:
- typedef std::unordered_map<RegisterId, LaneBitmask> MapType;
-
- public:
- typedef MapType::const_iterator iterator;
- iterator begin() const { return Masks.begin(); }
- iterator end() const { return Masks.end(); }
- RegisterRef normalize(RegisterRef RR) const;
-
- private:
- MapType Masks;
- BitVector ExpAliasUnits; // Register units for explicit aliases.
- bool CheckUnits;
- const TargetRegisterInfo &TRI;
};
struct NodeBase {
@@ -761,6 +693,7 @@ namespace rdf {
MachineFunction &getMF() const { return MF; }
const TargetInstrInfo &getTII() const { return TII; }
const TargetRegisterInfo &getTRI() const { return TRI; }
+ const PhysicalRegisterInfo &getPRI() const { return PRI; }
const MachineDominatorTree &getDT() const { return MDT; }
const MachineDominanceFrontier &getDF() const { return MDF; }
const RegisterAggr &getLiveIns() const { return LiveIns; }
@@ -833,9 +766,16 @@ namespace rdf {
void markBlock(NodeId B, DefStackMap &DefM);
void releaseBlock(NodeId B, DefStackMap &DefM);
- PackedRegisterRef pack(RegisterRef RR) { return LMI.pack(RR); }
- PackedRegisterRef pack(RegisterRef RR) const { return LMI.pack(RR); }
- RegisterRef unpack(PackedRegisterRef PR) const { return LMI.unpack(PR); }
+ PackedRegisterRef pack(RegisterRef RR) {
+ return { RR.Reg, LMI.getIndexForLaneMask(RR.Mask) };
+ }
+ PackedRegisterRef pack(RegisterRef RR) const {
+ return { RR.Reg, LMI.getIndexForLaneMask(RR.Mask) };
+ }
+ RegisterRef unpack(PackedRegisterRef PR) const {
+ return RegisterRef(PR.Reg, LMI.getLaneMaskForIndex(PR.MaskId));
+ }
+
RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const;
RegisterRef normalizeRef(RegisterRef RR) const;
RegisterRef restrictRef(RegisterRef AR, RegisterRef BR) const;
@@ -899,9 +839,6 @@ namespace rdf {
return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
}
- // Register aliasing.
- bool alias(RegisterRef RA, RegisterRef RB) const;
-
private:
void reset();
@@ -961,6 +898,7 @@ namespace rdf {
MachineFunction &MF;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
+ const PhysicalRegisterInfo PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
const TargetOperandInfo &TOI;
@@ -1015,12 +953,6 @@ namespace rdf {
return MM;
}
- // Optionally print the lane mask, if it is not ~0.
- struct PrintLaneMaskOpt {
- PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
- LaneBitmask Mask;
- };
- raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
template <typename T> struct Print;
template <typename T>
Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=293510&r1=293509&r2=293510&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Mon Jan 30 11:46:56 2017
@@ -119,7 +119,7 @@ NodeList Liveness::getAllReachingDefs(Re
// Stop at the covering/overwriting def of the initial register reference.
RegisterRef RR = TA.Addr->getRegRef(DFG);
if (!DFG.IsPreservingDef(TA))
- if (RegisterAggr::isCoverOf(RR, RefRR, TRI))
+ if (RegisterAggr::isCoverOf(RR, RefRR, PRI))
continue;
// Get the next level of reaching defs. This will include multiple
// reaching defs for shadows.
@@ -134,7 +134,7 @@ NodeList Liveness::getAllReachingDefs(Re
for (NodeId N : DefQ) {
auto TA = DFG.addr<DefNode*>(N);
bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
- if (!IsPhi && !DFG.alias(RefRR, TA.Addr->getRegRef(DFG)))
+ if (!IsPhi && !PRI.alias(RefRR, TA.Addr->getRegRef(DFG)))
continue;
Defs.insert(TA.Id);
Owners.insert(TA.Addr->getOwner(DFG).Id);
@@ -245,7 +245,7 @@ NodeSet Liveness::getAllReachingDefsRec(
NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) {
// Collect all defined registers. Do not consider phis to be defining
// anything, only collect "real" definitions.
- RegisterAggr DefRRs(TRI);
+ RegisterAggr DefRRs(PRI);
for (NodeId D : Defs) {
const auto DA = DFG.addr<const DefNode*>(D);
if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef))
@@ -299,7 +299,7 @@ NodeSet Liveness::getAllReachedUses(Regi
auto UA = DFG.addr<UseNode*>(U);
if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
RegisterRef UR = UA.Addr->getRegRef(DFG);
- if (DFG.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
+ if (PRI.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
Uses.insert(U);
}
U = UA.Addr->getSibling();
@@ -312,7 +312,7 @@ NodeSet Liveness::getAllReachedUses(Regi
RegisterRef DR = DA.Addr->getRegRef(DFG);
// If this def is already covered, it cannot reach anything new.
// Similarly, skip it if it is not aliased to the interesting register.
- if (DefRRs.hasCoverOf(DR) || !DFG.alias(RefRR, DR))
+ if (DefRRs.hasCoverOf(DR) || !PRI.alias(RefRR, DR))
continue;
NodeSet T;
if (DFG.IsPreservingDef(DA)) {
@@ -463,7 +463,7 @@ void Liveness::computePhiInfo() {
for (NodeAddr<UseNode*> VA : DFG.getRelatedRefs(PhiA, UA)) {
SeenUses.insert(VA.Id);
- RegisterAggr DefRRs(TRI);
+ RegisterAggr DefRRs(PRI);
for (NodeAddr<DefNode*> DA : getAllReachingDefs(VA)) {
if (DA.Addr->getFlags() & NodeAttrs::PhiRef) {
NodeId RP = DA.Addr->getOwner(DFG).Id;
@@ -918,7 +918,7 @@ void Liveness::traverse(MachineBasicBloc
// propagated upwards. This only applies to non-preserving defs,
// and to the parts of the register actually covered by those defs.
// (Note that phi defs should always be preserving.)
- RegisterAggr RRs(TRI);
+ RegisterAggr RRs(PRI);
LRef.Mask = OR.second;
if (!DFG.IsPreservingDef(DA)) {
@@ -946,7 +946,7 @@ 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(TRI);
+ RegisterAggr L(PRI);
L.insert(LRef).clear(RRs);
assert(!L.empty());
NewDefs.insert({TA.Id,L.begin()->second});
Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.h?rev=293510&r1=293509&r2=293510&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.h Mon Jan 30 11:46:56 2017
@@ -33,7 +33,7 @@ namespace rdf {
// This is really a std::map, except that it provides a non-trivial
// default constructor to the element accessed via [].
struct LiveMapType {
- LiveMapType(const TargetRegisterInfo &tri) : Empty(tri) {}
+ LiveMapType(const PhysicalRegisterInfo &pri) : Empty(pri) {}
RegisterAggr &operator[] (MachineBasicBlock *B) {
return Map.emplace(B, Empty).first->second;
@@ -49,9 +49,9 @@ namespace rdf {
typedef std::map<RegisterId,NodeRefSet> RefMap;
Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
- : DFG(g), TRI(g.getTRI()), MDT(g.getDT()), MDF(g.getDF()),
- MRI(mri), LiveMap(g.getTRI()), Empty(), NoRegs(g.getTRI()),
- Trace(false) {}
+ : DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
+ MDF(g.getDF()), MRI(mri), LiveMap(g.getPRI()), Empty(),
+ NoRegs(g.getPRI()), Trace(false) {}
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
bool FullChain, const RegisterAggr &DefRRs);
@@ -87,6 +87,7 @@ namespace rdf {
private:
const DataFlowGraph &DFG;
const TargetRegisterInfo &TRI;
+ const PhysicalRegisterInfo &PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
MachineRegisterInfo &MRI;
Added: llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp?rev=293510&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp (added)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp Mon Jan 30 11:46:56 2017
@@ -0,0 +1,196 @@
+//===--- RDFRegisters.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RDFRegisters.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+using namespace llvm;
+using namespace rdf;
+
+PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
+ const MachineFunction &mf)
+ : TRI(tri) {
+ RegInfos.resize(TRI.getNumRegs());
+
+ BitVector BadRC(TRI.getNumRegs());
+ for (const TargetRegisterClass *RC : TRI.regclasses()) {
+ for (MCPhysReg R : *RC) {
+ RegInfo &RI = RegInfos[R];
+ if (RI.RegClass != nullptr && !BadRC[R]) {
+ if (RC->LaneMask != RI.RegClass->LaneMask) {
+ BadRC.set(R);
+ RI.RegClass = nullptr;
+ }
+ } else
+ RI.RegClass = RC;
+ }
+ }
+
+ for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R) {
+ MCPhysReg SuperR = R;
+ for (MCSuperRegIterator S(R, &TRI, false); S.isValid(); ++S)
+ SuperR = *S;
+ RegInfos[R].MaxSuper = SuperR;
+ }
+}
+
+bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const {
+ assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg));
+ assert(TargetRegisterInfo::isPhysicalRegister(RB.Reg));
+ MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
+ MCRegUnitMaskIterator UMB(RB.Reg, &TRI);
+ // Reg units are returned in the numerical order.
+ while (UMA.isValid() && UMB.isValid()) {
+ std::pair<uint32_t,LaneBitmask> PA = *UMA;
+ std::pair<uint32_t,LaneBitmask> PB = *UMB;
+ if (PA.first == PB.first) {
+ // Lane mask of 0 (given by the iterator) should be treated as "full".
+ // This can happen when the register has only one unit, or when the
+ // unit corresponds to explicit aliasing. In such cases, the lane mask
+ // from RegisterRef should be ignored.
+ if (PA.second.none() || PB.second.none())
+ return true;
+
+ // At this point the common unit corresponds to a subregister. The lane
+ // masks correspond to the lane mask of that unit within the original
+ // register, for example assuming register quadruple q0 = r3:0, and
+ // a register pair d1 = r3:2, the lane mask of r2 in q0 may be 0b0100,
+ // while the lane mask of r2 in d1 may be 0b0001.
+ LaneBitmask LA = PA.second & RA.Mask;
+ LaneBitmask LB = PB.second & RB.Mask;
+ if (LA.any() && LB.any()) {
+ unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
+ // If register units were guaranteed to only have 1 bit in any lane
+ // mask, the code below would not be necessary. This is because LA
+ // and LB would have at most 1 bit set each, and that bit would be
+ // guaranteed to correspond to the given register unit.
+ uint32_t SubA = TRI.getSubRegIndex(RA.Reg, Root);
+ uint32_t SubB = TRI.getSubRegIndex(RB.Reg, Root);
+ const TargetRegisterClass *RC = RegInfos[Root].RegClass;
+ LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x1);
+ LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
+ LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
+ if ((MaskA & MaskB & RCMask).any())
+ return true;
+ }
+
+ ++UMA;
+ ++UMB;
+ continue;
+ }
+ if (PA.first < PB.first)
+ ++UMA;
+ else if (PB.first < PA.first)
+ ++UMB;
+ }
+ return false;
+}
+
+RegisterRef RegisterAggr::normalize(RegisterRef RR) const {
+ const TargetRegisterClass *RC = PRI.RegInfos[RR.Reg].RegClass;
+ LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x00000001);
+ LaneBitmask Common = RR.Mask & RCMask;
+
+ RegisterId SuperReg = PRI.RegInfos[RR.Reg].MaxSuper;
+// Ex: IP/EIP/RIP
+// assert(RC != nullptr || RR.Reg == SuperReg);
+ uint32_t Sub = PRI.getTRI().getSubRegIndex(SuperReg, RR.Reg);
+ LaneBitmask SuperMask = PRI.getTRI().composeSubRegIndexLaneMask(Sub, Common);
+ return RegisterRef(SuperReg, SuperMask);
+}
+
+bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
+ RegisterRef NR = normalize(RR);
+ auto F = Masks.find(NR.Reg);
+ if (F != Masks.end()) {
+ if ((F->second & NR.Mask).any())
+ return true;
+ }
+ if (CheckUnits) {
+ for (MCRegUnitIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U)
+ if (ExpAliasUnits.test(*U))
+ return true;
+ }
+ return false;
+}
+
+bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
+ // Always have a cover for empty lane mask.
+ RegisterRef NR = normalize(RR);
+ if (NR.Mask.none())
+ return true;
+ auto F = Masks.find(NR.Reg);
+ if (F == Masks.end())
+ return false;
+ return (NR.Mask & F->second) == NR.Mask;
+}
+
+RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
+ RegisterRef NR = normalize(RR);
+ auto F = Masks.find(NR.Reg);
+ if (F == Masks.end())
+ Masks.insert({NR.Reg, NR.Mask});
+ else
+ F->second |= NR.Mask;
+
+ // Visit all register units to see if there are any that were created
+ // by explicit aliases. Add those that were to the bit vector.
+ const TargetRegisterInfo &TRI = PRI.getTRI();
+ for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U) {
+ MCRegUnitRootIterator R(*U, &TRI);
+ ++R;
+ if (!R.isValid())
+ continue;
+ ExpAliasUnits.set(*U);
+ CheckUnits = true;
+ }
+ return *this;
+}
+
+RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
+ for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
+ insert(RegisterRef(P.first, P.second));
+ return *this;
+}
+
+RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
+ RegisterRef NR = 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;
+}
+
+RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
+ for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
+ clear(RegisterRef(P.first, P.second));
+ return *this;
+}
+
+RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
+ RegisterAggr T(PRI);
+ T.insert(RR).clear(*this);
+ if (T.empty())
+ return RegisterRef();
+ return RegisterRef(T.begin()->first, T.begin()->second);
+}
+
+void RegisterAggr::print(raw_ostream &OS) const {
+ OS << '{';
+ for (auto I : Masks)
+ OS << ' ' << PrintReg(I.first, &PRI.getTRI())
+ << PrintLaneMaskOpt(I.second);
+ OS << " }";
+}
+
Added: llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.h?rev=293510&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.h (added)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.h Mon Jan 30 11:46:56 2017
@@ -0,0 +1,115 @@
+//===--- RDFRegisters.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
+#define LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+
+#include <unordered_map>
+#include <vector>
+
+namespace llvm {
+namespace rdf {
+
+ typedef uint32_t RegisterId;
+
+ struct RegisterRef {
+ RegisterId Reg = 0;
+ LaneBitmask Mask = LaneBitmask::getNone();
+
+ RegisterRef() = default;
+ explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
+ : Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
+
+ operator bool() const {
+ return Reg != 0 && Mask.any();
+ }
+ bool operator== (const RegisterRef &RR) const {
+ return Reg == RR.Reg && Mask == RR.Mask;
+ }
+ bool operator!= (const RegisterRef &RR) const {
+ return !operator==(RR);
+ }
+ bool operator< (const RegisterRef &RR) const {
+ return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
+ }
+ };
+
+
+ struct PhysicalRegisterInfo {
+ PhysicalRegisterInfo(const TargetRegisterInfo &tri,
+ const MachineFunction &mf);
+
+ bool alias(RegisterRef RA, RegisterRef RB) const;
+
+ const TargetRegisterInfo &getTRI() const { return TRI; }
+
+// private:
+ struct RegInfo {
+ unsigned MaxSuper = 0;
+ const TargetRegisterClass *RegClass = nullptr;
+ };
+
+ const TargetRegisterInfo &TRI;
+ std::vector<RegInfo> RegInfos;
+ };
+
+
+ struct RegisterAggr {
+ RegisterAggr(const PhysicalRegisterInfo &pri)
+ : ExpAliasUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
+ RegisterAggr(const RegisterAggr &RG) = default;
+
+ bool empty() const { return Masks.empty(); }
+ bool hasAliasOf(RegisterRef RR) const;
+ bool hasCoverOf(RegisterRef RR) const;
+ static bool isCoverOf(RegisterRef RA, RegisterRef RB,
+ const PhysicalRegisterInfo &PRI) {
+ return RegisterAggr(PRI).insert(RA).hasCoverOf(RB);
+ }
+
+ RegisterAggr &insert(RegisterRef RR);
+ RegisterAggr &insert(const RegisterAggr &RG);
+ RegisterAggr &clear(RegisterRef RR);
+ RegisterAggr &clear(const RegisterAggr &RG);
+
+ RegisterRef clearIn(RegisterRef RR) const;
+
+ void print(raw_ostream &OS) const;
+
+ private:
+ typedef std::unordered_map<RegisterId, LaneBitmask> MapType;
+
+ public:
+ typedef MapType::const_iterator iterator;
+ iterator begin() const { return Masks.begin(); }
+ iterator end() const { return Masks.end(); }
+ RegisterRef normalize(RegisterRef RR) const;
+
+ private:
+ MapType Masks;
+ BitVector ExpAliasUnits; // Register units for explicit aliases.
+ bool CheckUnits = false;
+ const PhysicalRegisterInfo &PRI;
+ };
+
+ // Optionally print the lane mask, if it is not ~0.
+ struct PrintLaneMaskOpt {
+ PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
+ LaneBitmask Mask;
+ };
+ raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);
+
+} // namespace rdf
+} // namespace llvm
+
+#endif
+
More information about the llvm-commits
mailing list