[PATCH] D20102: [ScheduleDAG] Make sure to process all def operands before any use operands

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Tue May 10 07:56:46 PDT 2016


kparzysz created this revision.
kparzysz added a reviewer: MatzeB.
kparzysz added a subscriber: llvm-commits.
kparzysz set the repository for this revision to rL LLVM.
Herald added a subscriber: MatzeB.

An example from Hexagon where things went wrong:

```
%R0<def> = L2_loadrigp <ga:@fp04>      ; load function address
J2_callr %R0<kill>, ..., %R0<imp-def>  ; call *R0, return value in R0
```

ScheduleDAGInstrs::buildSchedGraph would visit all instructions going backwards, and in each instruction it would visit all operands in their order on the operand list. In the case of this call, it visited the use of R0 first, then removed it from the set Uses after it visited the def. This caused the DAG to be missing the data dependence edge on R0 between the load and the call.

The final result was that the load and the call were packetized together, which meant that the call used the prior value of R0 instead of the loaded one.

Repository:
  rL LLVM

http://reviews.llvm.org/D20102

Files:
  lib/CodeGen/ScheduleDAGInstrs.cpp
  test/CodeGen/Hexagon/callr-dep-edge.ll

Index: test/CodeGen/Hexagon/callr-dep-edge.ll
===================================================================
--- /dev/null
+++ test/CodeGen/Hexagon/callr-dep-edge.ll
@@ -0,0 +1,20 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+; Check that the callr and the load into r0 are not packetized together.
+
+target triple = "hexagon"
+
+ at fp = common global i32 (...)* null, align 4
+
+; CHECK: r0 = memw
+; CHECK: {
+; CHECK: callr r0
+
+; Function Attrs: nounwind
+define i32 @foo() #0 {
+entry:
+  %0 = load i32 ()*, i32 ()** bitcast (i32 (...)** @fp to i32 ()**), align 4
+  %call = tail call i32 %0() #0
+  ret i32 %call
+}
+
+attributes #0 = { nounwind }
Index: lib/CodeGen/ScheduleDAGInstrs.cpp
===================================================================
--- lib/CodeGen/ScheduleDAGInstrs.cpp
+++ lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -948,24 +948,41 @@
         "Cannot schedule terminators or labels!");
 
     // Add register-based dependencies (data, anti, and output).
+    // For some instructions (calls, returns, inline-asm, etc.) there can
+    // be explicit uses and implicit defs, in which case the use will appear
+    // on the operand list before the def. Do two passes over the operand
+    // list to make sure that defs are processed before any uses.
     bool HasVRegDef = false;
     for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
       const MachineOperand &MO = MI->getOperand(j);
-      if (!MO.isReg()) continue;
+      if (!MO.isReg() || !MO.isDef())
+        continue;
       unsigned Reg = MO.getReg();
-      if (Reg == 0) continue;
+      if (Reg == 0)
+        continue;
 
       if (TRI->isPhysicalRegister(Reg))
         addPhysRegDeps(SU, j);
       else {
-        if (MO.isDef()) {
-          HasVRegDef = true;
-          addVRegDefDeps(SU, j);
-        }
-        else if (MO.readsReg()) // ignore undef operands
-          addVRegUseDeps(SU, j);
+        HasVRegDef = true;
+        addVRegDefDeps(SU, j);
       }
     }
+    // Now process all uses.
+    for (unsigned j = 0, n = MI->getNumOperands(); j != n; ++j) {
+      const MachineOperand &MO = MI->getOperand(j);
+      if (!MO.isReg() || !MO.isUse())
+        continue;
+      unsigned Reg = MO.getReg();
+      if (Reg == 0)
+        continue;
+
+      if (TRI->isPhysicalRegister(Reg))
+        addPhysRegDeps(SU, j);
+      else if (MO.readsReg()) // ignore undef operands
+        addVRegUseDeps(SU, j);
+    }
+
     // If we haven't seen any uses in this scheduling region, create a
     // dependence edge to ExitSU to model the live-out latency. This is required
     // for vreg defs with no in-region use, and prefetches with no vreg def.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20102.56712.patch
Type: text/x-patch
Size: 2680 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160510/f882de83/attachment.bin>


More information about the llvm-commits mailing list