From 7bb63ac029bfe00e24ed4628d46252fde200c0e4 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Wed, 19 Oct 2016 16:30:56 +0000 Subject: [RDF] Switch RefMap in liveness calculation to use lane masks This required reengineering of some of the part of liveness calculation, including fixing some issues caused by the limitations of the previous approach. The current code is not necessarily the fastest, but it should be functionally correct (at least more so than before). The compile-time performance will be addressed in the future. llvm-svn: 284609 --- llvm/lib/Target/Hexagon/RDFGraph.cpp | 59 ++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'llvm/lib/Target/Hexagon/RDFGraph.cpp') 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 &P) { auto &TRI = P.G.getTRI(); @@ -36,8 +42,7 @@ raw_ostream &operator<< (raw_ostream &OS, const Print &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 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. -- cgit v1.2.3