[llvm] r283122 - [RDF] Replace RegisterAliasInfo with target-independent code using lane masks
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 3 10:14:49 PDT 2016
Author: kparzysz
Date: Mon Oct 3 12:14:48 2016
New Revision: 283122
URL: http://llvm.org/viewvc/llvm-project?rev=283122&view=rev
Log:
[RDF] Replace RegisterAliasInfo with target-independent code using lane masks
Removed:
llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp
llvm/trunk/lib/Target/Hexagon/HexagonRDF.h
Modified:
llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp
llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
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=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/Hexagon/CMakeLists.txt Mon Oct 3 12:14:48 2016
@@ -42,7 +42,6 @@ add_llvm_target(HexagonCodeGen
HexagonOptAddrMode.cpp
HexagonOptimizeSZextends.cpp
HexagonPeephole.cpp
- HexagonRDF.cpp
HexagonRDFOpt.cpp
HexagonRegisterInfo.cpp
HexagonSelectionDAGInfo.cpp
Modified: llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp Mon Oct 3 12:14:48 2016
@@ -587,7 +587,7 @@ void HexagonOptAddrMode::updateMap(NodeA
return;
for (auto &R : RDefMap) {
- auto F = DefM.find(R.first);
+ auto F = DefM.find(R.first.Reg);
if (F == DefM.end() || F->second.empty())
continue;
R.second[IA.Id] = F->second.top()->Id;
@@ -622,8 +622,7 @@ bool HexagonOptAddrMode::runOnMachineFun
const auto &TRI = *MF.getSubtarget().getRegisterInfo();
const TargetOperandInfo TOI(*HII);
- RegisterAliasInfo RAI(TRI);
- DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, RAI, TOI);
+ DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, TOI);
G.build();
DFG = &G;
Removed: llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp?rev=283121&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp (removed)
@@ -1,64 +0,0 @@
-//===--- HexagonRDF.cpp ---------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonRDF.h"
-#include "HexagonInstrInfo.h"
-#include "HexagonRegisterInfo.h"
-
-#include "llvm/CodeGen/MachineInstr.h"
-
-using namespace llvm;
-using namespace rdf;
-
-bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
- const DataFlowGraph &DFG) const {
- if (RA == RB)
- return true;
-
- if (TargetRegisterInfo::isVirtualRegister(RA.Reg) &&
- TargetRegisterInfo::isVirtualRegister(RB.Reg)) {
- // Hexagon-specific cases.
- if (RA.Reg == RB.Reg) {
- if (RA.Sub == 0)
- return true;
- if (RB.Sub == 0)
- return false;
- }
- }
-
- return RegisterAliasInfo::covers(RA, RB, DFG);
-}
-
-bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
- const DataFlowGraph &DFG) const {
- if (RRs.count(RR))
- return true;
-
- // The exact reference RR is not in the set.
-
- if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
- // Check if the there are references in RRs of the same register,
- // with both covering subregisters.
- bool HasLo = RRs.count({RR.Reg, Hexagon::subreg_loreg});
- bool HasHi = RRs.count({RR.Reg, Hexagon::subreg_hireg});
- if (HasLo && HasHi)
- return true;
- }
-
- if (TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
- // Check if both covering subregisters are present with full
- // lane masks.
- unsigned Lo = TRI.getSubReg(RR.Reg, Hexagon::subreg_loreg);
- unsigned Hi = TRI.getSubReg(RR.Reg, Hexagon::subreg_hireg);
- if (RRs.count({Lo, 0}) && RRs.count({Hi, 0}))
- return true;
- }
-
- return RegisterAliasInfo::covers(RRs, RR, DFG);
-}
Removed: llvm/trunk/lib/Target/Hexagon/HexagonRDF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDF.h?rev=283121&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDF.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDF.h (removed)
@@ -1,30 +0,0 @@
-//===--- HexagonRDF.h -----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXAGON_RDF_H
-#define HEXAGON_RDF_H
-#include "RDFGraph.h"
-
-namespace llvm {
- class TargetRegisterInfo;
-
-namespace rdf {
- struct HexagonRegisterAliasInfo : public RegisterAliasInfo {
- HexagonRegisterAliasInfo(const TargetRegisterInfo &TRI)
- : RegisterAliasInfo(TRI) {}
- bool covers(RegisterRef RA, RegisterRef RR,
- const DataFlowGraph &DFG) const override;
- bool covers(const RegisterSet &RRs, RegisterRef RR,
- const DataFlowGraph &DFG) const override;
- };
-} // namespace rdf
-} // namespace llvm
-
-#endif
-
Modified: llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp Mon Oct 3 12:14:48 2016
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "HexagonInstrInfo.h"
-#include "HexagonRDF.h"
#include "HexagonSubtarget.h"
#include "RDFCopy.h"
#include "RDFDeadCode.h"
@@ -286,9 +285,8 @@ bool HexagonRDFOpt::runOnMachineFunction
if (RDFDump)
MF.print(dbgs() << "Before " << getPassName() << "\n", nullptr);
- HexagonRegisterAliasInfo HAI(HRI);
TargetOperandInfo TOI(HII);
- DataFlowGraph G(MF, HII, HRI, *MDT, MDF, HAI, TOI);
+ DataFlowGraph G(MF, HII, HRI, *MDT, MDF, TOI);
// Dead phi nodes are necessary for copy propagation: we can add a use
// of a register in a block where it would need a phi node, but which
// was dead (and removed) during the graph build time.
Modified: llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp Mon Oct 3 12:14:48 2016
@@ -79,7 +79,7 @@ void CopyPropagation::recordCopy(NodeAdd
Copies.push_back(SA.Id);
for (auto I : EM) {
- auto FS = DefM.find(I.second);
+ auto FS = DefM.find(I.second.Reg);
if (FS == DefM.end() || FS->second.empty())
continue; // Undefined source
RDefMap[I.second][SA.Id] = FS->second.top()->Id;
@@ -106,7 +106,7 @@ void CopyPropagation::updateMap(NodeAddr
for (auto &R : RDefMap) {
if (!RRs.count(R.first))
continue;
- auto F = DefM.find(R.first);
+ auto F = DefM.find(R.first.Reg);
if (F == DefM.end() || F->second.empty())
continue;
R.second[IA.Id] = F->second.top()->Id;
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Mon Oct 3 12:14:48 2016
@@ -36,12 +36,9 @@ raw_ostream &operator<< (raw_ostream &OS
OS << TRI.getName(P.Obj.Reg);
else
OS << '#' << P.Obj.Reg;
- if (P.Obj.Sub > 0) {
- OS << ':';
- if (P.Obj.Sub < TRI.getNumSubRegIndices())
- OS << TRI.getSubRegIndexName(P.Obj.Sub);
- else
- OS << '#' << P.Obj.Sub;
+ if (P.Obj.Sub != 0) {
+ LaneBitmask LM = P.G.getLMI().getLaneMaskForIndex(P.Obj.Sub);
+ OS << ":L" << PrintLaneMask(LM);
}
return OS;
}
@@ -306,6 +303,12 @@ raw_ostream &operator<< (raw_ostream &OS
}
template<>
+raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterAggr> &P) {
+ P.Obj.print(OS);
+ return OS;
+}
+
+template<>
raw_ostream &operator<< (raw_ostream &OS,
const Print<DataFlowGraph::DefStack> &P) {
for (auto I = P.Obj.top(), E = P.Obj.bottom(); I != E; ) {
@@ -581,152 +584,6 @@ NodeAddr<BlockNode*> FuncNode::getEntryB
}
-// Register aliasing information.
-//
-
-LaneBitmask RegisterAliasInfo::getLaneMask(RegisterRef RR,
- const DataFlowGraph &DFG) const {
- assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
- const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(RR.Reg);
- return (RR.Sub != 0) ? DFG.getLaneMaskForIndex(RR.Sub) : RC->LaneMask;
-}
-
-RegisterAliasInfo::CommonRegister::CommonRegister(
- unsigned RegA, LaneBitmask LA, unsigned RegB, LaneBitmask LB,
- const TargetRegisterInfo &TRI) {
- if (RegA == RegB) {
- SuperReg = RegA;
- MaskA = LA;
- MaskB = LB;
- return;
- }
-
- // Find a common super-register.
- SuperReg = 0;
- for (MCSuperRegIterator SA(RegA, &TRI, true); SA.isValid(); ++SA) {
- if (!TRI.isSubRegisterEq(*SA, RegB))
- continue;
- SuperReg = *SA;
- break;
- }
- if (SuperReg == 0)
- return;
-
- if (unsigned SubA = TRI.getSubRegIndex(SuperReg, RegA))
- LA = TRI.composeSubRegIndexLaneMask(SubA, LA);
- if (unsigned SubB = TRI.getSubRegIndex(SuperReg, RegB))
- LB = TRI.composeSubRegIndexLaneMask(SubB, LB);
-
- MaskA = LA;
- MaskB = LB;
-}
-
-// Determine whether RA covers RB.
-bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
- const DataFlowGraph &DFG) const {
- if (RA == RB)
- return true;
- if (TargetRegisterInfo::isVirtualRegister(RA.Reg)) {
- assert(TargetRegisterInfo::isVirtualRegister(RB.Reg));
- if (RA.Reg != RB.Reg)
- return false;
- if (RA.Sub == 0)
- return true;
- return TRI.composeSubRegIndices(RA.Sub, RB.Sub) == RA.Sub;
- }
-
- assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg) &&
- TargetRegisterInfo::isPhysicalRegister(RB.Reg));
-
- CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
- RB.Reg, getLaneMask(RB, DFG), TRI);
- if (CR.SuperReg == 0)
- return false;
- return (CR.MaskA & CR.MaskB) == CR.MaskB;
-}
-
-// Determine whether RR is covered by the set of references RRs.
-bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
- const DataFlowGraph &DFG) const {
- if (RRs.count(RR))
- return true;
-
- // For virtual registers, we cannot accurately determine covering based
- // on subregisters. If RR itself is not present in RRs, but it has a sub-
- // register reference, check for the super-register alone. Otherwise,
- // assume non-covering.
- if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
- if (RR.Sub != 0)
- return RRs.count({RR.Reg, 0});
- return false;
- }
-
- // If any super-register of RR is present, then RR is covered.
- uint32_t Reg = RR.Sub == 0 ? RR.Reg : TRI.getSubReg(RR.Reg, RR.Sub);
- for (MCSuperRegIterator SR(Reg, &TRI); SR.isValid(); ++SR)
- if (RRs.count({*SR, 0}))
- return true;
-
- return false;
-}
-
-// Get the list of references aliased to RR. Lane masks are ignored.
-std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
- // Do not include RR in the alias set. For virtual registers return an
- // empty set.
- std::vector<RegisterRef> AS;
- if (TargetRegisterInfo::isVirtualRegister(RR.Reg))
- return AS;
- assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
- uint32_t R = RR.Reg;
- if (RR.Sub)
- R = TRI.getSubReg(RR.Reg, RR.Sub);
-
- for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)
- AS.push_back(RegisterRef({*AI, 0}));
- return AS;
-}
-
-// Check whether RA and RB are aliased.
-bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB,
- const DataFlowGraph &DFG) const {
- bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
- bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
- bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
- bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
-
- if (IsVirtA != IsVirtB)
- return false;
-
- if (IsVirtA) {
- if (RA.Reg != RB.Reg)
- return false;
- // RA and RB refer to the same register. If any of them refer to the
- // whole register, they must be aliased.
- if (RA.Sub == 0 || RB.Sub == 0)
- return true;
- unsigned SA = TRI.getSubRegIdxSize(RA.Sub);
- unsigned OA = TRI.getSubRegIdxOffset(RA.Sub);
- unsigned SB = TRI.getSubRegIdxSize(RB.Sub);
- unsigned OB = TRI.getSubRegIdxOffset(RB.Sub);
- if (OA <= OB && OA+SA > OB)
- return true;
- if (OB <= OA && OB+SB > OA)
- return true;
- return false;
- }
-
- assert(IsPhysA && IsPhysB);
- (void)IsPhysA, (void)IsPhysB;
-
- CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
- RB.Reg, getLaneMask(RB, DFG), TRI);
- if (CR.SuperReg == 0)
- return false;
- return (CR.MaskA & CR.MaskB) != 0;
-}
-
-
// Target operand information.
//
@@ -778,16 +635,112 @@ bool TargetOperandInfo::isFixedReg(const
}
+uint32_t RegisterAggr::getLargestSuperReg(uint32_t Reg) const {
+ uint32_t SuperReg = Reg;
+ while (true) {
+ MCSuperRegIterator SR(SuperReg, &TRI, false);
+ if (!SR.isValid())
+ return SuperReg;
+ SuperReg = *SR;
+ }
+ llvm_unreachable(nullptr);
+}
+
+LaneBitmask RegisterAggr::composeMaskForReg(uint32_t Reg, LaneBitmask LM,
+ uint32_t SuperR) const {
+ uint32_t SubR = TRI.getSubRegIndex(SuperR, Reg);
+ const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Reg);
+ return TRI.composeSubRegIndexLaneMask(SubR, LM & RC.LaneMask);
+}
+
+void RegisterAggr::setMaskRaw(uint32_t Reg, LaneBitmask LM) {
+ uint32_t SuperR = getLargestSuperReg(Reg);
+ LaneBitmask SuperM = composeMaskForReg(Reg, LM, SuperR);
+ auto F = Masks.find(SuperR);
+ if (F == Masks.end())
+ Masks.insert({SuperR, SuperM});
+ else
+ F->second |= SuperM;
+
+ // 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(Reg, &TRI); U.isValid(); ++U) {
+ MCRegUnitRootIterator R(*U, &TRI);
+ ++R;
+ if (!R.isValid())
+ continue;
+ ExpAliasUnits.set(*U);
+ CheckUnits = true;
+ }
+}
+
+bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
+ uint32_t SuperR = getLargestSuperReg(RR.Reg);
+ auto F = Masks.find(SuperR);
+ if (F != Masks.end()) {
+ LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+ if (F->second & composeMaskForReg(RR.Reg, M, SuperR))
+ 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 {
+ uint32_t SuperR = getLargestSuperReg(RR.Reg);
+ auto F = Masks.find(SuperR);
+ if (F == Masks.end())
+ return false;
+ LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+ LaneBitmask SuperM = composeMaskForReg(RR.Reg, M, SuperR);
+ return (SuperM & F->second) == SuperM;
+}
+
+RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
+ setMaskRaw(RR.Reg, LMI.getLaneMaskForIndex(RR.Sub));
+ return *this;
+}
+
+RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
+ for (auto P : RG.Masks)
+ setMaskRaw(P.first, P.second);
+ return *this;
+}
+
+RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
+ uint32_t SuperR = getLargestSuperReg(RR.Reg);
+ auto F = Masks.find(SuperR);
+ if (F == Masks.end())
+ return *this;
+ LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+ LaneBitmask NewM = F->second & ~composeMaskForReg(RR.Reg, M, SuperR);
+ if (NewM == LaneBitmask(0))
+ Masks.erase(F);
+ else
+ F->second = NewM;
+ return *this;
+}
+
+void RegisterAggr::print(raw_ostream &OS) const {
+ OS << '{';
+ for (auto I : Masks)
+ OS << ' ' << PrintReg(I.first, &TRI) << ':' << PrintLaneMask(I.second);
+ OS << " }";
+}
+
+
//
// The data flow graph construction.
//
DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
- const MachineDominanceFrontier &mdf, const RegisterAliasInfo &rai,
- const TargetOperandInfo &toi)
- : TimeG("rdf"), MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), RAI(rai),
- TOI(toi) {
+ const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
+ : TimeG("rdf"), MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi) {
}
@@ -879,16 +832,33 @@ unsigned DataFlowGraph::DefStack::nextDo
return P;
}
-std::vector<uint32_t> DataFlowGraph::getLandingPadLiveIns() const {
- std::vector<uint32_t> LR;
+
+// Register information.
+
+// Get the list of references aliased to RR. Lane masks are ignored.
+RegisterSet DataFlowGraph::getAliasSet(uint32_t Reg) const {
+ // Do not include RR in the alias set. For virtual registers return an
+ // empty set.
+ RegisterSet AS;
+ if (TargetRegisterInfo::isVirtualRegister(Reg))
+ return AS;
+ assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+ for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
+ AS.insert({*AI,0});
+ return AS;
+}
+
+RegisterSet DataFlowGraph::getLandingPadLiveIns() const {
+ RegisterSet LR;
const Function &F = *MF.getFunction();
const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn()
: nullptr;
const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
- if (uint32_t EPReg = TLI.getExceptionPointerRegister(PF))
- LR.push_back(EPReg);
- if (uint32_t ESReg = TLI.getExceptionSelectorRegister(PF))
- LR.push_back(ESReg);
+ if (uint32_t R = TLI.getExceptionPointerRegister(PF))
+ LR.insert({R,0});
+ if (uint32_t R = TLI.getExceptionSelectorRegister(PF))
+ LR.insert({R,0});
return LR;
}
@@ -1037,7 +1007,7 @@ void DataFlowGraph::build(unsigned Optio
// branches in the program, or fall-throughs from other blocks. They
// are entered from the exception handling runtime and target's ABI
// may define certain registers as defined on entry to such a block.
- std::vector<uint32_t> EHRegs = getLandingPadLiveIns();
+ RegisterSet EHRegs = getLandingPadLiveIns();
if (!EHRegs.empty()) {
for (NodeAddr<BlockNode*> BA : Blocks) {
const MachineBasicBlock &B = *BA.Addr->getCode();
@@ -1050,15 +1020,15 @@ void DataFlowGraph::build(unsigned Optio
Preds.push_back(findBlock(PB));
// Build phi nodes for each live-in.
- for (uint32_t R : EHRegs) {
+ for (RegisterRef RR : EHRegs) {
NodeAddr<PhiNode*> PA = newPhi(BA);
uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
// Add def:
- NodeAddr<DefNode*> DA = newDef(PA, {R,0}, PhiFlags);
+ NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
PA.Addr->addMember(DA, *this);
// Add uses (no reaching defs for phi uses):
for (NodeAddr<BlockNode*> PBA : Preds) {
- NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, {R,0}, PBA);
+ NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
PA.Addr->addMember(PUA, *this);
}
}
@@ -1130,9 +1100,9 @@ void DataFlowGraph::pushDefs(NodeAddr<In
for (NodeAddr<DefNode*> DA : Defs) {
if (Visited.count(DA.Id))
continue;
+
NodeList Rel = getRelatedRefs(IA, DA);
NodeAddr<DefNode*> PDA = Rel.front();
- // Push the definition on the stack for the register and all aliases.
RegisterRef RR = PDA.Addr->getRegRef();
#ifndef NDEBUG
// Assert if the register is defined in two or more unrelated defs.
@@ -1145,13 +1115,16 @@ void DataFlowGraph::pushDefs(NodeAddr<In
llvm_unreachable(nullptr);
}
#endif
- DefM[RR].push(DA);
- for (auto A : RAI.getAliasSet(RR)) {
+ // Push the definition on the stack for the register and all aliases.
+ // The def stack traversal in linkNodeUp will check the exact aliasing.
+ DefM[RR.Reg].push(DA);
+ for (RegisterRef A : getAliasSet(RR.Reg /*FIXME? use RegisterRef*/)) {
+ // Check that we don't push the same def twice.
assert(A != RR);
- DefM[A].push(DA);
+ DefM[A.Reg].push(DA);
}
// Mark all the related defs as visited.
- for (auto T : Rel)
+ for (NodeAddr<NodeBase*> T : Rel)
Visited.insert(T.Id);
}
}
@@ -1171,6 +1144,62 @@ NodeList DataFlowGraph::getRelatedRefs(N
return Refs;
}
+// Return true if RA and RB overlap, false otherwise.
+bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
+ // Handling of physical registers.
+ bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
+ bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
+ if (IsPhysA != IsPhysB)
+ return false;
+ if (IsPhysA) {
+ LaneBitmask LA = LMI.getLaneMaskForIndex(RA.Sub);
+ LaneBitmask LB = LMI.getLaneMaskForIndex(RB.Sub);
+
+ 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 the returned lane mask is 0, it should be treated as ~0
+ // (or the lane mask from the given register ref should be ignored).
+ // This can happen when a register has only one unit.
+ if (PA.first < PB.first || (PA.second && !(PA.second & LA)))
+ ++UMA;
+ else if (PB.first < PA.first || (PB.second && !(PB.second & LB)))
+ ++UMB;
+ else
+ return true;
+ }
+ return false;
+ }
+
+ // Handling of virtual registers.
+ bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
+ bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
+ if (IsVirtA != IsVirtB)
+ return false;
+ if (IsVirtA) {
+ if (RA.Reg != RB.Reg)
+ return false;
+ // RA and RB refer to the same register. If any of them refer to the
+ // whole register, they must be aliased.
+ if (RA.Sub == 0 || RB.Sub == 0)
+ return true;
+ unsigned SA = TRI.getSubRegIdxSize(RA.Sub);
+ unsigned OA = TRI.getSubRegIdxOffset(RA.Sub);
+ unsigned SB = TRI.getSubRegIdxSize(RB.Sub);
+ unsigned OB = TRI.getSubRegIdxOffset(RB.Sub);
+ if (OA <= OB && OA+SA > OB)
+ return true;
+ if (OB <= OA && OB+SB > OA)
+ return true;
+ return false;
+ }
+
+ return false;
+}
+
// Clear all information in the graph.
void DataFlowGraph::reset() {
@@ -1301,7 +1330,7 @@ void DataFlowGraph::buildStmt(NodeAddr<B
if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
continue;
RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() };
- if (RAI.alias(DR, UR, *this))
+ if (alias(DR, UR))
return false;
}
return true;
@@ -1407,15 +1436,15 @@ void DataFlowGraph::buildStmt(NodeAddr<B
// that block, and from all blocks dominated by it.
void DataFlowGraph::buildBlockRefs(NodeAddr<BlockNode*> BA,
BlockRefsMap &RefM) {
- auto &Refs = RefM[BA.Id];
+ RegisterSet &Refs = RefM[BA.Id];
MachineDomTreeNode *N = MDT.getNode(BA.Addr->getCode());
assert(N);
for (auto I : *N) {
MachineBasicBlock *SB = I->getBlock();
- auto SBA = findBlock(SB);
+ NodeAddr<BlockNode*> SBA = findBlock(SB);
buildBlockRefs(SBA, RefM);
- const auto &SRs = RefM[SBA.Id];
- Refs.insert(SRs.begin(), SRs.end());
+ const RegisterSet &RefsS = RefM[SBA.Id];
+ Refs.insert(RefsS.begin(), RefsS.end());
}
for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
@@ -1451,8 +1480,7 @@ void DataFlowGraph::recordDefsForDF(Bloc
Defs.insert(RA.Addr->getRegRef());
}
- // Finally, add the set of defs to each block in the iterated dominance
- // frontier.
+ // Calculate the iterated dominance frontier of BB.
const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
SetVector<MachineBasicBlock*> IDF(DF.begin(), DF.end());
for (unsigned i = 0; i < IDF.size(); ++i) {
@@ -1464,13 +1492,15 @@ void DataFlowGraph::recordDefsForDF(Bloc
// Get the register references that are reachable from this block.
RegisterSet &Refs = RefM[BA.Id];
for (auto DB : IDF) {
- auto DBA = findBlock(DB);
- const auto &Rs = RefM[DBA.Id];
- Refs.insert(Rs.begin(), Rs.end());
+ NodeAddr<BlockNode*> DBA = findBlock(DB);
+ const RegisterSet &RefsD = RefM[DBA.Id];
+ Refs.insert(RefsD.begin(), RefsD.end());
}
+ // Finally, add the set of defs to each block in the iterated dominance
+ // frontier.
for (auto DB : IDF) {
- auto DBA = findBlock(DB);
+ NodeAddr<BlockNode*> DBA = findBlock(DB);
PhiM[DBA.Id].insert(Defs.begin(), Defs.end());
}
}
@@ -1491,7 +1521,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
for (auto I : RRs)
- if (I != RR && RAI.covers(I, RR, *this))
+ if (I != RR && RegisterAggr::isCoverOf(I, RR, LMI, TRI))
RR = I;
return RR;
};
@@ -1518,18 +1548,16 @@ void DataFlowGraph::buildPhis(BlockRefsM
auto Aliased = [this,&MaxRefs](RegisterRef RR,
std::vector<unsigned> &Closure) -> bool {
for (auto I : Closure)
- if (RAI.alias(RR, MaxRefs[I], *this))
+ if (alias(RR, MaxRefs[I]))
return true;
return false;
};
// Prepare a list of NodeIds of the block's predecessors.
- std::vector<NodeId> PredList;
+ NodeList Preds;
const MachineBasicBlock *MBB = BA.Addr->getCode();
- for (auto PB : MBB->predecessors()) {
- auto B = findBlock(PB);
- PredList.push_back(B.Id);
- }
+ for (auto PB : MBB->predecessors())
+ Preds.push_back(findBlock(PB));
while (!MaxRefs.empty()) {
// Put the first element in the closure, and then add all subsequent
@@ -1553,8 +1581,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
PA.Addr->addMember(DA, *this);
}
// Add phi uses.
- for (auto P : PredList) {
- auto PBA = addr<BlockNode*>(P);
+ for (NodeAddr<BlockNode*> PBA : Preds) {
for (unsigned X = 0; X != CS; ++X) {
RegisterRef RR = MaxRefs[ClosureIdx[X]];
NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
@@ -1632,21 +1659,21 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
NodeAddr<T> TAP;
// References from the def stack that have been examined so far.
- RegisterSet Defs;
+ RegisterAggr Defs(LMI, TRI);
for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
RegisterRef QR = I->Addr->getRegRef();
- auto AliasQR = [QR,this] (RegisterRef RR) -> bool {
- return RAI.alias(QR, RR, *this);
- };
- bool PrecUp = RAI.covers(QR, RR, *this);
+
// Skip all defs that are aliased to any of the defs that we have already
- // seen. If we encounter a covering def, stop the stack traversal early.
- if (any_of(Defs, AliasQR)) {
- if (PrecUp)
+ // seen. If this completes a cover of RR, stop the stack traversal.
+ bool Alias = Defs.hasAliasOf(QR);
+ bool Cover = Defs.insert(QR).hasCoverOf(RR);
+ if (Alias) {
+ if (Cover)
break;
continue;
}
+
// The reaching def.
NodeAddr<DefNode*> RDA = *I;
@@ -1662,27 +1689,29 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
// Create the link.
TAP.Addr->linkToDef(TAP.Id, RDA);
- if (PrecUp)
+ if (Cover)
break;
- Defs.insert(QR);
}
}
// Create data-flow links for all reference nodes in the statement node SA.
void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA) {
+#ifndef NDEBUG
RegisterSet Defs;
+#endif
// Link all nodes (upwards in the data-flow) with their reaching defs.
for (NodeAddr<RefNode*> RA : SA.Addr->members(*this)) {
uint16_t Kind = RA.Addr->getKind();
assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
RegisterRef RR = RA.Addr->getRegRef();
- // Do not process multiple defs of the same reference.
- if (Kind == NodeAttrs::Def && Defs.count(RR))
- continue;
+#ifndef NDEBUG
+ // Do not expect multiple defs of the same reference.
+ assert(Kind != NodeAttrs::Def || !Defs.count(RR));
Defs.insert(RR);
+#endif
- auto F = DefM.find(RR);
+ auto F = DefM.find(RR.Reg);
if (F == DefM.end())
continue;
DefStack &DS = F->second;
@@ -1732,7 +1761,7 @@ void DataFlowGraph::linkBlockRefs(DefSta
return PUA.Addr->getPredecessor() == BA.Id;
};
- std::vector<uint32_t> EHLiveIns = getLandingPadLiveIns();
+ RegisterSet EHLiveIns = getLandingPadLiveIns();
MachineBasicBlock *MBB = BA.Addr->getCode();
for (auto SB : MBB->successors()) {
@@ -1744,14 +1773,14 @@ void DataFlowGraph::linkBlockRefs(DefSta
// Find what register this phi is for.
NodeAddr<RefNode*> RA = IA.Addr->getFirstMember(*this);
assert(RA.Id != 0);
- if (find(EHLiveIns, RA.Addr->getRegRef().Reg) != EHLiveIns.end())
+ if (EHLiveIns.count(RA.Addr->getRegRef()))
continue;
}
// Go over each phi use associated with MBB, and link it.
for (auto U : IA.Addr->members_if(IsUseForBA, *this)) {
NodeAddr<PhiUseNode*> PUA = U;
RegisterRef RR = PUA.Addr->getRegRef();
- linkRefUp<UseNode*>(IA, PUA, DefM[RR]);
+ linkRefUp<UseNode*>(IA, PUA, DefM[RR.Reg]);
}
}
}
Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Mon Oct 3 12:14:48 2016
@@ -224,6 +224,7 @@
#ifndef RDF_GRAPH_H
#define RDF_GRAPH_H
+#include "llvm/ADT/BitVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -236,6 +237,11 @@
#include <unordered_map>
#include <vector>
+// RDF uses uint32_t to refer to registers. This is to ensure that the type
+// size remains specific. In other places, registers are often stored using
+// unsigned.
+static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
+
namespace llvm {
class MachineBasicBlock;
class MachineFunction;
@@ -421,32 +427,6 @@ namespace rdf {
};
typedef std::set<RegisterRef> RegisterSet;
- struct RegisterAliasInfo {
- RegisterAliasInfo(const TargetRegisterInfo &tri) : TRI(tri) {}
- virtual ~RegisterAliasInfo() {}
-
- virtual std::vector<RegisterRef> getAliasSet(RegisterRef RR) const;
- virtual bool alias(RegisterRef RA, RegisterRef RB,
- const DataFlowGraph &DFG) const;
- virtual bool covers(RegisterRef RA, RegisterRef RB,
- const DataFlowGraph &DFG) const;
- virtual bool covers(const RegisterSet &RRs, RegisterRef RR,
- const DataFlowGraph &DFG) const;
-
- const TargetRegisterInfo &TRI;
-
- protected:
- LaneBitmask getLaneMask(RegisterRef RR, const DataFlowGraph &DFG) const;
-
- struct CommonRegister {
- CommonRegister(unsigned RegA, LaneBitmask LA,
- unsigned RegB, LaneBitmask LB,
- const TargetRegisterInfo &TRI);
- unsigned SuperReg;
- LaneBitmask MaskA, MaskB;
- };
- };
-
struct TargetOperandInfo {
TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
virtual ~TargetOperandInfo() {}
@@ -463,7 +443,7 @@ namespace rdf {
// as invalid and is never allocated.
template <typename T, unsigned N = 32>
struct IndexedSet {
- IndexedSet() : Map(N) {}
+ IndexedSet() : Map() { Map.reserve(N); }
const T get(uint32_t Idx) const {
// Index Idx corresponds to Map[Idx-1].
assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
@@ -473,7 +453,7 @@ namespace rdf {
// Linear search.
auto F = find(Map, Val);
if (F != Map.end())
- return *F;
+ return F - Map.begin();
Map.push_back(Val);
return Map.size(); // Return actual_index + 1.
}
@@ -482,6 +462,55 @@ namespace rdf {
std::vector<T> Map;
};
+ struct LaneMaskIndex : private IndexedSet<LaneBitmask> {
+ LaneBitmask getLaneMaskForIndex(uint32_t K) const {
+ return K == 0 ? ~LaneBitmask(0) : get(K);
+ }
+ uint32_t getIndexForLaneMask(LaneBitmask LM) {
+ assert(LM != LaneBitmask(0));
+ return LM == ~LaneBitmask(0) ? 0 : insert(LM);
+ }
+ };
+
+ struct RegisterAggr {
+ typedef std::pair<uint32_t,LaneBitmask> ValueType;
+
+ RegisterAggr(const LaneMaskIndex &m, const TargetRegisterInfo &tri)
+ : Masks(), ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false),
+ LMI(m), TRI(tri) {}
+ RegisterAggr(const RegisterAggr &RG)
+ : Masks(RG.Masks), ExpAliasUnits(RG.ExpAliasUnits),
+ CheckUnits(RG.CheckUnits), LMI(RG.LMI), TRI(RG.TRI) {}
+
+ bool empty() const { return Masks.empty(); }
+ bool hasAliasOf(RegisterRef RR) const;
+ bool hasCoverOf(RegisterRef RR) const;
+ static bool isCoverOf(RegisterRef RefA, RegisterRef RefB,
+ const LaneMaskIndex &LMI, const TargetRegisterInfo &TRI) {
+ return RegisterAggr(LMI, TRI).insert(RefA).hasCoverOf(RefB);
+ }
+
+ RegisterAggr &insert(RegisterRef RR);
+ RegisterAggr &insert(const RegisterAggr &RG);
+ RegisterAggr &clear(RegisterRef RR);
+
+ void print(raw_ostream &OS) const;
+
+ private:
+ typedef std::unordered_map<ValueType::first_type,
+ ValueType::second_type> MapType;
+ MapType Masks;
+ BitVector ExpAliasUnits; // Register units for explicit aliases.
+ bool CheckUnits;
+ const LaneMaskIndex &LMI;
+ const TargetRegisterInfo &TRI;
+
+ uint32_t getLargestSuperReg(uint32_t Reg) const;
+ void setMaskRaw(uint32_t Reg, LaneBitmask LM);
+ LaneBitmask composeMaskForReg(uint32_t Reg, LaneBitmask LM,
+ uint32_t SuperR) const;
+ };
+
struct NodeBase {
public:
@@ -669,8 +698,7 @@ namespace rdf {
struct DataFlowGraph {
DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
- const MachineDominanceFrontier &mdf, const RegisterAliasInfo &rai,
- const TargetOperandInfo &toi);
+ const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi);
NodeBase *ptr(NodeId N) const;
template <typename T> T ptr(NodeId N) const {
@@ -682,34 +710,14 @@ namespace rdf {
return { ptr<T>(N), N };
}
- NodeAddr<FuncNode*> getFunc() const {
- return Func;
- }
- MachineFunction &getMF() const {
- return MF;
- }
- const TargetInstrInfo &getTII() const {
- return TII;
- }
- const TargetRegisterInfo &getTRI() const {
- return TRI;
- }
- const MachineDominatorTree &getDT() const {
- return MDT;
- }
- const MachineDominanceFrontier &getDF() const {
- return MDF;
- }
- const RegisterAliasInfo &getRAI() const {
- return RAI;
- }
-
- LaneBitmask getLaneMaskForIndex(uint32_t K) const {
- return LMMap.get(K);
- }
- uint32_t getIndexForLaneMask(LaneBitmask LM) {
- return LMMap.insert(LM);
- }
+ NodeAddr<FuncNode*> getFunc() const { return Func; }
+ MachineFunction &getMF() const { return MF; }
+ LaneMaskIndex &getLMI() { return LMI; }
+ const LaneMaskIndex &getLMI() const { return LMI; }
+ const TargetInstrInfo &getTII() const { return TII; }
+ const TargetRegisterInfo &getTRI() const { return TRI; }
+ const MachineDominatorTree &getDT() const { return MDT; }
+ const MachineDominanceFrontier &getDF() const { return MDF; }
struct DefStack {
DefStack() = default;
@@ -759,14 +767,9 @@ namespace rdf {
StorageType Stack;
};
- struct RegisterRefHasher {
- unsigned operator() (RegisterRef RR) const {
- return RR.Reg | (RR.Sub << 24);
- }
- };
// Make this std::unordered_map for speed of accessing elements.
- typedef std::unordered_map<RegisterRef,DefStack,RegisterRefHasher>
- DefStackMap;
+ // Map: Register (physical or virtual) -> DefStack
+ typedef std::unordered_map<uint32_t,DefStack> DefStackMap;
void build(unsigned Options = BuildOptions::None);
void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
@@ -826,10 +829,14 @@ namespace rdf {
return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
}
+ // Register aliasing.
+ bool alias(RegisterRef RA, RegisterRef RB) const;
+
private:
void reset();
- std::vector<uint32_t> getLandingPadLiveIns() const;
+ RegisterSet getAliasSet(uint32_t Reg) const;
+ RegisterSet getLandingPadLiveIns() const;
NodeAddr<NodeBase*> newNode(uint16_t Attrs);
NodeAddr<NodeBase*> cloneNode(const NodeAddr<NodeBase*> B);
@@ -886,14 +893,13 @@ namespace rdf {
// Local map: MachineBasicBlock -> NodeAddr<BlockNode*>
std::map<MachineBasicBlock*,NodeAddr<BlockNode*>> BlockNodes;
// Lane mask map.
- IndexedSet<LaneBitmask> LMMap;
+ LaneMaskIndex LMI;
MachineFunction &MF;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
- const RegisterAliasInfo &RAI;
const TargetOperandInfo &TOI;
}; // struct DataFlowGraph
Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Mon Oct 3 12:14:48 2016
@@ -85,7 +85,7 @@ namespace rdf {
// the data-flow.
NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
- NodeAddr<RefNode*> RefA, bool FullChain, const RegisterSet &DefRRs) {
+ NodeAddr<RefNode*> RefA, bool FullChain, const RegisterAggr &DefRRs) {
NodeList RDefs; // Return value.
SetVector<NodeId> DefQ;
SetVector<NodeId> Owners;
@@ -118,8 +118,9 @@ NodeList Liveness::getAllReachingDefs(Re
continue;
// Stop at the covering/overwriting def of the initial register reference.
RegisterRef RR = TA.Addr->getRegRef();
- if (!DFG.IsPreservingDef(TA) && RAI.covers(RR, RefRR, DFG))
- continue;
+ if (!DFG.IsPreservingDef(TA))
+ if (RegisterAggr::isCoverOf(RR, RefRR, DFG.getLMI(), TRI))
+ continue;
// Get the next level of reaching defs. This will include multiple
// reaching defs for shadows.
for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
@@ -133,7 +134,7 @@ NodeList Liveness::getAllReachingDefs(Re
for (auto N : DefQ) {
auto TA = DFG.addr<DefNode*>(N);
bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
- if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef(), DFG))
+ if (!IsPhi && !DFG.alias(RefRR, TA.Addr->getRegRef()))
continue;
Defs.insert(TA.Id);
Owners.insert(TA.Addr->getOwner(DFG).Id);
@@ -195,14 +196,14 @@ NodeList Liveness::getAllReachingDefs(Re
// covered if we added A first, and A would be covered
// if we added B first.
- RegisterSet RRs = DefRRs;
+ RegisterAggr RRs(DefRRs);
auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
return TA.Addr->getKind() == NodeAttrs::Def &&
Defs.count(TA.Id);
};
for (auto T : Tmp) {
- if (!FullChain && RAI.covers(RRs, RefRR, DFG))
+ if (!FullChain && RRs.hasCoverOf(RefRR))
break;
auto TA = DFG.addr<InstrNode*>(T);
bool IsPhi = DFG.IsCode<NodeAttrs::Phi>(TA);
@@ -217,7 +218,7 @@ NodeList Liveness::getAllReachingDefs(Re
// phi d1<R3>(,d2,), ... Phi def d1 is covered by d2.
// d2<R3>(d1,,u3), ...
// ..., u3<D1>(d2) This use needs to be live on entry.
- if (FullChain || IsPhi || !RAI.covers(RRs, QR, DFG))
+ if (FullChain || IsPhi || !RRs.hasCoverOf(QR))
Ds.push_back(DA);
}
RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
@@ -240,19 +241,12 @@ NodeList Liveness::getAllReachingDefs(Re
}
-static const RegisterSet NoRegs;
-
-NodeList Liveness::getAllReachingDefs(NodeAddr<RefNode*> RefA) {
- return getAllReachingDefs(RefA.Addr->getRegRef(), RefA, false, NoRegs);
-}
-
-
NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR,
NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) {
// Collect all defined registers. Do not consider phis to be defining
// anything, only collect "real" definitions.
- RegisterSet DefRRs;
- for (const auto D : Defs) {
+ RegisterAggr DefRRs(DFG.getLMI(), TRI);
+ for (NodeId D : Defs) {
const auto DA = DFG.addr<const DefNode*>(D);
if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef))
DefRRs.insert(DA.Addr->getRegRef());
@@ -289,12 +283,12 @@ NodeSet Liveness::getAllReachingDefsRec(
NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
- NodeAddr<DefNode*> DefA, const RegisterSet &DefRRs) {
+ NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs) {
NodeSet Uses;
// If the original register is already covered by all the intervening
// defs, no more uses can be reached.
- if (RAI.covers(DefRRs, RefRR, DFG))
+ if (DefRRs.hasCoverOf(RefRR))
return Uses;
// Add all directly reached uses.
@@ -305,7 +299,7 @@ NodeSet Liveness::getAllReachedUses(Regi
auto UA = DFG.addr<UseNode*>(U);
if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
auto UR = UA.Addr->getRegRef();
- if (RAI.alias(RefRR, UR, DFG) && !RAI.covers(DefRRs, UR, DFG))
+ if (DFG.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
Uses.insert(U);
}
U = UA.Addr->getSibling();
@@ -318,14 +312,14 @@ NodeSet Liveness::getAllReachedUses(Regi
auto DR = DA.Addr->getRegRef();
// If this def is already covered, it cannot reach anything new.
// Similarly, skip it if it is not aliased to the interesting register.
- if (RAI.covers(DefRRs, DR, DFG) || !RAI.alias(RefRR, DR, DFG))
+ if (DefRRs.hasCoverOf(DR) || !DFG.alias(RefRR, DR))
continue;
NodeSet T;
if (DFG.IsPreservingDef(DA)) {
// If it is a preserving def, do not update the set of intervening defs.
T = getAllReachedUses(RefRR, DA, DefRRs);
} else {
- RegisterSet NewDefRRs = DefRRs;
+ RegisterAggr NewDefRRs = DefRRs;
NewDefRRs.insert(DR);
T = getAllReachedUses(RefRR, DA, NewDefRRs);
}
@@ -347,21 +341,21 @@ void Liveness::computePhiInfo() {
}
// phi use -> (map: reaching phi -> set of registers defined in between)
- std::map<NodeId,std::map<NodeId,RegisterSet>> PhiUp;
+ std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
std::vector<NodeId> PhiUQ; // Work list of phis for upward propagation.
// Go over all phis.
for (NodeAddr<PhiNode*> PhiA : Phis) {
// Go over all defs and collect the reached uses that are non-phi uses
// (i.e. the "real uses").
- auto &RealUses = RealUseMap[PhiA.Id];
- auto PhiRefs = PhiA.Addr->members(DFG);
+ RefMap &RealUses = RealUseMap[PhiA.Id];
+ NodeList PhiRefs = PhiA.Addr->members(DFG);
// Have a work queue of defs whose reached uses need to be found.
// For each def, add to the queue all reached (non-phi) defs.
SetVector<NodeId> DefQ;
NodeSet PhiDefs;
- for (auto R : PhiRefs) {
+ for (NodeAddr<RefNode*> R : PhiRefs) {
if (!DFG.IsRef<NodeAttrs::Def>(R))
continue;
DefQ.insert(R.Id);
@@ -466,12 +460,17 @@ void Liveness::computePhiInfo() {
for (NodeAddr<UseNode*> VA : DFG.getRelatedRefs(PhiA, UA)) {
SeenUses.insert(VA.Id);
- RegisterSet DefRRs;
+ RegisterAggr DefRRs(DFG.getLMI(), TRI);
for (NodeAddr<DefNode*> DA : getAllReachingDefs(VA)) {
if (DA.Addr->getFlags() & NodeAttrs::PhiRef) {
NodeId RP = DA.Addr->getOwner(DFG).Id;
NodeId FU = FirstUse.insert({RP,VA.Id}).first->second;
- PhiUp[FU][RP].insert(DefRRs.begin(), DefRRs.end());
+ std::map<NodeId,RegisterAggr> &M = PhiUp[FU];
+ auto F = M.find(RP);
+ if (F == M.end())
+ M.insert(std::make_pair(RP, DefRRs));
+ else
+ F->second.insert(DefRRs);
}
DefRRs.insert(DA.Addr->getRegRef());
}
@@ -485,7 +484,7 @@ void Liveness::computePhiInfo() {
dbgs() << "phi " << Print<NodeId>(I.first, DFG) << " -> {";
for (auto R : I.second)
dbgs() << ' ' << Print<NodeId>(R.first, DFG)
- << Print<RegisterSet>(R.second, DFG);
+ << Print<RegisterAggr>(R.second, DFG);
dbgs() << " }\n";
}
}
@@ -520,10 +519,10 @@ void Liveness::computePhiInfo() {
for (auto U : PUs) {
NodeAddr<UseNode*> UA = U;
- std::map<NodeId,RegisterSet> &PUM = PhiUp[UA.Id];
- for (const std::pair<NodeId,RegisterSet> &P : PUM) {
+ std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
+ for (const std::pair<NodeId,RegisterAggr> &P : PUM) {
bool Changed = false;
- RegisterSet MidDefs = P.second;
+ const RegisterAggr &MidDefs = P.second;
// Collect the set UpReached of uses that are reached by the current
// phi PA, and are not covered by any intervening def between PA and
@@ -533,7 +532,7 @@ void Liveness::computePhiInfo() {
RegisterRef R = T.first;
if (!isRestrictedToRef(PA, UA, R))
R = getRestrictedRegRef(UA);
- if (!RAI.covers(MidDefs, R, DFG))
+ if (!MidDefs.hasCoverOf(R))
UpReached.insert(R);
}
if (UpReached.empty())
@@ -654,7 +653,7 @@ void Liveness::computeLiveIns() {
// The restricted ref may be different from the ref that was
// accessed in the "real use". This means that this phi use
// is not the one that carries this reference, so skip it.
- if (!RAI.alias(R.first, RR, DFG))
+ if (!DFG.alias(R.first, RR))
continue;
for (auto D : getAllReachingDefs(RR, UA))
LOX[RR].insert(D.Id);
@@ -787,7 +786,7 @@ bool Liveness::isRestrictedToRef(NodeAdd
NodeId RD = TA.Addr->getReachingDef();
if (RD == 0)
continue;
- if (RAI.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef(), DFG))
+ if (DFG.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef()))
return false;
}
return true;
@@ -805,13 +804,6 @@ RegisterRef Liveness::getRestrictedRegRe
}
-unsigned Liveness::getPhysReg(RegisterRef RR) const {
- if (!TargetRegisterInfo::isPhysicalRegister(RR.Reg))
- return 0;
- return RR.Sub ? TRI.getSubReg(RR.Reg, RR.Sub) : RR.Reg;
-}
-
-
// Helper function to obtain the basic block containing the reaching def
// of the given use.
MachineBasicBlock *Liveness::getBlockWithRef(NodeId RN) const {
@@ -899,13 +891,15 @@ void Liveness::traverse(MachineBasicBloc
else {
bool IsPreserving = DFG.IsPreservingDef(DA);
if (IA.Addr->getKind() != NodeAttrs::Phi && !IsPreserving) {
- bool Covering = RAI.covers(DDR, I.first, DFG);
+ bool Covering = RegisterAggr::isCoverOf(DDR, I.first,
+ DFG.getLMI(), TRI);
NodeId U = DA.Addr->getReachedUse();
while (U && Covering) {
auto DUA = DFG.addr<UseNode*>(U);
if (!(DUA.Addr->getFlags() & NodeAttrs::Undef)) {
RegisterRef Q = DUA.Addr->getRegRef();
- Covering = RAI.covers(DA.Addr->getRegRef(), Q, DFG);
+ Covering = RegisterAggr::isCoverOf(DA.Addr->getRegRef(), Q,
+ DFG.getLMI(), TRI);
}
U = DUA.Addr->getSibling();
}
@@ -919,7 +913,7 @@ void Liveness::traverse(MachineBasicBloc
for (auto R : Rest) {
auto DA = DFG.addr<DefNode*>(R);
RegisterRef DRR = DA.Addr->getRegRef();
- RegisterSet RRs;
+ RegisterAggr RRs(DFG.getLMI(), TRI);
for (NodeAddr<DefNode*> TA : getAllReachingDefs(DA)) {
NodeAddr<InstrNode*> IA = TA.Addr->getOwner(DFG);
NodeAddr<BlockNode*> BA = IA.Addr->getOwner(DFG);
@@ -928,7 +922,7 @@ void Liveness::traverse(MachineBasicBloc
RRs.insert(TA.Addr->getRegRef());
if (BA.Addr->getCode() == B)
continue;
- if (RAI.covers(RRs, DRR, DFG))
+ if (RRs.hasCoverOf(DRR))
break;
Defs.insert(TA.Id);
}
Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.h?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.h Mon Oct 3 12:14:48 2016
@@ -35,15 +35,24 @@ namespace rdf {
Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
: DFG(g), TRI(g.getTRI()), MDT(g.getDT()), MDF(g.getDF()),
- RAI(g.getRAI()), MRI(mri), Empty(), Trace(false) {}
+ MRI(mri), Empty(), NoRegs(g.getLMI(), g.getTRI()),
+ Trace(false) {}
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
- bool FullChain = false, const RegisterSet &DefRRs = RegisterSet());
- NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA);
+ bool FullChain, const RegisterAggr &DefRRs);
+ NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
+ return getAllReachingDefs(RefA.Addr->getRegRef(), RefA, false, NoRegs);
+ }
+ NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
+ return getAllReachingDefs(RefRR, RefA, false, NoRegs);
+ }
NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
NodeSet &Visited, const NodeSet &Defs);
NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
- const RegisterSet &DefRRs = RegisterSet());
+ const RegisterAggr &DefRRs);
+ NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
+ return getAllReachedUses(RefRR, DefA, NoRegs);
+ }
LiveMapType &getLiveMap() { return LiveMap; }
const LiveMapType &getLiveMap() const { return LiveMap; }
@@ -65,10 +74,10 @@ namespace rdf {
const TargetRegisterInfo &TRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
- const RegisterAliasInfo &RAI;
MachineRegisterInfo &MRI;
LiveMapType LiveMap;
const RefMap Empty;
+ const RegisterAggr NoRegs;
bool Trace;
// Cache of mapping from node ids (for RefNodes) to the containing
@@ -99,7 +108,6 @@ namespace rdf {
bool isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
RegisterRef RR) const;
RegisterRef getRestrictedRegRef(NodeAddr<RefNode*> RA) const;
- unsigned getPhysReg(RegisterRef RR) const;
MachineBasicBlock *getBlockWithRef(NodeId RN) const;
void traverse(MachineBasicBlock *B, RefMap &LiveIn);
void emptify(RefMap &M);
More information about the llvm-commits
mailing list