Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -1275,7 +1275,7 @@ /// Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. - void setDesc(const MCInstrDesc &tid) { MCID = &tid; } + void setDesc(const MCInstrDesc &tid); /// Replace current source information with new such. /// Avoid using this, the constructor argument is preferable. Index: include/llvm/CodeGen/MachineOperand.h =================================================================== --- include/llvm/CodeGen/MachineOperand.h +++ include/llvm/CodeGen/MachineOperand.h @@ -110,6 +110,26 @@ /// 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 with this bit set, can freely be changed to any other register + /// that is a member of the register class returned by + /// MI->getRegClassConstraint(). + /// + /// The renamable flag can be set to 0 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 + /// will have renamable set to 0 by default. + /// + /// - 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, and set renamable to 0 for these operands. Additionally, + /// the xxxgcb property prevents any operands from being marked renamable + /// for targets that don't have detailed opcode hasExtraSrcRegAllocReq + /// values. unsigned IsRenamable : 1; /// IsUndef - True if this register operand reads an "undef" value, i.e. the Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -1362,6 +1362,12 @@ // 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; } //===----------------------------------------------------------------------===// Index: lib/CodeGen/MachineInstr.cpp =================================================================== --- lib/CodeGen/MachineInstr.cpp +++ lib/CodeGen/MachineInstr.cpp @@ -180,6 +180,20 @@ addOperand(*MF, Op); } +void MachineInstr::setDesc(const MCInstrDesc &tid) { + MCID = &tid; + if (hasExtraDefRegAllocReq()) + for (MachineOperand &MO : defs()) + if (MO.isReg() && MO.isDef() && + TargetRegisterInfo::isPhysicalRegister(MO.getReg())) + MO.setIsRenamable(false); + if (hasExtraSrcRegAllocReq()) + for (MachineOperand &MO : uses()) + if (MO.isReg() && MO.isUse() && + TargetRegisterInfo::isPhysicalRegister(MO.getReg())) + MO.setIsRenamable(false); +} + /// Move NumOps MachineOperands from Src to Dst, with support for overlapping /// ranges. If MRI is non-null also update use-def chains. static void moveOperands(MachineOperand *Dst, MachineOperand *Src, Index: lib/Target/AArch64/AArch64.td =================================================================== --- lib/Target/AArch64/AArch64.td +++ lib/Target/AArch64/AArch64.td @@ -538,4 +538,5 @@ let InstructionSet = AArch64InstrInfo; let AssemblyParserVariants = [GenericAsmParserVariant, AppleAsmParserVariant]; let AssemblyWriters = [GenericAsmWriter, AppleAsmWriter]; + let AllowRegisterRenaming = 1; } Index: lib/Target/AMDGPU/AMDGPU.td =================================================================== --- lib/Target/AMDGPU/AMDGPU.td +++ lib/Target/AMDGPU/AMDGPU.td @@ -691,6 +691,7 @@ SDWA9AsmParserVariant, DPPAsmParserVariant]; let AssemblyWriters = [AMDGPUAsmWriter]; + let AllowRegisterRenaming = 1; } // Dummy Instruction itineraries for pseudo instructions Index: lib/Target/ARM/ARM.td =================================================================== --- lib/Target/ARM/ARM.td +++ lib/Target/ARM/ARM.td @@ -1043,4 +1043,5 @@ let AssemblyWriters = [ARMAsmWriter]; let AssemblyParsers = [ARMAsmParser]; let AssemblyParserVariants = [ARMAsmParserVariant]; + let AllowRegisterRenaming = 1; } Index: lib/Target/Hexagon/Hexagon.td =================================================================== --- lib/Target/Hexagon/Hexagon.td +++ lib/Target/Hexagon/Hexagon.td @@ -358,4 +358,5 @@ let AssemblyParsers = [HexagonAsmParser]; let AssemblyParserVariants = [HexagonAsmParserVariant]; let AssemblyWriters = [HexagonAsmWriter]; + let AllowRegisterRenaming = 1; } Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -238,4 +238,5 @@ let InstructionSet = MipsInstrInfo; let AssemblyParsers = [MipsAsmParser]; let AssemblyParserVariants = [MipsAsmParserVariant]; + let AllowRegisterRenaming = 1; } Index: lib/Target/PowerPC/PPC.td =================================================================== --- lib/Target/PowerPC/PPC.td +++ lib/Target/PowerPC/PPC.td @@ -465,4 +465,5 @@ let AssemblyParsers = [PPCAsmParser]; let AssemblyParserVariants = [PPCAsmParserVariant]; + let AllowRegisterRenaming = 1; } Index: lib/Target/RISCV/RISCV.td =================================================================== --- lib/Target/RISCV/RISCV.td +++ lib/Target/RISCV/RISCV.td @@ -92,4 +92,5 @@ let InstructionSet = RISCVInstrInfo; let AssemblyParsers = [RISCVAsmParser]; let AssemblyWriters = [RISCVAsmWriter]; + let AllowRegisterRenaming = 1; } Index: lib/Target/Sparc/Sparc.td =================================================================== --- lib/Target/Sparc/Sparc.td +++ lib/Target/Sparc/Sparc.td @@ -176,4 +176,5 @@ let InstructionSet = SparcInstrInfo; let AssemblyParsers = [SparcAsmParser]; let AssemblyWriters = [SparcAsmWriter]; + let AllowRegisterRenaming = 1; } Index: lib/Target/SystemZ/SystemZ.td =================================================================== --- lib/Target/SystemZ/SystemZ.td +++ lib/Target/SystemZ/SystemZ.td @@ -75,4 +75,5 @@ def SystemZ : Target { let InstructionSet = SystemZInstrInfo; let AssemblyParsers = [SystemZAsmParser]; + let AllowRegisterRenaming = 1; } Index: lib/Target/X86/X86.td =================================================================== --- lib/Target/X86/X86.td +++ lib/Target/X86/X86.td @@ -1124,4 +1124,5 @@ let InstructionSet = X86InstrInfo; let AssemblyParserVariants = [ATTAsmParserVariant, IntelAsmParserVariant]; let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter]; + let AllowRegisterRenaming = 1; } Index: utils/TableGen/CodeGenTarget.h =================================================================== --- utils/TableGen/CodeGenTarget.h +++ utils/TableGen/CodeGenTarget.h @@ -77,6 +77,11 @@ /// 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; Index: utils/TableGen/CodeGenTarget.cpp =================================================================== --- utils/TableGen/CodeGenTarget.cpp +++ utils/TableGen/CodeGenTarget.cpp @@ -224,6 +224,9 @@ return TargetRec->getValueAsDef("InstructionSet"); } +bool CodeGenTarget::getAllowRegisterRenaming() const { + return TargetRec->getValueAsInt("AllowRegisterRenaming"); +} /// getAsmParser - Return the AssemblyParser definition for this target. /// Index: utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- utils/TableGen/InstrInfoEmitter.cpp +++ utils/TableGen/InstrInfoEmitter.cpp @@ -480,6 +480,8 @@ << 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 "