[PATCH] D40333: Separate LoopTraversal and BreakFalseDeps out of ExecutionDomainFix into their own files

Matthias Braun via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 27 14:05:54 PST 2017


MatzeB added a comment.

Some comments on the software engineering side, I didn't really look into the dependency breaking algorithms yet.



================
Comment at: include/llvm/CodeGen/BreakFalseDeps.h:36
+
+class BreakFalseDeps : public MachineFunctionPass, LoopTraversal {
+private:
----------------
This is probably a bad use of inheritance. Saying "BreakFalseDeps is a LoopTraversal" feels odd. I believe this could be rewritten so that LoopTraversal is subclassed separately inside BreakFalseDeps.cpp without making it a supertype of BreakFalseDeps itself.


================
Comment at: include/llvm/CodeGen/BreakFalseDeps.h:82
+private:
+  // Dependency breaking.
+  bool pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
----------------
It's usually easiest to just document the functions with `///` doxygen comments instead of forming groups of methods.

If you really want to form groups, the correct doxygen syntax would be:
```
/// \name Dependency Breaking
/// \{
...
/// \}
```



================
Comment at: include/llvm/CodeGen/LoopTraversal.h:12-39
+/// This class implements the basic blocks traversal order used by passes like
+/// BreakFalseDeps and ExecutionDomainFix.
+///
+/// We want to visit every instruction in every basic block in order to update
+/// it's execution domain or break any false dependencies. However, for the
+/// dependency breaking, we need to know clearances from all predecessors
+/// (including any backedges). One way to do so would be to do two complete
----------------
- The comment (except for the first `\file` sentence) would better fit in front of `class LoopTraversal`.

- It's good to see an example trying to explain the goals of the algorithm!

- You can simplify the explanation by removing descriptions of how things are not done (i.e. the "it's not using the two-pass or naive worklist approaches" parts). Instead you should describe what actually is done: A reverse postorder traversal with an intertwined worklist algorithm for backedges.


================
Comment at: include/llvm/CodeGen/LoopTraversal.h:51-67
+  struct MBBInfo {
+    // Whether we have gotten to this block in primary processing yet.
+    bool PrimaryCompleted = false;
+
+    // The number of predecessors for which primary processing has completed
+    unsigned IncomingProcessed = 0;
+
----------------
This looks to me like these datastructures could be `private`.


================
Comment at: include/llvm/CodeGen/LoopTraversal.h:73-81
+  // Overridden by the derived classes.
+  virtual void enterBasicBlock(MachineBasicBlock *) = 0;
+  virtual void leaveBasicBlock(MachineBasicBlock *) = 0;
+  virtual void processBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass) = 0;
+
+  // Traversal operations
+  void runOnBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass);
----------------
This API seems too complicated to me. Given that this is just a loop traversal API I would expect that `traverse()` and `runOnBasicBlock()` is enough.

See also my comment inside `runOnBasicBlock()`; `isBlockDone()` can be private so it is not part of the API I believe.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:18-19
+
+/// Includes the general logic of handeling a basic block, activating sub phases
+/// that are implemented by the derived classes.
+void LoopTraversal::runOnBasicBlock(MachineBasicBlock *MBB, bool PrimaryPass) {
----------------
It is usually more convenient for users of the API if the doxygen comments are in the header;  similar for following methods.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:21-23
+  enterBasicBlock(MBB);
+  processBasicBlock(MBB, PrimaryPass);
+  leaveBasicBlock(MBB);
----------------
As far as I can see all three of `enterBasicBlock()`, `processBasicBlock()`, `leaveBasicBlock()` are always called together in this order. So it could just as well be a single function. In fact I believe just adding `virtual` to `runOnBasicBlock()` and removing the three other methods would suffice.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:36
+  // Initialize the MMBInfos
+  for (auto &MBB : mf) {
+    MBBInfo InitialInfo;
----------------
Using `MachineBasicBlock &` instead of `auto &` is friendlier to people reading the code.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:45-48
+  for (ReversePostOrderTraversal<MachineBasicBlock *>::rpo_iterator
+           MBBI = RPOT.begin(),
+           MBBE = RPOT.end();
+       MBBI != MBBE; ++MBBI) {
----------------
You could simplify this to:
```
for (MachineBasicBlock *MBB : RPOT) {
   // ...
}
```

Same with the loop after this one.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:63-71
+          if (Primary) {
+            MBBInfos[Succ].IncomingProcessed++;
+          }
+          if (Done) {
+            MBBInfos[Succ].IncomingCompleted++;
+          }
+          if (isBlockDone(Succ)) {
----------------
Don't use `{}` for 1 line ifs.


================
Comment at: lib/CodeGen/LoopTraversal.cpp:78-80
+  // We need to go through again and finalize any blocks that are not done yet.
+  // This is possible if blocks have dead predecessors, so we didn't visit them
+  // above.
----------------
Can you explain how this happens? Both loops appear to be using a RPO traversal, how could the first one miss some that this 2nd pass catches?


Repository:
  rL LLVM

https://reviews.llvm.org/D40333





More information about the llvm-commits mailing list