[llvm] r226071 - [RegisterCoalescer] Remove copies to reserved registers

Hal Finkel hfinkel at anl.gov
Wed Jan 14 17:25:28 PST 2015


Author: hfinkel
Date: Wed Jan 14 19:25:28 2015
New Revision: 226071

URL: http://llvm.org/viewvc/llvm-project?rev=226071&view=rev
Log:
[RegisterCoalescer] Remove copies to reserved registers

This allows the RegisterCoalescer to join "non-flipped" range pairs with a
physical destination register -- which allows the RegisterCoalescer to remove
copies like this:

<vreg> = something (maybe a load, for example)
... (things that don't use PHYSREG)
PHYSREG = COPY <vreg>

(with all of the restrictions normally applied by the RegisterCoalescer: having
compatible register classes, etc. )

Previously, the RegisterCoalescer handled only the opposite case (copying
*from* a physical register). I don't handle the problem fully here, but try to
get the common case where there is only one use of <vreg> (the COPY).

An upcoming commit to the PowerPC backend will make this pattern much more
common on PPC64/ELF systems.

Modified:
    llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
    llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll
    llvm/trunk/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll

Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=226071&r1=226070&r2=226071&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Wed Jan 14 19:25:28 2015
@@ -1209,10 +1209,10 @@ bool RegisterCoalescer::canJoinPhys(cons
   }
 
   LiveInterval &JoinVInt = LIS->getInterval(CP.getSrcReg());
-  if (CP.isFlipped() && JoinVInt.containsOneValue())
+  if (JoinVInt.containsOneValue())
     return true;
 
-  DEBUG(dbgs() << "\tCannot join defs into reserved register.\n");
+  DEBUG(dbgs() << "\tCannot join complex intervals into reserved register.\n");
   return false;
 }
 
@@ -1431,8 +1431,7 @@ bool RegisterCoalescer::joinReservedPhys
   LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
   DEBUG(dbgs() << "\t\tRHS = " << RHS << '\n');
 
-  assert(CP.isFlipped() && RHS.containsOneValue() &&
-         "Invalid join with reserved register");
+  assert(RHS.containsOneValue() && "Invalid join with reserved register");
 
   // Optimization for reserved registers like ESP. We can only merge with a
   // reserved physreg if RHS has a single value that is a copy of CP.DstReg().
@@ -1453,7 +1452,18 @@ bool RegisterCoalescer::joinReservedPhys
   // defs are there.
 
   // Delete the identity copy.
-  MachineInstr *CopyMI = MRI->getVRegDef(RHS.reg);
+  MachineInstr *CopyMI;
+  if (CP.isFlipped()) {
+    CopyMI = MRI->getVRegDef(RHS.reg);
+  } else {
+    if (!MRI->hasOneNonDBGUse(RHS.reg)) {
+      DEBUG(dbgs() << "\t\tMultiple vreg uses\n");
+      return false;
+    }
+
+    CopyMI = &*MRI->use_instr_nodbg_begin(RHS.reg);
+  }
+  
   LIS->RemoveMachineInstrFromMaps(CopyMI);
   CopyMI->eraseFromParent();
 

Modified: llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll?rev=226071&r1=226070&r2=226071&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/dyn-stackalloc.ll Wed Jan 14 19:25:28 2015
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=arm-eabi %s -o /dev/null
+; RUN: llc -mcpu=generic -mtriple=arm-eabi < %s | FileCheck %s
 
 %struct.comment = type { i8**, i32*, i32, i8* }
 %struct.info = type { i32, i32, i32, i32, i32, i32, i32, i8* }
@@ -7,6 +7,18 @@
 @str215 = external global [2 x i8]
 
 define void @t1(%struct.state* %v) {
+
+; Make sure we generate:
+;   sub	sp, sp, r1
+; instead of:
+;   sub	r1, sp, r1
+;   mov	sp, r1
+
+; CHECK-LABEL: @t1
+; CHECK: bic [[REG1:r[0-9]+]],
+; CHECK-NOT: sub r{{[0-9]+}}, sp, [[REG1]]
+; CHECK: sub sp, sp, [[REG1]]
+
   %tmp6 = load i32* null
   %tmp8 = alloca float, i32 %tmp6
   store i32 1, i32* null

Modified: llvm/trunk/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll?rev=226071&r1=226070&r2=226071&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll (original)
+++ llvm/trunk/test/CodeGen/X86/2009-02-12-DebugInfoVLA.ll Wed Jan 14 19:25:28 2015
@@ -1,9 +1,19 @@
 ; RUN: llc < %s
-; RUN: llc < %s -march=x86-64
+; RUN: llc < %s -march=x86-64 | FileCheck %s
 ; PR3538
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
 target triple = "i386-apple-darwin9"
 define signext i8 @foo(i8* %s1) nounwind ssp {
+
+; Make sure we generate:
+;  movq	-40(%rbp), %rsp
+; Instead of:
+;  movq	-40(%rbp), %rax
+;  movq	%rax, %rsp
+
+; CHECK-LABEL: @foo
+; CHECK: movq	-40(%rbp), %rsp
+
 entry:
   %s1_addr = alloca i8*                           ; <i8**> [#uses=2]
   %retval = alloca i32                            ; <i32*> [#uses=2]





More information about the llvm-commits mailing list