diff options
| author | Quentin Colombet <qcolombet@apple.com> | 2017-04-01 01:26:14 +0000 |
|---|---|---|
| committer | Quentin Colombet <qcolombet@apple.com> | 2017-04-01 01:26:14 +0000 |
| commit | 7f64318938cecbe53ee3ba59c79dd3b32cb7373b (patch) | |
| tree | 0638a4c990b690e87dfa3f0c10b37dc845bcd7f2 /llvm | |
| parent | b43da15602e271ff8a3bbcf2f2d16378e31bc76c (diff) | |
| download | bcm5719-llvm-7f64318938cecbe53ee3ba59c79dd3b32cb7373b.tar.gz bcm5719-llvm-7f64318938cecbe53ee3ba59c79dd3b32cb7373b.zip | |
[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
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 26 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reg_sequence.mir | 25 |
2 files changed, 43 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 2901761c1cd..b2df2f15967 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -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"); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reg_sequence.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reg_sequence.mir new file mode 100644 index 00000000000..15ccf1f5459 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reg_sequence.mir @@ -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 + +... |

