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.cpp59
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.
OpenPOWER on IntegriCloud