[llvm] 39ab9da - [RDF] Create build config

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 14 15:34:51 PDT 2023


Author: Krzysztof Parzyszek
Date: 2023-06-14T15:34:24-07:00
New Revision: 39ab9da92058719240f072dbe5a6e09812501db4

URL: https://github.com/llvm/llvm-project/commit/39ab9da92058719240f072dbe5a6e09812501db4
DIFF: https://github.com/llvm/llvm-project/commit/39ab9da92058719240f072dbe5a6e09812501db4.diff

LOG: [RDF] Create build config

- Add option to ignore reserved registers
- Add possibility to track selected registers or register classes only

Tracking is done based on register units, so the set of registers to track
is translated into a set of register units.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/RDFGraph.h
    llvm/lib/CodeGen/RDFGraph.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/RDFGraph.h b/llvm/include/llvm/CodeGen/RDFGraph.h
index b2d6d16e2d5bb..cf7344e8c3e74 100644
--- a/llvm/include/llvm/CodeGen/RDFGraph.h
+++ b/llvm/include/llvm/CodeGen/RDFGraph.h
@@ -225,6 +225,7 @@
 #define LLVM_CODEGEN_RDFGRAPH_H
 
 #include "RDFRegisters.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/LaneBitmask.h"
 #include "llvm/Support/Allocator.h"
@@ -336,6 +337,7 @@ struct BuildOptions {
   enum : unsigned {
     None = 0x00,
     KeepDeadPhis = 0x01, // Do not remove dead phis during build.
+    OmitReserved = 0x02, // Do not track reserved registers.
   };
 };
 
@@ -664,6 +666,19 @@ struct DataFlowGraph {
                 const MachineDominanceFrontier &mdf,
                 const TargetOperandInfo &toi);
 
