1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

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.

llvm-svn: 304606
This commit is contained in:
Matthias Braun 2017-06-02 23:01:42 +00:00
parent 0531e97657
commit 5693b1e8e8
5 changed files with 244 additions and 1 deletions

View 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&);

View File

@ -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)

View File

@ -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
...

View File

@ -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
...

View 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);