mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-23 13:02:52 +02:00
[RegBankSelect] Support REG_SEQUENCE for generic mapping
REG_SEQUENCE falls into the same category as COPY for operands mapping: - They don't have MCInstrDesc with register constraints - The input variable could use whatever register classes - It is possible to have register class already assigned to the operands In particular, given REG_SEQUENCE are always target specific because of the subreg indices. Those indices must apply to the register class of the definition of the REG_SEQUENCE and therefore, the target must set a register class to that definition. As a result, the generic code can always use that register class to derive a valid mapping for a REG_SEQUENCE. llvm-svn: 299285
This commit is contained in:
parent
f32206eabf
commit
65c28040ef
@ -126,15 +126,26 @@ const TargetRegisterClass *RegisterBankInfo::constrainGenericRegister(
|
||||
return &RC;
|
||||
}
|
||||
|
||||
/// Check whether or not \p MI should be treated like a copy
|
||||
/// for the mappings.
|
||||
/// Copy like instruction are special for mapping because
|
||||
/// they don't have actual register constraints. Moreover,
|
||||
/// they sometimes have register classes assigned and we can
|
||||
/// just use that instead of failing to provide a generic mapping.
|
||||
static bool isCopyLike(const MachineInstr &MI) {
|
||||
return MI.isCopy() || MI.isPHI() ||
|
||||
MI.getOpcode() == TargetOpcode::REG_SEQUENCE;
|
||||
}
|
||||
|
||||
RegisterBankInfo::InstructionMapping
|
||||
RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
// For copies we want to walk over the operands and try to find one
|
||||
// that has a register bank since the instruction itself will not get
|
||||
// us any constraint.
|
||||
bool isCopyLike = MI.isCopy() || MI.isPHI();
|
||||
bool IsCopyLike = isCopyLike(MI);
|
||||
// For copy like instruction, only the mapping of the definition
|
||||
// is important. The rest is not constrained.
|
||||
unsigned NumOperandsForMapping = isCopyLike ? 1 : MI.getNumOperands();
|
||||
unsigned NumOperandsForMapping = IsCopyLike ? 1 : MI.getNumOperands();
|
||||
|
||||
RegisterBankInfo::InstructionMapping Mapping(DefaultMappingID, /*Cost*/ 1,
|
||||
/*OperandsMapping*/ nullptr,
|
||||
@ -168,7 +179,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
// For copy-like instruction, we want to reuse the register bank
|
||||
// that is already set on Reg, if any, since those instructions do
|
||||
// not have any constraints.
|
||||
const RegisterBank *CurRegBank = isCopyLike ? AltRegBank : nullptr;
|
||||
const RegisterBank *CurRegBank = IsCopyLike ? AltRegBank : nullptr;
|
||||
if (!CurRegBank) {
|
||||
// If this is a target specific instruction, we can deduce
|
||||
// the register bank from the encoding constraints.
|
||||
@ -177,7 +188,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
// All our attempts failed, give up.
|
||||
CompleteMapping = false;
|
||||
|
||||
if (!isCopyLike)
|
||||
if (!IsCopyLike)
|
||||
// MI does not carry enough information to guess the mapping.
|
||||
return InstructionMapping();
|
||||
continue;
|
||||
@ -185,7 +196,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
}
|
||||
const ValueMapping *ValMapping =
|
||||
&getValueMapping(0, getSizeInBits(Reg, MRI, TRI), *CurRegBank);
|
||||
if (isCopyLike) {
|
||||
if (IsCopyLike) {
|
||||
OperandsMapping[0] = ValMapping;
|
||||
CompleteMapping = true;
|
||||
break;
|
||||
@ -193,7 +204,7 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const {
|
||||
OperandsMapping[OpIdx] = ValMapping;
|
||||
}
|
||||
|
||||
if (isCopyLike && !CompleteMapping)
|
||||
if (IsCopyLike && !CompleteMapping)
|
||||
// No way to deduce the type from what we have.
|
||||
return InstructionMapping();
|
||||
|
||||
@ -492,8 +503,7 @@ bool RegisterBankInfo::InstructionMapping::verify(
|
||||
// Check that all the register operands are properly mapped.
|
||||
// Check the constructor invariant.
|
||||
// For PHI, we only care about mapping the definition.
|
||||
assert(NumOperands ==
|
||||
((MI.isCopy() || MI.isPHI()) ? 1 : MI.getNumOperands()) &&
|
||||
assert(NumOperands == (isCopyLike(MI) ? 1 : MI.getNumOperands()) &&
|
||||
"NumOperands must match, see constructor");
|
||||
assert(MI.getParent() && MI.getParent()->getParent() &&
|
||||
"MI must be connected to a MachineFunction");
|
||||
|
@ -0,0 +1,25 @@
|
||||
# RUN: llc %s -mtriple aarch64-- -o - -run-pass regbankselect | FileCheck %s
|
||||
--- |
|
||||
define void @foo() { ret void }
|
||||
...
|
||||
---
|
||||
# CHECK-LABEL: foo
|
||||
# Check that we produce a valid mapping for REG_SEQUENCE.
|
||||
# This used to fail the RegisterBankInfo verify because
|
||||
# we were using the exclusively the type of the definition
|
||||
# whereas since REG_SEQUENCE are kind of target opcode
|
||||
# their definition may not have a type.
|
||||
#
|
||||
# CHECK: id: 0, class: dd
|
||||
name: foo
|
||||
legalized: true
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: dd }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %d0, %d1
|
||||
|
||||
%0 = REG_SEQUENCE %d0, %subreg.dsub0, %d1, %subreg.dsub1
|
||||
|
||||
...
|
Loading…
Reference in New Issue
Block a user