diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 0cac8cbd6987..85fa78d0fed4 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -1126,8 +1126,7 @@ class MachineInstr /// Replace all occurrences of FromReg with ToReg:SubIdx, /// properly composing subreg indices where necessary. void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, - const TargetRegisterInfo &RegInfo, - bool ClearIsRenamable = false); + const TargetRegisterInfo &RegInfo); /// We have determined MI kills a register. Look for the /// operand that uses it and mark it as IsKill. If AddIfNotFound is true, diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index 22fd86aaabd3..4f0db1c2ebcc 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -105,11 +105,7 @@ class MachineOperand { /// This is only valid on register operands. unsigned IsDeadOrKill : 1; - /// IsRenamable - True if this register may be renamed, i.e. it does not - /// generate a value that is somehow read in a way that is not represented by - /// the Machine IR (e.g. to meet an ABI or ISA requirement). This is only - /// valid on physical register operands. Virtual registers are assumed to - /// always be renamable regardless of the value of this field. + /// See isRenamable(). unsigned IsRenamable : 1; /// IsUndef - True if this register operand reads an "undef" value, i.e. the @@ -384,6 +380,35 @@ class MachineOperand { return IsUndef; } + /// isRenamable - Returns true if this register may be renamed, i.e. it does + /// not generate a value that is somehow read in a way that is not represented + /// by the Machine IR (e.g. to meet an ABI or ISA requirement). This is only + /// valid on physical register operands. Virtual registers are assumed to + /// always be renamable regardless of the value of this field. + /// + /// Operands that are renamable can freely be changed to any other register + /// that is a member of the register class returned by + /// MI->getRegClassConstraint(). + /// + /// isRenamable can return false for several different reasons: + /// + /// - ABI constraints (since liveness is not always precisely modeled). We + /// conservatively handle these cases by setting all physical register + /// operands that didn’t start out as virtual regs to not be renamable. + /// Also any physical register operands created after register allocation or + /// whose register is changed after register allocation will not be + /// renamable. This state is tracked in the MachineOperand::IsRenamable + /// bit. + /// + /// - Opcode/target constraints: for opcodes that have complex register class + /// requirements (e.g. that depend on other operands/instructions), we set + /// hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq in the machine opcode + /// description. Operands belonging to instructions with opcodes that are + /// marked hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq return false from + /// isRenamable(). Additionally, the AllowRegisterRenaming target property + /// prevents any operands from being marked renamable for targets that don't + /// have detailed opcode hasExtraSrcRegAllocReq/hasExtraDstRegAllocReq + /// values. bool isRenamable() const; bool isInternalRead() const { @@ -473,10 +498,6 @@ class MachineOperand { void setIsRenamable(bool Val = true); - /// Set IsRenamable to true if there are no extra register allocation - /// requirements placed on this operand by the parent instruction's opcode. - void setIsRenamableIfNoExtraRegAllocReq(); - void setIsInternalRead(bool Val = true) { assert(isReg() && "Wrong MachineOperand mutator"); IsInternalRead = Val; diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 82a3be5e63d4..f18784c77739 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -1362,6 +1362,12 @@ class Target { // AssemblyWriters - The AsmWriter instances available for this target. list AssemblyWriters = [DefaultAsmWriter]; + + // AllowRegisterRenaming - Controls whether this target allows + // post-register-allocation renaming of registers. This is done by + // setting hasExtraDefRegAllocReq and hasExtraSrcRegAllocReq to 1 + // for all opcodes if this flag is set to 0. + int AllowRegisterRenaming = 0; } //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index d2d3bc77ac45..98993b2146e4 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -930,8 +930,7 @@ void MachineInstr::clearKillInfo() { void MachineInstr::substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, - const TargetRegisterInfo &RegInfo, - bool ClearIsRenamable) { + const TargetRegisterInfo &RegInfo) { if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { if (SubIdx) ToReg = RegInfo.getSubReg(ToReg, SubIdx); @@ -939,11 +938,8 @@ void MachineInstr::substituteRegister(unsigned FromReg, unsigned ToReg, if (!MO.isReg() || MO.getReg() != FromReg) continue; MO.substPhysReg(ToReg, RegInfo); - if (ClearIsRenamable) - MO.setIsRenamable(false); } } else { - assert(!ClearIsRenamable && "IsRenamable invalid for virtual registers"); for (MachineOperand &MO : operands()) { if (!MO.isReg() || MO.getReg() != FromReg) continue; diff --git a/lib/CodeGen/MachineOperand.cpp b/lib/CodeGen/MachineOperand.cpp index 9122edefac7e..409dd079a3c9 100644 --- a/lib/CodeGen/MachineOperand.cpp +++ b/lib/CodeGen/MachineOperand.cpp @@ -50,6 +50,9 @@ void MachineOperand::setReg(unsigned Reg) { if (getReg() == Reg) return; // No change. + // Clear the IsRenamable bit to keep it conservatively correct. + IsRenamable = false; + // Otherwise, we have to change the register. If this operand is embedded // into a machine function, we need to update the old and new register's // use/def lists. @@ -110,30 +113,27 @@ bool MachineOperand::isRenamable() const { assert(isReg() && "Wrong MachineOperand accessor"); assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && "isRenamable should only be checked on physical registers"); - return IsRenamable; + if (!IsRenamable) + return false; + + const MachineInstr *MI = getParent(); + if (!MI) + return true; + + if (isDef()) + return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle); + + assert(isUse() && "Reg is not def or use"); + return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle); } void MachineOperand::setIsRenamable(bool Val) { assert(isReg() && "Wrong MachineOperand accessor"); assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && "setIsRenamable should only be called on physical registers"); - if (const MachineInstr *MI = getParent()) - if ((isDef() && MI->hasExtraDefRegAllocReq()) || - (isUse() && MI->hasExtraSrcRegAllocReq())) - assert(!Val && "isRenamable should be false for " - "hasExtraDefRegAllocReq/hasExtraSrcRegAllocReq opcodes"); IsRenamable = Val; } -void MachineOperand::setIsRenamableIfNoExtraRegAllocReq() { - if (const MachineInstr *MI = getParent()) - if ((isDef() && MI->hasExtraDefRegAllocReq()) || - (isUse() && MI->hasExtraSrcRegAllocReq())) - return; - - setIsRenamable(true); -} - // If this operand is currently a register operand, and if this is in a // function, deregister the operand from the register's use/def list. void MachineOperand::removeRegFromUses() { diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 3e87dd6a4a30..3b38bbff2152 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -1132,14 +1132,10 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { } } if (MO->isRenamable()) { - if ((MO->isDef() && MI->hasExtraDefRegAllocReq()) || - (MO->isUse() && MI->hasExtraSrcRegAllocReq())) - report("Illegal isRenamable setting for opcode with extra regalloc " - "requirements", - MO, MONum); - if (MRI->isReserved(Reg)) + if (MRI->isReserved(Reg)) { report("isRenamable set on reserved register", MO, MONum); - return; + return; + } } } else { // Virtual register. diff --git a/lib/CodeGen/RegAllocFast.cpp b/lib/CodeGen/RegAllocFast.cpp index 17d9492d942e..7a8d4225ad06 100644 --- a/lib/CodeGen/RegAllocFast.cpp +++ b/lib/CodeGen/RegAllocFast.cpp @@ -699,13 +699,13 @@ bool RegAllocFast::setPhysReg(MachineInstr &MI, unsigned OpNum, bool Dead = MO.isDead(); if (!MO.getSubReg()) { MO.setReg(PhysReg); - MO.setIsRenamableIfNoExtraRegAllocReq(); + MO.setIsRenamable(true); return MO.isKill() || Dead; } // Handle subregister index. MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : 0); - MO.setIsRenamableIfNoExtraRegAllocReq(); + MO.setIsRenamable(true); MO.setSubReg(0); // A kill flag implies killing the full register. Add corresponding super diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 13f7e83f3dd0..cb3b20410209 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -530,7 +530,7 @@ void VirtRegRewriter::rewrite() { // Rewrite. Note we could have used MachineOperand::substPhysReg(), but // we need the inlining here. MO.setReg(PhysReg); - MO.setIsRenamableIfNoExtraRegAllocReq(); + MO.setIsRenamable(true); } // Add any missing super-register kills after rewriting the whole diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index 7e510a1fbd60..e99842bd2e04 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -538,4 +538,5 @@ def AArch64 : Target { let InstructionSet = AArch64InstrInfo; let AssemblyParserVariants = [GenericAsmParserVariant, AppleAsmParserVariant]; let AssemblyWriters = [GenericAsmWriter, AppleAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/AMDGPU/AMDGPU.td b/lib/Target/AMDGPU/AMDGPU.td index c7b3b6dcbf55..d7992180e563 100644 --- a/lib/Target/AMDGPU/AMDGPU.td +++ b/lib/Target/AMDGPU/AMDGPU.td @@ -686,6 +686,7 @@ def AMDGPU : Target { SDWA9AsmParserVariant, DPPAsmParserVariant]; let AssemblyWriters = [AMDGPUAsmWriter]; + let AllowRegisterRenaming = 1; } // Dummy Instruction itineraries for pseudo instructions diff --git a/lib/Target/AMDGPU/SIInsertSkips.cpp b/lib/Target/AMDGPU/SIInsertSkips.cpp index bc8cf5eb1917..331b17bac9a4 100644 --- a/lib/Target/AMDGPU/SIInsertSkips.cpp +++ b/lib/Target/AMDGPU/SIInsertSkips.cpp @@ -278,11 +278,6 @@ void SIInsertSkips::kill(MachineInstr &MI) { .add(MI.getOperand(0)) .addImm(0); // omod } - // Clear isRenamable bit if new opcode requires it to be 0. - if (NewMI->hasExtraSrcRegAllocReq()) - for (MachineOperand &NewMO : NewMI->uses()) - if (NewMO.isReg() && NewMO.isUse()) - NewMO.setIsRenamable(false); break; } case AMDGPU::SI_KILL_I1_TERMINATOR: { diff --git a/lib/Target/AMDGPU/SIInstrFormats.td b/lib/Target/AMDGPU/SIInstrFormats.td index 9e7aea6705f3..5fbee37e3ed7 100644 --- a/lib/Target/AMDGPU/SIInstrFormats.td +++ b/lib/Target/AMDGPU/SIInstrFormats.td @@ -186,6 +186,9 @@ class InstSI pattern = [], string asm = ""> @@ -203,8 +206,6 @@ class VPseudoInstSI pattern = [], string asm = ""> : PseudoInstSI { let VALU = 1; let Uses = [EXEC]; - // Avoid changing source registers in a way that violates constant bus read limitations. - let hasExtraSrcRegAllocReq = 1; } class CFPseudoInstSI pattern = [], diff --git a/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp b/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp index e77c98a72cf0..2dc6f2702b3b 100644 --- a/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp +++ b/lib/Target/AMDGPU/SIOptimizeExecMasking.cpp @@ -246,7 +246,6 @@ bool SIOptimizeExecMasking::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "Fold exec copy: " << *PrepareExecInst); PrepareExecInst->getOperand(0).setReg(AMDGPU::EXEC); - PrepareExecInst->getOperand(0).setIsRenamable(false); DEBUG(dbgs() << "into: " << *PrepareExecInst << '\n'); @@ -353,8 +352,7 @@ bool SIOptimizeExecMasking::runOnMachineFunction(MachineFunction &MF) { for (MachineInstr *OtherInst : OtherUseInsts) { OtherInst->substituteRegister(CopyToExec, AMDGPU::EXEC, - AMDGPU::NoSubRegister, *TRI, - /*ClearIsRenamable=*/true); + AMDGPU::NoSubRegister, *TRI); } } diff --git a/lib/Target/AMDGPU/VOPInstructions.td b/lib/Target/AMDGPU/VOPInstructions.td index dfe18de97be1..520d5dd0f50f 100644 --- a/lib/Target/AMDGPU/VOPInstructions.td +++ b/lib/Target/AMDGPU/VOPInstructions.td @@ -81,8 +81,6 @@ class VOP3_Pseudo pattern = [], let UseNamedOperandTable = 1; let VOP3_OPSEL = isVop3OpSel; let IsPacked = P.IsPacked; - // Avoid changing source registers in a way that violates constant bus read limitations. - let hasExtraSrcRegAllocReq = 1; string Mnemonic = opName; string AsmOperands = !if(isVop3OpSel, diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index 705cfe0d3383..ecb2ef2351d0 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -1043,4 +1043,5 @@ def ARM : Target { let AssemblyWriters = [ARMAsmWriter]; let AssemblyParsers = [ARMAsmParser]; let AssemblyParserVariants = [ARMAsmParserVariant]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 03fbd7748cdb..d299024e5018 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1378,7 +1378,6 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { MachineInstrBuilder LDM, STM; if (isThumb1 || !MI->getOperand(1).isDead()) { MachineOperand LDWb(MI->getOperand(1)); - LDWb.setIsRenamable(false); LDM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA_UPD : isThumb1 ? ARM::tLDMIA_UPD : ARM::LDMIA_UPD)) @@ -1389,7 +1388,6 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { if (isThumb1 || !MI->getOperand(0).isDead()) { MachineOperand STWb(MI->getOperand(0)); - STWb.setIsRenamable(false); STM = BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA_UPD : isThumb1 ? ARM::tSTMIA_UPD : ARM::STMIA_UPD)) @@ -1399,11 +1397,9 @@ void ARMBaseInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const { } MachineOperand LDBase(MI->getOperand(3)); - LDBase.setIsRenamable(false); LDM.add(LDBase).add(predOps(ARMCC::AL)); MachineOperand STBase(MI->getOperand(2)); - STBase.setIsRenamable(false); STM.add(STBase).add(predOps(ARMCC::AL)); // Sort the scratch registers into ascending order. diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index b14b2c6a813f..9e6bfbc36481 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -608,7 +608,6 @@ void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI, MIB.add(MI.getOperand(OpIdx++)); if (IsExt) { MachineOperand VdSrc(MI.getOperand(OpIdx++)); - VdSrc.setIsRenamable(false); MIB.add(VdSrc); } @@ -620,7 +619,6 @@ void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI, // Copy the other source register operand. MachineOperand VmSrc(MI.getOperand(OpIdx++)); - VmSrc.setIsRenamable(false); MIB.add(VmSrc); // Copy the predicate operands. @@ -1470,7 +1468,6 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, // Copy the destination register. MachineOperand Dst(MI.getOperand(OpIdx++)); - Dst.setIsRenamable(false); MIB.add(Dst); // Copy the predicate operands. diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 19afaed5a415..c5629b99dd6c 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -9196,8 +9196,6 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, // Thumb1 post-indexed loads are really just single-register LDMs. case ARM::tLDR_postidx: { MachineOperand Def(MI.getOperand(1)); - if (TargetRegisterInfo::isPhysicalRegister(Def.getReg())) - Def.setIsRenamable(false); BuildMI(*BB, MI, dl, TII->get(ARM::tLDMIA_UPD)) .add(Def) // Rn_wb .add(MI.getOperand(2)) // Rn diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td index 169704cbfba0..e1f3dec59f79 100644 --- a/lib/Target/Hexagon/Hexagon.td +++ b/lib/Target/Hexagon/Hexagon.td @@ -359,4 +359,5 @@ def Hexagon : Target { let AssemblyParsers = [HexagonAsmParser]; let AssemblyParserVariants = [HexagonAsmParserVariant]; let AssemblyWriters = [HexagonAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/Hexagon/RDFCopy.cpp b/lib/Target/Hexagon/RDFCopy.cpp index 212f75c746ca..4339fa2089d9 100644 --- a/lib/Target/Hexagon/RDFCopy.cpp +++ b/lib/Target/Hexagon/RDFCopy.cpp @@ -101,7 +101,6 @@ NodeId CopyPropagation::getLocalReachingDef(RegisterRef RefRR, bool CopyPropagation::run() { scanBlock(&DFG.getMF().front()); - MachineRegisterInfo &MRI = DFG.getMF().getRegInfo(); if (trace()) { dbgs() << "Copies:\n"; @@ -181,8 +180,6 @@ bool CopyPropagation::run() { unsigned NewReg = MinPhysReg(SR); Op.setReg(NewReg); Op.setSubReg(0); - if (MRI.isReserved(NewReg)) - Op.setIsRenamable(false); DFG.unlinkUse(UA, false); if (AtCopy != 0) { UA.Addr->linkToDef(UA.Id, DFG.addr(AtCopy)); diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index f8e739497f4c..4a99a9fe603f 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -242,4 +242,5 @@ def Mips : Target { let InstructionSet = MipsInstrInfo; let AssemblyParsers = [MipsAsmParser]; let AssemblyParserVariants = [MipsAsmParserVariant]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/PowerPC/PPC.td b/lib/Target/PowerPC/PPC.td index 46502208b175..24abe7a85228 100644 --- a/lib/Target/PowerPC/PPC.td +++ b/lib/Target/PowerPC/PPC.td @@ -465,4 +465,5 @@ def PPC : Target { let AssemblyParsers = [PPCAsmParser]; let AssemblyParserVariants = [PPCAsmParserVariant]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/RISCV/RISCV.td b/lib/Target/RISCV/RISCV.td index 4caaaa43c10b..3e80d745b827 100644 --- a/lib/Target/RISCV/RISCV.td +++ b/lib/Target/RISCV/RISCV.td @@ -92,4 +92,5 @@ def RISCV : Target { let InstructionSet = RISCVInstrInfo; let AssemblyParsers = [RISCVAsmParser]; let AssemblyWriters = [RISCVAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/Sparc/Sparc.td b/lib/Target/Sparc/Sparc.td index 9e0a297c8812..dbe763f08445 100644 --- a/lib/Target/Sparc/Sparc.td +++ b/lib/Target/Sparc/Sparc.td @@ -176,4 +176,5 @@ def Sparc : Target { let InstructionSet = SparcInstrInfo; let AssemblyParsers = [SparcAsmParser]; let AssemblyWriters = [SparcAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/SystemZ/SystemZ.td b/lib/Target/SystemZ/SystemZ.td index 06905fb41e44..3800f7a26b79 100644 --- a/lib/Target/SystemZ/SystemZ.td +++ b/lib/Target/SystemZ/SystemZ.td @@ -75,4 +75,5 @@ def SystemZAsmParser : AsmParser { def SystemZ : Target { let InstructionSet = SystemZInstrInfo; let AssemblyParsers = [SystemZAsmParser]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 649851aefeaa..a701788e59c5 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -1130,4 +1130,5 @@ def X86 : Target { let InstructionSet = X86InstrInfo; let AssemblyParserVariants = [ATTAsmParserVariant, IntelAsmParserVariant]; let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter]; + let AllowRegisterRenaming = 1; } diff --git a/lib/Target/X86/X86FloatingPoint.cpp b/lib/Target/X86/X86FloatingPoint.cpp index 6a13367e3ce7..9a72e7114be0 100644 --- a/lib/Target/X86/X86FloatingPoint.cpp +++ b/lib/Target/X86/X86FloatingPoint.cpp @@ -1383,7 +1383,6 @@ void FPS::handleCompareFP(MachineBasicBlock::iterator &I) { // Change from the pseudo instruction to the concrete instruction. MI.getOperand(0).setReg(getSTReg(Op1)); - MI.getOperand(0).setIsRenamable(false); MI.RemoveOperand(1); MI.setDesc(TII->get(getConcreteOpcode(MI.getOpcode()))); @@ -1411,7 +1410,6 @@ void FPS::handleCondMovFP(MachineBasicBlock::iterator &I) { MI.RemoveOperand(0); MI.RemoveOperand(1); MI.getOperand(0).setReg(getSTReg(Op1)); - MI.getOperand(0).setIsRenamable(false); MI.setDesc(TII->get(getConcreteOpcode(MI.getOpcode()))); // If we kill the second operand, make sure to pop it from the stack. @@ -1628,7 +1626,6 @@ void FPS::handleSpecialFP(MachineBasicBlock::iterator &Inst) { else // Operand with a single register class constraint ("t" or "u"). Op.setReg(X86::ST0 + FPReg); - Op.setIsRenamable(false); } // Simulate the inline asm popping its inputs and pushing its outputs. diff --git a/test/CodeGen/AMDGPU/postra-norename.mir b/test/CodeGen/AMDGPU/postra-norename.mir new file mode 100644 index 000000000000..4e10cf3b3e6a --- /dev/null +++ b/test/CodeGen/AMDGPU/postra-norename.mir @@ -0,0 +1,13 @@ +# RUN: llc -march=amdgcn -mcpu=gfx900 -run-pass postrapseudos %s -o - | FileCheck -check-prefix=GCN %s + +# Check that post-RA expanded COPY doesn't have renamable operands +# since V_MOV_B32_e32 has hasExtraSrcRegAllocReq set. +# GCN-LABEL: name: test1 +# GCN: $vgpr1 = V_MOV_B32_e32 $vgpr0, implicit $exec +name: test1 +tracksRegLiveness: true +body: | + bb.0: + liveins: $vgpr0 + renamable $vgpr1 = COPY renamable $vgpr0 +... diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 2f1f20d47720..451d305e5c5e 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -224,6 +224,9 @@ Record *CodeGenTarget::getInstructionSet() const { return TargetRec->getValueAsDef("InstructionSet"); } +bool CodeGenTarget::getAllowRegisterRenaming() const { + return TargetRec->getValueAsInt("AllowRegisterRenaming"); +} /// getAsmParser - Return the AssemblyParser definition for this target. /// diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 4d5a0ed685c6..c38f92bb979a 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -77,6 +77,11 @@ class CodeGenTarget { /// Record *getInstructionSet() const; + /// getAllowRegisterRenaming - Return the AllowRegisterRenaming flag value for + /// this target. + /// + bool getAllowRegisterRenaming() const; + /// getAsmParser - Return the AssemblyParser definition for this target. /// Record *getAsmParser() const; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 379e3245d066..b9bc43122b23 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -480,6 +480,8 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, << Inst.TheDef->getValueAsInt("Size") << ",\t" << SchedModels.getSchedClassIdx(Inst) << ",\t0"; + CodeGenTarget &Target = CDP.getTargetInfo(); + // Emit all of the target independent flags... if (Inst.isPseudo) OS << "|(1ULL<second; - CodeGenTarget &Target = CDP.getTargetInfo(); if (Inst.HasComplexDeprecationPredicate) // Emit a function pointer to the complex predicate method. OS << ", -1 "