diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFGraph.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFGraph.cpp | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFGraph.cpp b/llvm/lib/Target/Hexagon/RDFGraph.cpp index f25fcf72065..3d0777af9cd 100644 --- a/llvm/lib/Target/Hexagon/RDFGraph.cpp +++ b/llvm/lib/Target/Hexagon/RDFGraph.cpp @@ -29,6 +29,12 @@ using namespace rdf; namespace llvm { namespace rdf { +raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P) { + if (P.Mask != ~LaneBitmask(0)) + OS << ':' << PrintLaneMask(P.Mask); + return OS; +} + template<> raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) { auto &TRI = P.G.getTRI(); @@ -36,8 +42,7 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) { OS << TRI.getName(P.Obj.Reg); else OS << '#' << P.Obj.Reg; - if (P.Obj.Mask != ~LaneBitmask(0)) - OS << ":" << PrintLaneMask(P.Obj.Mask); + OS << PrintLaneMaskOpt(P.Obj.Mask); return OS; } @@ -719,10 +724,24 @@ RegisterAggr &RegisterAggr::clear(RegisterRef RR) { return *this; } +RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) { + for (std::pair<uint32_t,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) << ':' << PrintLaneMask(I.second); + OS << ' ' << PrintReg(I.first, &TRI) << PrintLaneMaskOpt(I.second); OS << " }"; } @@ -1051,6 +1070,40 @@ RegisterRef DataFlowGraph::makeRegRef(unsigned Reg, unsigned Sub) const { return RegisterRef(Reg); } +RegisterRef DataFlowGraph::normalizeRef(RegisterRef RR) const { + // FIXME copied from RegisterAggr + uint32_t SuperReg = RR.Reg; + while (true) { + MCSuperRegIterator SR(SuperReg, &TRI, false); + if (!SR.isValid()) + break; + SuperReg = *SR; + } + + uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg); + const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg); + LaneBitmask SuperMask = RR.Mask & + TRI.composeSubRegIndexLaneMask(Sub, RC.LaneMask); + return RegisterRef(SuperReg, SuperMask); +} + +RegisterRef DataFlowGraph::restrictRef(RegisterRef AR, RegisterRef BR) const { + if (AR.Reg == BR.Reg) { + LaneBitmask M = AR.Mask & BR.Mask; + return M ? RegisterRef(AR.Reg, M) : RegisterRef(); + } +#ifndef NDEBUG + RegisterRef NAR = normalizeRef(AR); + RegisterRef NBR = normalizeRef(BR); + assert(NAR.Reg != NBR.Reg); +#endif + // This isn't strictly correct, because the overlap may happen in the + // part masked out. + if (TRI.regsOverlap(AR.Reg, BR.Reg)) + return AR; + return RegisterRef(); +} + // For each stack in the map DefM, push the delimiter for block B on it. void DataFlowGraph::markBlock(NodeId B, DefStackMap &DefM) { // Push block delimiters. |