From: Matthias Braun Date: Fri, 2 Jun 2017 23:01:42 +0000 (+0000) Subject: RegisterScavenging: Add ScavengerTest pass X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3310b59ffc8e7c56b503b9236beafe133c9c5ce2;p=llvm RegisterScavenging: Add ScavengerTest pass 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 --- diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index e2ed718277a..7a734d474e7 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -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&); diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index a805467e114..1aed58c36e1 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -15,19 +15,23 @@ // //===----------------------------------------------------------------------===// +#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 index 00000000000..8b5c26230bc --- /dev/null +++ b/test/CodeGen/PowerPC/scavenging.mir @@ -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 index 00000000000..8d97aeb22cb --- /dev/null +++ b/test/CodeGen/X86/scavenger.mir @@ -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 +... diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 58900594304..e10d112dcf9 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -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);