diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-09-22 21:01:24 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-09-22 21:01:24 +0000 |
commit | 29e93f3880f4c6e02727637b35c79ea08997b30b (patch) | |
tree | e2a51872f320e4b632fa65daa277cbbfd019625b /llvm/lib/Target/Hexagon/RDFGraph.cpp | |
parent | e68df598f595fb0e6b1162a3b3130ed8ddd5de7e (diff) | |
download | bcm5719-llvm-29e93f3880f4c6e02727637b35c79ea08997b30b.tar.gz bcm5719-llvm-29e93f3880f4c6e02727637b35c79ea08997b30b.zip |
[RDF] Add initial support for lane masks in the DFG
Use lane masks for calculating covering and aliasing of register
references.
llvm-svn: 282194
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFGraph.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFGraph.cpp | 102 |
1 files changed, 70 insertions, 32 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFGraph.cpp b/llvm/lib/Target/Hexagon/RDFGraph.cpp index bea9a837127..dd39dcfdb1c 100644 --- a/llvm/lib/Target/Hexagon/RDFGraph.cpp +++ b/llvm/lib/Target/Hexagon/RDFGraph.cpp @@ -580,14 +580,47 @@ NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) { // Register aliasing information. // -// In theory, the lane information could be used to determine register -// covering (and aliasing), but depending on the sub-register structure, -// the lane mask information may be missing. The covering information -// must be available for this framework to work, so relying solely on -// the lane data is not sufficient. + +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 { +bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB, + const DataFlowGraph &DFG) const { if (RA == RB) return true; if (TargetRegisterInfo::isVirtualRegister(RA.Reg)) { @@ -601,13 +634,17 @@ bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const { assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg) && TargetRegisterInfo::isPhysicalRegister(RB.Reg)); - uint32_t A = RA.Sub != 0 ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg; - uint32_t B = RB.Sub != 0 ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg; - return TRI.isSubRegister(A, B); + + 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 { +bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR, + const DataFlowGraph &DFG) const { if (RRs.count(RR)) return true; @@ -630,7 +667,7 @@ bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR) const { return false; } -// Get the list of references aliased to RR. +// 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. @@ -648,16 +685,17 @@ std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const { } // Check whether RA and RB are aliased. -bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const { - bool VirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg); - bool VirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg); - bool PhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg); - bool PhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg); - - if (VirtA != VirtB) +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 (VirtA) { + if (IsVirtA) { if (RA.Reg != RB.Reg) return false; // RA and RB refer to the same register. If any of them refer to the @@ -675,14 +713,14 @@ bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const { return false; } - assert(PhysA && PhysB); - (void)PhysA, (void)PhysB; - uint32_t A = RA.Sub ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg; - uint32_t B = RB.Sub ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg; - for (MCRegAliasIterator I(A, &TRI, true); I.isValid(); ++I) - if (B == *I) - 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; } @@ -1213,7 +1251,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) { if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef()) continue; RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() }; - if (RAI.alias(DR, UR)) + if (RAI.alias(DR, UR, *this)) return false; } return true; @@ -1398,7 +1436,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM, auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef { for (auto I : RRs) - if (I != RR && RAI.covers(I, RR)) + if (I != RR && RAI.covers(I, RR, *this)) RR = I; return RR; }; @@ -1425,7 +1463,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM, auto Aliased = [this,&MaxRefs](RegisterRef RR, std::vector<unsigned> &Closure) -> bool { for (auto I : Closure) - if (RAI.alias(RR, MaxRefs[I])) + if (RAI.alias(RR, MaxRefs[I], *this)) return true; return false; }; @@ -1544,9 +1582,9 @@ void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA, 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); + return RAI.alias(QR, RR, *this); }; - bool PrecUp = RAI.covers(QR, RR); + 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)) { |