[llvm] MTM: improve operand latency when missing sched info (PR #101389)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 8 07:53:23 PDT 2024


================
@@ -761,6 +762,64 @@ static void updatePhysDepsDownwards(const MachineInstr *UseMI,
   }
 }
 
+/// Estimates the number of cycles elapsed between DefMI and UseMI if they're
+/// non-null and in the same BasicBlock. Returns std::nullopt when UseMI is in a
+/// different MBB than DefMI.
+static std::optional<unsigned>
+estimateDefUseCycles(const TargetSchedModel &Sched, const MachineInstr *DefMI,
+                     const MachineInstr *UseMI) {
+  if (!DefMI || !UseMI || DefMI == UseMI)
+    return 0;
+  const MachineBasicBlock *ParentBB = DefMI->getParent();
+  if (ParentBB != UseMI->getParent())
+    return std::nullopt;
+
+  const auto DefIt =
+      llvm::find_if(ParentBB->instrs(),
+                    [DefMI](const MachineInstr &MI) { return DefMI == &MI; });
+  const auto UseIt =
+      llvm::find_if(ParentBB->instrs(),
+                    [UseMI](const MachineInstr &MI) { return UseMI == &MI; });
+
+  unsigned NumMicroOps = 0;
+  for (auto It = DefIt; It != UseIt; ++It) {
+    // In cases where the UseMI is a PHI at the beginning of the MBB, compute
+    // MicroOps until the end of the MBB.
+    if (It.isEnd())
+      break;
+
+    NumMicroOps += Sched.getNumMicroOps(&*It);
+  }
+  return NumMicroOps / Sched.getIssueWidth();
----------------
michaelmaitland wrote:

We have a loop that iterates over instructions between `DefMI` and `UseMI`:

```
for (auto It = DefIt; It != UseIt; ++It) {
    // In cases where the UseMI is a PHI at the beginning of the MBB, compute
    // MicroOps until the end of the MBB.
    if (It.isEnd())
      break;

    NumMicroOps += Sched.getNumMicroOps(&*It);
  }
```

I suggest the following scenario:
```
defmi = ...
a = ...
b = use a
usemi = ...
```
In this case, we will be looping over instructions `a` and `b` and adding their number of micro ops to calculate the number of cycles elapsed between `defmi` and `usemi`.

Let's take the assumption that `a` has default def latency of N cycles and `b` has default latency of M cycles.

> What do you mean by "instructions that depends on each other"?

In my scenario, `b` uses the result of `a`. It cannot start until that result is ready. If we want to make it concrete, we could imagine that it looks like this:

```
a = add 3, 2
b = sub a, 2
```

We cannot start the subtraction until `a` is finished calculating. This is what I am calling a dependency. We can assume for sake of simplicity here that `a` and `b` are independent from `defmi` and `usemi`.

In this scenario, I am suggesting that if the default latency of a is larger than the number of micro-ops, then we must wait at least the default latency of `a` before starting `b`. I suggest that we can incorporate this into the estimation.



https://github.com/llvm/llvm-project/pull/101389


More information about the llvm-commits mailing list