[PATCH] D50849: [llvm-mca] Refactor how execution is orchestrated by the Pipeline. NFCI

Andrea Di Biagio via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 16 10:04:08 PDT 2018


andreadb created this revision.
andreadb added reviewers: mattd, courbet, gchatelet, RKSimon.
Herald added subscribers: gbedwell, tschuett.

This patch changes how instruction execution is orchestrated by the Pipeline.

In particular, this patch makes it more explicit how instructions transition through the various pipeline stages during execution.

The main goal is to simplify the stage API and simpify the Pipeline execution. At the same time, this patch fixes some issues which are currently latent, but that are likely to cause problems in future if people define custom pipelines.

The new design assumes that each pipeline stage knows the "next-in-sequence".
The Stage API has gained two new methods:

- `isAvailable(IR)`
- `checkNextStage(IR)`
- `moveToTheNextStage(IR)`.

An instruction IR can be executed by a Stage if method `Stage::isAvailable(IR)` returns true.
Stage may accept a limited number of instructions per cycle. So, method `isAvailable(IR)` is responsible for checking if instruction IR can execute within the current cycle.

Instructions can move to next stages using method `moveToTheNextStage(IR)`.
An instruction cannot be moved to the next stage if method `checkNextStage(IR)` (called on the current stage) returns false.

Instruction IR may be allowed to transition through multiple stages in a single cycle, provided that stages are available, and that `checkNextStage(IR)` always returns true.

Since now stages know about their "next-in-sequence", some methods in the Stage interface have become now redundant. For example, this patch gets rid of `Stage::preExecute()` and `Stage::postExecute()`.

Method `Pipeline::runCycle()` is now much simpler, and it correctly visits stages in post-order at the beginning/end of a cycle. Before, this caused an issue with the sequence of stages in the default pipeline; that issue is now fixed.

Other changes:

1. DispatchStage no longer requires a reference to the Scheduler.
2. ExecuteStage no longer needs to directly interact with the RetireControlUnit. Instead, executed instructions are now directly moved to the next stage (i.e. the retire stage).
3. RetireStage gained an execute method. This allowed us to remove the dependency with the RCU in ExecuteStage.
4. FecthStage now updates the "program counter" during `cycleBegin()` (i.e. before we start executing new instructions).
5. We no longer need Stage::Status to be returned by method `execute()`. It has been dropped in favor of a more lightweight llvm::Error.

With this change, the Pipeline logic is simplified. We no longer generate extra calls to pre/postExecute() every instruction. We also avoid redundant `execute(IR)` calls on stages that are not reached by IR (that was an oddity of the previous design).

Overally, when testing a debug build of llvm-mca, I measured a ~11% performance gain w.r.t. the previous design. I also think that the Stage interface is probably easier to read now. That being said, code comments have to be improved (I plan to do it in a follow-up patch).

Please let me know if okay to commit.

-Andrea


https://reviews.llvm.org/D50849

Files:
  tools/llvm-mca/Context.cpp
  tools/llvm-mca/DispatchStage.cpp
  tools/llvm-mca/DispatchStage.h
  tools/llvm-mca/ExecuteStage.cpp
  tools/llvm-mca/ExecuteStage.h
  tools/llvm-mca/FetchStage.cpp
  tools/llvm-mca/FetchStage.h
  tools/llvm-mca/InstructionTables.cpp
  tools/llvm-mca/InstructionTables.h
  tools/llvm-mca/Pipeline.cpp
  tools/llvm-mca/Pipeline.h
  tools/llvm-mca/RetireStage.cpp
  tools/llvm-mca/RetireStage.h
  tools/llvm-mca/Stage.h

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D50849.161045.patch
Type: text/x-patch
Size: 24064 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180816/cfb1e3bd/attachment.bin>


More information about the llvm-commits mailing list