+  struct Config {
+    Config() = default;
+    Config(unsigned Opts) : Options(Opts) {}
+    Config(ArrayRef<const TargetRegisterClass *> RCs) : Classes(RCs) {}
+    Config(ArrayRef<MCPhysReg> Track) : TrackRegs(Track.begin(), Track.end()) {}
+    Config(ArrayRef<RegisterId> Track)
+        : TrackRegs(Track.begin(), Track.end()) {}
+
+    unsigned Options = BuildOptions::None;
+    SmallVector<const TargetRegisterClass *> Classes;
+    std::set<RegisterId> TrackRegs;
+  };
+
   NodeBase *ptr(NodeId N) const;
   template <typename T> T ptr(NodeId N) const { //
     return static_cast<T>(ptr(N));
@@ -756,7 +771,9 @@ struct DataFlowGraph {
   // Map: Register (physical or virtual) -> DefStack
   using DefStackMap = std::unordered_map<RegisterId, DefStack>;
 
-  void build(unsigned Options = BuildOptions::None);
+  void build(const Config &config);
+  void build() { build(Config()); }
+
   void pushAllDefs(Instr IA, DefStackMap &DM);
   void markBlock(NodeId B, DefStackMap &DefM);
   void releaseBlock(NodeId B, DefStackMap &DefM);
@@ -793,6 +810,9 @@ struct DataFlowGraph {
       removeFromOwner(DA);
   }
 
+  bool isTracked(RegisterRef RR) const;
+  bool hasUntrackedRef(Stmt S, bool IgnoreReserved = true) const;
+
   // Some useful filters.
   template <uint16_t Kind> static bool IsRef(const Node BA) {
     return BA.Addr->getType() == NodeAttrs::Ref && BA.Addr->getKind() == Kind;
@@ -882,6 +902,10 @@ struct DataFlowGraph {
   std::map<MachineBasicBlock *, Block> BlockNodes;
   // Lane mask map.
   LaneMaskIndex LMI;
+
+  Config BuildCfg;
+  std::set<unsigned> TrackedUnits;
+  BitVector ReservedRegs;
 }; // struct DataFlowGraph
 
 template <typename Predicate>

diff  --git a/llvm/lib/CodeGen/RDFGraph.cpp b/llvm/lib/CodeGen/RDFGraph.cpp
index ece51eae5dd65..abf3b1e6fbb9e 100644
--- a/llvm/lib/CodeGen/RDFGraph.cpp
+++ b/llvm/lib/CodeGen/RDFGraph.cpp
@@ -855,8 +855,43 @@ Func DataFlowGraph::newFunc(MachineFunction *MF) {
 }
 
 // Build the data flow graph.
-void DataFlowGraph::build(unsigned Options) {
+void DataFlowGraph::build(const Config &config) {
   reset();
+  BuildCfg = config;
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  ReservedRegs = MRI.getReservedRegs();
+  bool SkipReserved = BuildCfg.Options & BuildOptions::OmitReserved;
+
+  auto Insert = [](auto &Set, auto &&Range) {
+    Set.insert(Range.begin(), Range.end());
+  };
+
+  if (BuildCfg.TrackRegs.empty()) {
+    std::set<RegisterId> BaseSet;
+    if (BuildCfg.Classes.empty()) {
+      // Insert every register.
+      for (unsigned R = 0, E = getPRI().getTRI().getNumRegs(); R != E; ++R)
+        BaseSet.insert(R);
+    } else {
+      for (const TargetRegisterClass *RC : BuildCfg.Classes) {
+        for (MCPhysReg R : *RC)
+          BaseSet.insert(R);
+      }
+    }
+    for (RegisterId R : BaseSet) {
+      if (SkipReserved && ReservedRegs[R])
+        continue;
+      Insert(TrackedUnits, getPRI().getUnits(RegisterRef(R)));
+    }
+  } else {
+    // Track set in Config overrides everything.
+    for (unsigned R : BuildCfg.TrackRegs) {
+      if (SkipReserved && ReservedRegs[R])
+        continue;
+      Insert(TrackedUnits, getPRI().getUnits(RegisterRef(R)));
+    }
+  }
+
   TheFunc = newFunc(&MF);
 
   if (MF.empty())
@@ -876,7 +911,6 @@ void DataFlowGraph::build(unsigned Options) {
   NodeList Blocks = TheFunc.Addr->members(*this);
 
   // Collect function live-ins and entry block live-ins.
-  MachineRegisterInfo &MRI = MF.getRegInfo();
   MachineBasicBlock &EntryB = *EA.Addr->getCode();
   assert(EntryB.pred_empty() && "Function entry block has predecessors");
   for (std::pair<unsigned, unsigned> P : MRI.liveins())
@@ -888,6 +922,8 @@ void DataFlowGraph::build(unsigned Options) {
 
   // Add function-entry phi nodes for the live-in registers.
   for (RegisterRef RR : LiveIns.refs()) {
+    if (RR.isReg() && !isTracked(RR)) // isReg is likely guaranteed
+      continue;
     Phi PA = newPhi(EA);
     uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
     Def DA = newDef(PA, RR, PhiFlags);
@@ -913,6 +949,8 @@ void DataFlowGraph::build(unsigned Options) {
 
       // Build phi nodes for each live-in.
       for (RegisterRef RR : EHRegs.refs()) {
+        if (RR.isReg() && !isTracked(RR))
+          continue;
         Phi PA = newPhi(BA);
         uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
         // Add def:
@@ -940,7 +978,7 @@ void DataFlowGraph::build(unsigned Options) {
   linkBlockRefs(DM, EA);
 
   // Finally, remove all unused phi nodes.
-  if (!(Options & BuildOptions::KeepDeadPhis))
+  if (!(BuildCfg.Options & BuildOptions::KeepDeadPhis))
     removeUnusedPhis();
 }
 
@@ -1024,6 +1062,8 @@ void DataFlowGraph::pushClobbers(Instr IA, DefStackMap &DefM) {
     DefM[RR.Reg].push(DA);
     Defined.insert(RR.Reg);
     for (RegisterId A : getPRI().getAliasSet(RR.Reg)) {
+      if (RegisterRef::isRegId(A) && !isTracked(RegisterRef(A)))
+        continue;
       // Check that we don't push the same def twice.
       assert(A != RR.Reg);
       if (!Defined.count(A))
@@ -1079,6 +1119,8 @@ void DataFlowGraph::pushDefs(Instr IA, DefStackMap &DefM) {
     // The def stack traversal in linkNodeUp will check the exact aliasing.
     DefM[RR.Reg].push(DA);
     for (RegisterId A : getPRI().getAliasSet(RR.Reg)) {
+      if (RegisterRef::isRegId(A) && !isTracked(RegisterRef(A)))
+        continue;
       // Check that we don't push the same def twice.
       assert(A != RR.Reg);
       DefM[A].push(DA);
@@ -1107,6 +1149,8 @@ NodeList DataFlowGraph::getRelatedRefs(Instr IA, Ref RA) const {
 void DataFlowGraph::reset() {
   Memory.clear();
   BlockNodes.clear();
+  TrackedUnits.clear();
+  ReservedRegs.clear();
   TheFunc = Func();
 }
 
@@ -1245,7 +1289,7 @@ void DataFlowGraph::buildStmt(Block BA, MachineInstr &In) {
     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
       continue;
     Register R = Op.getReg();
-    if (!R || !R.isPhysical())
+    if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)))
       continue;
     uint16_t Flags = NodeAttrs::None;
     if (TOI.isPreserving(In, OpN)) {
@@ -1277,9 +1321,12 @@ void DataFlowGraph::buildStmt(Block BA, MachineInstr &In) {
     SA.Addr->addMember(DA, *this);
     // Record all clobbered registers in DoneDefs.
     const uint32_t *RM = Op.getRegMask();
-    for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i)
+    for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
+      if (!isTracked(RegisterRef(i)))
+        continue;
       if (!(RM[i / 32] & (1u << (i % 32))))
         DoneClobbers.set(i);
+    }
   }
 
   // Process implicit defs, skipping those that have already been added
@@ -1289,7 +1336,7 @@ void DataFlowGraph::buildStmt(Block BA, MachineInstr &In) {
     if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
       continue;
     Register R = Op.getReg();
-    if (!R || !R.isPhysical() || DoneDefs.test(R))
+    if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)) || DoneDefs.test(R))
       continue;
     RegisterRef RR = makeRegRef(Op);
     uint16_t Flags = NodeAttrs::None;
@@ -1318,7 +1365,7 @@ void DataFlowGraph::buildStmt(Block BA, MachineInstr &In) {
     if (!Op.isReg() || !Op.isUse())
       continue;
     Register R = Op.getReg();
-    if (!R || !R.isPhysical())
+    if (!R || !R.isPhysical() || !isTracked(RegisterRef(R)))
       continue;
     uint16_t Flags = NodeAttrs::None;
     if (Op.isUndef())
@@ -1348,9 +1395,13 @@ void DataFlowGraph::recordDefsForDF(BlockRefsMap &PhiM, Block BA) {
   // This is done to make sure that each defined reference gets only one
   // phi node, even if it is defined multiple times.
   RegisterAggr Defs(getPRI());
-  for (Instr IA : BA.Addr->members(*this))
-    for (Ref RA : IA.Addr->members_if(IsDef, *this))
-      Defs.insert(RA.Addr->getRegRef(*this));
+  for (Instr IA : BA.Addr->members(*this)) {
+    for (Ref RA : IA.Addr->members_if(IsDef, *this)) {
+      RegisterRef RR = RA.Addr->getRegRef(*this);
+      if (RR.isReg() && isTracked(RR))
+        Defs.insert(RR);
+    }
+  }
 
   // Calculate the iterated dominance frontier of BB.
   const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
@@ -1721,4 +1772,28 @@ void DataFlowGraph::unlinkDefDF(Def DA) {
   }
 }
 
+bool DataFlowGraph::isTracked(RegisterRef RR) const {
+  return !disjoint(getPRI().getUnits(RR), TrackedUnits);
+}
+
+bool DataFlowGraph::hasUntrackedRef(Stmt S, bool IgnoreReserved) const {
+  SmallVector<MachineOperand *> Ops;
+
+  for (Ref R : S.Addr->members(*this)) {
+    Ops.push_back(&R.Addr->getOp());
+    RegisterRef RR = R.Addr->getRegRef(*this);
+    if (IgnoreReserved && RR.isReg() && ReservedRegs[RR.idx()])
+      continue;
+    if (!isTracked(RR))
+      return true;
+  }
+  for (const MachineOperand &Op : S.Addr->getCode()->operands()) {
+    if (!Op.isReg() && !Op.isRegMask())
+      continue;
+    if (llvm::find(Ops, &Op) == Ops.end())
+      return true;
+  }
+  return false;
+}
+
 } // end namespace llvm::rdf


        


More information about the llvm-commits mailing list