[llvm] [MCP] Move dependencies if they block copy propagation (PR #105562)
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 22 12:01:04 PDT 2024
================
@@ -92,6 +106,113 @@ static cl::opt<cl::boolOrDefault>
EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden);
namespace {
+// A ScheduleDAG subclass that is used as a dependency graph.
+class ScheduleDAGMCP : public ScheduleDAGInstrs {
+public:
+ void schedule() override {
+ llvm_unreachable("This schedule dag is only used as a dependency graph for "
+ "Machine Copy Propagation\n");
+ }
+
+ ScheduleDAGMCP(MachineFunction &MF, const MachineLoopInfo *MLI,
+ bool RemoveKillFlags = false)
+ : ScheduleDAGInstrs(MF, MLI, RemoveKillFlags) {
+ CanHandleTerminators = true;
+ }
+};
+
+static std::optional<llvm::SmallVector<MachineInstr *>>
+moveInstructionsOutOfTheWayIfWeCan(SUnit *Dst, SUnit *Src) {
+ MachineInstr *DstInstr = Dst->getInstr();
+ MachineInstr *SrcInstr = Src->getInstr();
+ MachineBasicBlock *MBB = SrcInstr->getParent();
+
+ if (DstInstr == nullptr || SrcInstr == nullptr)
+ return {};
+ assert("This function only operates on a basic block level." &&
+ MBB == SrcInstr->getParent());
+
+ int SectionSize =
+ std::distance(SrcInstr->getIterator(), DstInstr->getIterator());
+
+ // The bit vector representing the instructions in the section.
+ // This vector stores which instruction needs to be moved and which does not.
+ BitVector SectionInstr(SectionSize, false);
+
+ // The queue for the breadth first search.
+ std::queue<const SUnit *> Edges;
+
+ // Process the children of a node.
+ // Basically every node are checked before it is being put into the queue.
+ // A node is enqueued if it has no dependencies on the source of the copy
+ // (only if we are not talking about the destination node which is a special
+ // case indicated by a flag) and is located between the source of the copy and
+ // the destination of the copy.
+ auto ProcessSNodeChildren = [SrcInstr, &SectionSize, &SectionInstr](
+ std::queue<const SUnit *> &Queue,
+ const SUnit *Node, bool IsRoot) -> bool {
+ for (llvm::SDep I : Node->Preds) {
+ SUnit *SU = I.getSUnit();
+ MachineInstr &MI = *(SU->getInstr());
+ if (!IsRoot && &MI == SrcInstr)
+ return false;
----------------
qcolombet wrote:
Should we dequeue any of the unit pushed?
(I don't understand what the queue is used for yet, but it feels weird that depending on how the `Node->Preds` is ordered we enqueue potentially different things.)
For instance, let's say we have two SUnit in Node->Preds and one of them is SrcInstr.
If SrcInstr is viewed first, the queue will be left untouched, but if it is seen last then the queue may have some additional entries.
https://github.com/llvm/llvm-project/pull/105562
More information about the llvm-commits
mailing list