mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-25 13:45:34 +00:00
[GlobalISel] Set, require, and verify Legalized MF property.
RegBankSelect and InstructionSelect run after the legalizer and require a Legalized function: check that all instructions are legal. Note that this should be in the MachineVerifier, but it can't use the MachineLegalizer as it's currently in the separate GlobalISel library. Note that the RegBankSelect verifier checks have the same layering problem, but we only use inline methods so end up not needing to link against the GlobalISel library. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@277472 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a877bb83bf
commit
d170182063
@ -32,7 +32,8 @@ public:
|
||||
|
||||
MachineFunctionProperties getRequiredProperties() const override {
|
||||
return MachineFunctionProperties()
|
||||
.set(MachineFunctionProperties::Property::IsSSA);
|
||||
.set(MachineFunctionProperties::Property::IsSSA)
|
||||
.set(MachineFunctionProperties::Property::Legalized);
|
||||
}
|
||||
|
||||
InstructionSelect();
|
||||
|
@ -48,6 +48,11 @@ public:
|
||||
MachineFunctionProperties::Property::IsSSA);
|
||||
}
|
||||
|
||||
MachineFunctionProperties getSetProperties() const override {
|
||||
return MachineFunctionProperties().set(
|
||||
MachineFunctionProperties::Property::Legalized);
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
};
|
||||
} // End namespace llvm.
|
||||
|
@ -586,7 +586,8 @@ public:
|
||||
|
||||
MachineFunctionProperties getRequiredProperties() const override {
|
||||
return MachineFunctionProperties()
|
||||
.set(MachineFunctionProperties::Property::IsSSA);
|
||||
.set(MachineFunctionProperties::Property::IsSSA)
|
||||
.set(MachineFunctionProperties::Property::Legalized);
|
||||
}
|
||||
|
||||
/// Walk through \p MF and assign a register bank to every virtual register
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -51,6 +52,19 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
// other MF/MFI fields we need to initialize.
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check that our input is fully legal: we require the function to have the
|
||||
// Legalized property, so it should be.
|
||||
// FIXME: This should be in the MachineVerifier, but it can't use the
|
||||
// MachineLegalizer as it's currently in the separate GlobalISel library.
|
||||
// The RegBankSelected property is already checked in the verifier. Note
|
||||
// that it has the same layering problem, but we only use inline methods so
|
||||
// end up not needing to link against the GlobalISel library.
|
||||
if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer())
|
||||
for (const MachineBasicBlock &MBB : MF)
|
||||
for (const MachineInstr &MI : MBB)
|
||||
if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI))
|
||||
reportSelectionError(MI, "Instruction is not legal");
|
||||
|
||||
// FIXME: We could introduce new blocks and will need to fix the outer loop.
|
||||
// Until then, keep track of the number of blocks to assert that we don't.
|
||||
const size_t NumBlocks = MF.size();
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
|
||||
#include "llvm/ADT/PostOrderIterator.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineLegalizer.h"
|
||||
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
|
||||
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
@ -542,6 +543,26 @@ bool RegBankSelect::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (F->hasFnAttribute(Attribute::OptimizeNone))
|
||||
OptMode = Mode::Fast;
|
||||
init(MF);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check that our input is fully legal: we require the function to have the
|
||||
// Legalized property, so it should be.
|
||||
// FIXME: This should be in the MachineVerifier, but it can't use the
|
||||
// MachineLegalizer as it's currently in the separate GlobalISel library.
|
||||
if (const MachineLegalizer *MLI = MF.getSubtarget().getMachineLegalizer()) {
|
||||
for (const MachineBasicBlock &MBB : MF) {
|
||||
for (const MachineInstr &MI : MBB) {
|
||||
if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI)) {
|
||||
std::string ErrStorage;
|
||||
raw_string_ostream Err(ErrStorage);
|
||||
Err << "Instruction is not legal: " << MI << '\n';
|
||||
report_fatal_error(Err.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Walk the function and assign register banks to all operands.
|
||||
// Use a RPOT to make sure all registers are assigned before we choose
|
||||
// the best mapping of the current instruction.
|
||||
|
@ -39,6 +39,7 @@
|
||||
# CHECK-LABEL: name: add_s32_gpr
|
||||
name: add_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -63,6 +64,7 @@ body: |
|
||||
# CHECK-LABEL: name: add_s64_gpr
|
||||
name: add_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
@ -87,6 +89,7 @@ body: |
|
||||
# CHECK-LABEL: name: sub_s32_gpr
|
||||
name: sub_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -111,6 +114,7 @@ body: |
|
||||
# CHECK-LABEL: name: sub_s64_gpr
|
||||
name: sub_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
@ -135,6 +139,7 @@ body: |
|
||||
# CHECK-LABEL: name: or_s32_gpr
|
||||
name: or_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -159,6 +164,7 @@ body: |
|
||||
# CHECK-LABEL: name: or_s64_gpr
|
||||
name: or_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
@ -183,6 +189,7 @@ body: |
|
||||
# CHECK-LABEL: name: xor_s32_gpr
|
||||
name: xor_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -207,6 +214,7 @@ body: |
|
||||
# CHECK-LABEL: name: xor_s64_gpr
|
||||
name: xor_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
@ -231,6 +239,7 @@ body: |
|
||||
# CHECK-LABEL: name: and_s32_gpr
|
||||
name: and_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -255,6 +264,7 @@ body: |
|
||||
# CHECK-LABEL: name: and_s64_gpr
|
||||
name: and_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
@ -278,6 +288,7 @@ body: |
|
||||
# CHECK-LABEL: name: unconditional_br
|
||||
name: unconditional_br
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: body:
|
||||
# CHECK: bb.0:
|
||||
@ -294,6 +305,7 @@ body: |
|
||||
# CHECK-LABEL: name: load_s64_gpr
|
||||
name: load_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64sp }
|
||||
@ -318,6 +330,7 @@ body: |
|
||||
# CHECK-LABEL: name: load_s32_gpr
|
||||
name: load_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64sp }
|
||||
@ -342,6 +355,7 @@ body: |
|
||||
# CHECK-LABEL: name: store_s64_gpr
|
||||
name: store_s64_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64sp }
|
||||
@ -368,6 +382,7 @@ body: |
|
||||
# CHECK-LABEL: name: store_s32_gpr
|
||||
name: store_s32_gpr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64sp }
|
||||
|
@ -63,6 +63,7 @@
|
||||
# Based on the type i32, this should be gpr.
|
||||
name: defaultMapping
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
registers:
|
||||
@ -80,6 +81,7 @@ body: |
|
||||
# FPR is used for both floating point and vector registers.
|
||||
name: defaultMappingVector
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: fpr }
|
||||
registers:
|
||||
@ -97,6 +99,7 @@ body: |
|
||||
# in FPR, but at the use, it should be GPR.
|
||||
name: defaultMapping1Repair
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: fpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -117,6 +120,7 @@ body: |
|
||||
# Check that we repair the assignment for %0 differently for both uses.
|
||||
name: defaultMapping2Repairs
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: fpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -143,6 +147,7 @@ body: |
|
||||
# fixes that.
|
||||
name: defaultMappingDefRepair
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
# CHECK-NEXT: - { id: 1, class: fpr }
|
||||
@ -164,6 +169,7 @@ body: |
|
||||
# Check that we are able to propagate register banks from phis.
|
||||
name: phiPropagation
|
||||
isSSA: true
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr32 }
|
||||
@ -201,6 +207,7 @@ body: |
|
||||
# Make sure we can repair physical register uses as well.
|
||||
name: defaultMappingUseRepairPhysReg
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -222,6 +229,7 @@ body: |
|
||||
# Make sure we can repair physical register defs.
|
||||
name: defaultMappingDefRepairPhysReg
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -242,6 +250,7 @@ body: |
|
||||
# G_OR instruction from fpr to gpr.
|
||||
name: greedyMappingOr
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -288,6 +297,7 @@ body: |
|
||||
# %2 constraint.
|
||||
name: greedyMappingOrWithConstraints
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr }
|
||||
@ -334,6 +344,7 @@ body: |
|
||||
# CHECK-LABEL: name: ignoreTargetSpecificInst
|
||||
name: ignoreTargetSpecificInst
|
||||
isSSA: true
|
||||
legalized: true
|
||||
# CHECK: registers:
|
||||
# CHECK-NEXT: - { id: 0, class: gpr64 }
|
||||
# CHECK-NEXT: - { id: 1, class: gpr64 }
|
||||
|
20
test/CodeGen/AArch64/GlobalISel/legalize-property.mir
Normal file
20
test/CodeGen/AArch64/GlobalISel/legalize-property.mir
Normal file
@ -0,0 +1,20 @@
|
||||
# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - | FileCheck %s
|
||||
# REQUIRES: global-isel
|
||||
|
||||
--- |
|
||||
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64--"
|
||||
define void @legalized_property() { ret void }
|
||||
...
|
||||
|
||||
---
|
||||
# Check that we set the "legalized" property.
|
||||
# CHECK-LABEL: name: legalized_property
|
||||
# CHECK: legalized: true
|
||||
# CHECK: isSSA: true
|
||||
name: legalized_property
|
||||
isSSA: true
|
||||
legalized: false
|
||||
body: |
|
||||
bb.0:
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user