summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/RDFGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFGraph.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/RDFGraph.cpp102
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)) {
OpenPOWER on IntegriCloud