Partition use lists so defs always come before uses.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 9 Aug 2012 22:49:46 +0000 (22:49 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 9 Aug 2012 22:49:46 +0000 (22:49 +0000)
This makes it possible to speed up def_iterator by stopping at the first
use. This makes def_empty() and getUniqueVRegDef() much faster when
there are many uses.

In a +Asserts build, LiveVariables is 100x faster in one case because
getVRegDef() has an assertion that would scan to the end of a
def_iterator chain.

Spill weight calculation is significantly faster (300x in one case)
because isTriviallyReMaterializable() calls MRI->isConstantPhysReg(%RIP)
which calls def_empty(%RIP).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161634 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineRegisterInfo.h
lib/CodeGen/MachineRegisterInfo.cpp
test/CodeGen/X86/apm.ll
test/CodeGen/X86/xor.ll

index 68905e3c5e54522089761d2b5da9b9dc7f420e1c..42a8aa43d98241726fd75c3e956389fd0b4cf996 100644 (file)
@@ -513,11 +513,20 @@ public:
       assert(Op && "Cannot increment end iterator!");
       Op = getNextOperandForReg(Op);
 
-      // If this is an operand we don't care about, skip it.
-      while (Op && ((!ReturnUses && Op->isUse()) ||
-                    (!ReturnDefs && Op->isDef()) ||
-                    (SkipDebug && Op->isDebug())))
-        Op = getNextOperandForReg(Op);
+      // All defs come before the uses, so stop def_iterator early.
+      if (!ReturnUses) {
+        if (Op) {
+          if (Op->isUse())
+            Op = 0;
+          else
+            assert(!Op->isDebug() && "Can't have debug defs");
+        }
+      } else {
+        // If this is an operand we don't care about, skip it.
+        while (Op && ((!ReturnDefs && Op->isDef()) ||
+                      (SkipDebug && Op->isDebug())))
+          Op = getNextOperandForReg(Op);
+      }
 
       return *this;
     }
index bd826fb7c1bed6cfc8faefe0c638292738066ea8..5fb938f3400dafe23d7c7cbad1d3c5b204ebd21c 100644 (file)
@@ -144,9 +144,17 @@ void MachineRegisterInfo::addRegOperandToUseList(MachineOperand *MO) {
   Head->Contents.Reg.Prev = MO;
   MO->Contents.Reg.Prev = Last;
 
-  // Insert at the front.
-  MO->Contents.Reg.Next = Head;
-  HeadRef = MO;
+  // Def operands always precede uses. This allows def_iterator to stop early.
+  // Insert def operands at the front, and use operands at the back.
+  if (MO->isDef()) {
+    // Insert def at the front.
+    MO->Contents.Reg.Next = Head;
+    HeadRef = MO;
+  } else {
+    // Insert use at the end.
+    MO->Contents.Reg.Next = 0;
+    Last->Contents.Reg.Next = MO;
+  }
 }
 
 /// Remove MO from its use-def list.
index 9f4b0f46562f91a5e015599a8b919edf313e383d..aaedf18481b5d48326bb9772102baf055acf0806 100644 (file)
@@ -3,8 +3,8 @@
 ; PR8573
 
 ; CHECK: foo:
-; CHECK: movl    %esi, %ecx
-; CHECK-NEXT: leaq    (%rdi), %rax
+; CHECK: leaq    (%rdi), %rax
+; CHECK-NEXT: movl    %esi, %ecx
 ; CHECK-NEXT: monitor
 ; WIN64: foo:
 ; WIN64:      leaq    (%rcx), %rax
index 73416eff0e67d755ed55d959685ca1a611a65275..996bfc40ee5649fdba63fed53b6aef9417dd18fe 100644 (file)
@@ -31,7 +31,7 @@ entry:
 ; X64: test3:
 ; X64: notl
 ; X64: andl
-; X64: shrl    %eax
+; X64: shrl
 ; X64: ret
 
 ; X32: test3: