]> granicus.if.org Git - llvm/commitdiff
RegisterScavenging: Add ScavengerTest pass
authorMatthias Braun <matze@braunis.de>
Fri, 2 Jun 2017 23:01:42 +0000 (23:01 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 2 Jun 2017 23:01:42 +0000 (23:01 +0000)
This pass allows to run the register scavenging independently of
PrologEpilogInserter to allow targeted testing.

Also adds some basic register scavenging tests.

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

include/llvm/InitializePasses.h
lib/CodeGen/RegisterScavenging.cpp
test/CodeGen/PowerPC/scavenging.mir [new file with mode: 0644]
test/CodeGen/X86/scavenger.mir [new file with mode: 0644]
tools/llc/llc.cpp

index e2ed718277ae41c63abd8841c229c752a5559cea..7a734d474e745b97bcfea63c461cb4b8a11033ee 100644 (file)
@@ -330,6 +330,7 @@ void initializeSanitizerCoverageModulePass(PassRegistry&);
 void initializeScalarEvolutionWrapperPassPass(PassRegistry&);
 void initializeScalarizeMaskedMemIntrinPass(PassRegistry&);
 void initializeScalarizerPass(PassRegistry&);
+void initializeScavengerTestPass(PassRegistry&);
 void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&);
 void initializeSeparateConstOffsetFromGEPPass(PassRegistry&);
 void initializeShadowStackGCLoweringPass(PassRegistry&);
index a805467e114606ae6793e256b41bdf80bd7340e5..1aed58c36e17dd28ab9cf0bacab3b30b40507367 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/CodeGen/RegisterScavenging.h"
+
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/PassSupport.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetFrameLowering.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetSubtargetInfo.h"
@@ -555,5 +559,37 @@ void llvm::scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS) {
     }
   }
 
+  MRI.clearVirtRegs();
   MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
 }
+
+namespace {
+/// This class runs register scavenging independ of the PrologEpilogInserter.
+/// This is used in for testing.
+class ScavengerTest : public MachineFunctionPass {
+public:
+  static char ID;
+  ScavengerTest() : MachineFunctionPass(ID) {}
+  bool runOnMachineFunction(MachineFunction &MF) {
+    const TargetSubtargetInfo &STI = MF.getSubtarget();
+    const TargetFrameLowering &TFL = *STI.getFrameLowering();
+
+    RegScavenger RS;
+    // Let's hope that calling those outside of PrologEpilogueInserter works
+    // well enough to initialize the scavenger with some emergency spillslots
+    // for the target.
+    BitVector SavedRegs;
+    TFL.determineCalleeSaves(MF, SavedRegs, &RS);
+    TFL.processFunctionBeforeFrameFinalized(MF, &RS);
+
+    // Let's scavenge the current function
+    scavengeFrameVirtualRegs(MF, RS);
+    return true;
+  }
+};
+char ScavengerTest::ID;
+
+} // end anonymous namespace
+
+INITIALIZE_PASS(ScavengerTest, "scavenger-test",
+                "Scavenge virtual registers inside basic blocks", false, false)
diff --git a/test/CodeGen/PowerPC/scavenging.mir b/test/CodeGen/PowerPC/scavenging.mir
new file mode 100644 (file)
index 0000000..8b5c262
--- /dev/null
@@ -0,0 +1,149 @@
+# RUN: llc -mtriple=ppc64-- -run-pass scavenger-test -verify-machineinstrs -o - %s | FileCheck %s
+---
+# CHECK-LABEL: name: noscav0
+name: noscav0
+tracksRegLiveness: true
+body: |
+  bb.0:
+    ; CHECK: [[REG0:%r[0-9]+]] = LI 42
+    ; CHECK-NEXT: NOP implicit [[REG0]]
+    %0 : gprc = LI 42
+    NOP implicit %0
+
+    ; CHECK: [[REG1:%r[0-9]+]] = LI 42
+    ; CHECK-NEXT: NOP
+    ; CHECK-NEXT: NOP implicit [[REG1]]
+    ; CHECK-NEXT: NOP
+    ; CHECK-NEXT: NOP implicit [[REG1]]
+    %1 : gprc = LI 42
+    NOP
+    NOP implicit %1
+    NOP
+    NOP implicit %1
+
+    ; CHECK: [[REG2:%r[0-9]+]] = LI 42
+    ; CHECK-NEXT: NOP implicit [[REG2]]
+    %2 : gprc = LI 42
+    NOP implicit %2
+
+    %x0 = IMPLICIT_DEF
+    %x1 = IMPLICIT_DEF
+    %x2 = IMPLICIT_DEF
+    %x3 = IMPLICIT_DEF
+    %x4 = IMPLICIT_DEF
+    %x27 = IMPLICIT_DEF
+    %x28 = IMPLICIT_DEF
+    %x29 = IMPLICIT_DEF
+    %x30 = IMPLICIT_DEF
+
+    ; CHECK-NOT: %x0 = LI 42
+    ; CHECK-NOT: %x1 = LI 42
+    ; CHECK-NOT: %x2 = LI 42
+    ; CHECK-NOT: %x3 = LI 42
+    ; CHECK-NOT: %x4 = LI 42
+    ; CHECK-NOT: %x5 = LI 42
+    ; CHECK-NOT: %x27 = LI 42
+    ; CHECK-NOT: %x28 = LI 42
+    ; CHECK-NOT: %x29 = LI 42
+    ; CHECK-NOT: %x30 = LI 42
+    ; CHECK: [[REG3:%r[0-9]+]] = LI 42
+    ; CHECK-NEXT: %x5 = IMPLICIT_DEF
+    ; CHECK-NEXT: NOP implicit [[REG2]]
+    ; CHECK-NEXT: NOP implicit [[REG3]]
+    %3 : gprc = LI 42
+    %x5 = IMPLICIT_DEF
+    NOP implicit %2
+    NOP implicit %3
+
+    NOP implicit %x0
+    NOP implicit %x1
+    NOP implicit %x2
+    NOP implicit %x3
+    NOP implicit %x4
+    NOP implicit %x5
+    NOP implicit %x27
+    NOP implicit %x28
+    NOP implicit %x29
+    NOP implicit %x30
+...
+---
+# CHECK-LABEL: name: scav0
+name: scav0
+tracksRegLiveness: true
+stack:
+  # variable-sized object should be a reason to reserve an emergency spillslot
+  # in the RegScavenger
+  - { id: 0, type: variable-sized, offset: -32, alignment: 1 }
+body: |
+  bb.0:
+    %x0 = IMPLICIT_DEF
+    %x1 = IMPLICIT_DEF
+    %x2 = IMPLICIT_DEF
+    %x3 = IMPLICIT_DEF
+    %x4 = IMPLICIT_DEF
+    %x5 = IMPLICIT_DEF
+    %x6 = IMPLICIT_DEF
+    %x7 = IMPLICIT_DEF
+    %x8 = IMPLICIT_DEF
+    %x9 = IMPLICIT_DEF
+    %x10 = IMPLICIT_DEF
+    %x11 = IMPLICIT_DEF
+    %x12 = IMPLICIT_DEF
+    %x13 = IMPLICIT_DEF
+    %x14 = IMPLICIT_DEF
+    %x15 = IMPLICIT_DEF
+    %x16 = IMPLICIT_DEF
+    %x17 = IMPLICIT_DEF
+    %x18 = IMPLICIT_DEF
+    %x19 = IMPLICIT_DEF
+    %x20 = IMPLICIT_DEF
+    %x21 = IMPLICIT_DEF
+    %x22 = IMPLICIT_DEF
+    %x23 = IMPLICIT_DEF
+    %x24 = IMPLICIT_DEF
+    %x25 = IMPLICIT_DEF
+    %x26 = IMPLICIT_DEF
+    %x27 = IMPLICIT_DEF
+    %x28 = IMPLICIT_DEF
+    %x29 = IMPLICIT_DEF
+    %x30 = IMPLICIT_DEF
+
+    ; CHECK: STD killed [[SPILLEDREG:%x[0-9]+]]
+    ; CHECK: [[SPILLEDREG]] = LI8 42
+    ; CHECK: NOP implicit [[SPILLEDREG]]
+    ; CHECK: [[SPILLEDREG]] = LD
+    %0 : g8rc = LI8 42
+    NOP implicit %0
+
+    NOP implicit %x0
+    NOP implicit %x1
+    NOP implicit %x2
+    NOP implicit %x3
+    NOP implicit %x4
+    NOP implicit %x5
+    NOP implicit %x6
+    NOP implicit %x7
+    NOP implicit %x8
+    NOP implicit %x9
+    NOP implicit %x10
+    NOP implicit %x11
+    NOP implicit %x12
+    NOP implicit %x13
+    NOP implicit %x14
+    NOP implicit %x15
+    NOP implicit %x16
+    NOP implicit %x17
+    NOP implicit %x18
+    NOP implicit %x19
+    NOP implicit %x20
+    NOP implicit %x21
+    NOP implicit %x22
+    NOP implicit %x23
+    NOP implicit %x24
+    NOP implicit %x25
+    NOP implicit %x26
+    NOP implicit %x27
+    NOP implicit %x28
+    NOP implicit %x29
+    NOP implicit %x30
+...
diff --git a/test/CodeGen/X86/scavenger.mir b/test/CodeGen/X86/scavenger.mir
new file mode 100644 (file)
index 0000000..8d97aeb
--- /dev/null
@@ -0,0 +1,54 @@
+# RUN: llc -mtriple=i386-- -run-pass scavenger-test -verify-machineinstrs -o - %s | FileCheck %s
+---
+# CHECK-LABEL: name: func0
+name: func0
+tracksRegLiveness: true
+body: |
+  bb.0:
+    %0 : gr32 = MOV32ri 42
+    %ebp = COPY %0
+...
+---
+# CHECK-LABEL: name: func2
+name: func2
+tracksRegLiveness: true
+body: |
+  bb.0:
+    ; CHECK-NOT: %eax = MOV32ri 42
+    ; CHECK: [[REG0:%e[a-z]+]] = MOV32ri 42
+    ; CHECK: %ebp = COPY [[REG0]]
+    %eax = MOV32ri 13
+    %0 : gr32 = MOV32ri 42
+    %ebp = COPY %0
+
+    ; CHECK: [[REG1:%e[a-z]+]] = MOV32ri 23
+    ; CHECK: [[REG2:%e[a-z]+]] = MOV32ri 7
+    ; CHECK: [[REG1]] = ADD32ri8 [[REG1]], 5, implicit-def dead %eflags
+    %1 : gr32 = MOV32ri 23
+    %2 : gr32 = MOV32ri 7
+    %1 = ADD32ri8 %1, 5, implicit-def dead %eflags
+
+    NOOP implicit %ebp
+
+    ; CHECK: NOOP implicit [[REG2]]
+    ; CHECK: NOOP implicit [[REG1]]
+    NOOP implicit %2
+    NOOP implicit %1
+    RETQ %eax
+...
+---
+# Defs without uses are currently broken
+#name: func3
+#tracksRegLiveness: true
+#body: |
+#  bb.0:
+#    dead %0 : gr32 = MOV32ri 42
+...
+---
+# Uses without defs are currently broken (and honestly not that useful).
+#name: func3
+#tracksRegLiveness: true
+#body: |
+#  bb.0:
+#    NOOP undef implicit %0 : gr32
+...
index 589005943045c183fde14ea71e51dafb212e4e4c..e10d112dcf9052d25dc3d3c7fae2281d2d13a009 100644 (file)
@@ -304,6 +304,9 @@ int main(int argc, char **argv) {
   initializeScalarizeMaskedMemIntrinPass(*Registry);
   initializeExpandReductionsPass(*Registry);
 
+  // Initialize debugging passes.
+  initializeScavengerTestPass(*Registry);
+
   // Register the target printer for --version.
   cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);