https://github.com/bwendling updated https://github.com/llvm/llvm-project/pull/66958
>From ed8d57d182510f2d33ad4fe78cd88c717cefbd47 Mon Sep 17 00:00:00 2001 From: Bill Wendling <mo...@google.com> Date: Wed, 20 Sep 2023 15:11:00 -0700 Subject: [PATCH 1/2] [NFC][CodeGen] Create method to clear registers Place the architecuture-specific logic to clear registers in a single place and call it via a TargetInstrInfo method. --- llvm/include/llvm/CodeGen/TargetInstrInfo.h | 7 +++ .../Target/AArch64/AArch64FrameLowering.cpp | 9 +--- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 20 ++++++++ llvm/lib/Target/AArch64/AArch64InstrInfo.h | 5 ++ llvm/lib/Target/X86/X86FrameLowering.cpp | 39 ++------------- llvm/lib/Target/X86/X86InstrInfo.cpp | 50 +++++++++++++++++++ llvm/lib/Target/X86/X86InstrInfo.h | 4 ++ 7 files changed, 92 insertions(+), 42 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index d55250bd04ab3e7..14a5a468d2df96a 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -2046,6 +2046,13 @@ class TargetInstrInfo : public MCInstrInfo { "Target didn't implement TargetInstrInfo::buildOutlinedFrame!"); } + virtual void buildClearRegister(Register Reg, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const { + llvm_unreachable( + "Target didn't implement TargetInstrInfo::buildClearRegister!"); + } + /// Insert a call to an outlined function into the program. /// Returns an iterator to the spot where we inserted the call. This must be /// implemented by the target. diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp index 68e68449d4073b2..435b095936f6eaf 100644 --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -786,16 +786,11 @@ void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero, // Zero out GPRs. for (MCRegister Reg : GPRsToZero.set_bits()) - BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), Reg).addImm(0); + TII.buildClearRegister(Reg, MBB, MBBI, DL); // Zero out FP/vector registers. for (MCRegister Reg : FPRsToZero.set_bits()) - if (HasSVE) - BuildMI(MBB, MBBI, DL, TII.get(AArch64::DUP_ZI_D), Reg) - .addImm(0) - .addImm(0); - else - BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVIv2d_ns), Reg).addImm(0); + TII.buildClearRegister(Reg, MBB, MBBI, DL); if (HasSVE) { for (MCRegister PReg : diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index bceea75f278221a..76f3af620b026fb 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -8329,6 +8329,26 @@ bool AArch64InstrInfo::shouldOutlineFromFunctionByDefault( return MF.getFunction().hasMinSize(); } +void AArch64InstrInfo::buildClearRegister(Register Reg, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const { + const MachineFunction &MF = *MBB.getParent(); + const AArch64Subtarget &STI = MF.getSubtarget<AArch64Subtarget>(); + const AArch64RegisterInfo &TRI = *STI.getRegisterInfo(); + + if (TRI.isGeneralPurposeRegister(MF, Reg)) { + BuildMI(MBB, Iter, DL, get(AArch64::MOVi64imm), Reg) + .addImm(0); + } else if (STI.hasSVE()) { + BuildMI(MBB, Iter, DL, get(AArch64::DUP_ZI_D), Reg) + .addImm(0) + .addImm(0); + } else { + BuildMI(MBB, Iter, DL, get(AArch64::MOVIv2d_ns), Reg) + .addImm(0); + } +} + std::optional<DestSourcePair> AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index 2cd028d263f694d..4a4d87c1b1f6ba5 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -318,6 +318,11 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo { MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override; bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override; + + void buildClearRegister(Register Reg, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const override; + /// Returns the vector element size (B, H, S or D) of an SVE opcode. uint64_t getElementSizeForOpcode(unsigned Opc) const; /// Returns true if the opcode is for an SVE instruction that sets the diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index a5a4f91299f3d8a..bd261c760d9301a 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -562,48 +562,17 @@ void X86FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero, RegsToZero.reset(Reg); } + // Zero out the GPRs first. for (MCRegister Reg : GPRsToZero.set_bits()) - BuildMI(MBB, MBBI, DL, TII.get(X86::XOR32rr), Reg) - .addReg(Reg, RegState::Undef) - .addReg(Reg, RegState::Undef); + TII.buildClearRegister(Reg, MBB, MBBI, DL); - // Zero out registers. + // Zero out the remaining registers. for (MCRegister Reg : RegsToZero.set_bits()) { if (ST.hasMMX() && X86::VR64RegClass.contains(Reg)) // FIXME: Ignore MMX registers? continue; - unsigned XorOp; - if (X86::VR128RegClass.contains(Reg)) { - // XMM# - if (!ST.hasSSE1()) - continue; - XorOp = X86::PXORrr; - } else if (X86::VR256RegClass.contains(Reg)) { - // YMM# - if (!ST.hasAVX()) - continue; - XorOp = X86::VPXORrr; - } else if (X86::VR512RegClass.contains(Reg)) { - // ZMM# - if (!ST.hasAVX512()) - continue; - XorOp = X86::VPXORYrr; - } else if (X86::VK1RegClass.contains(Reg) || - X86::VK2RegClass.contains(Reg) || - X86::VK4RegClass.contains(Reg) || - X86::VK8RegClass.contains(Reg) || - X86::VK16RegClass.contains(Reg)) { - if (!ST.hasVLX()) - continue; - XorOp = ST.hasBWI() ? X86::KXORQrr : X86::KXORWrr; - } else { - continue; - } - - BuildMI(MBB, MBBI, DL, TII.get(XorOp), Reg) - .addReg(Reg, RegState::Undef) - .addReg(Reg, RegState::Undef); + TII.buildClearRegister(Reg, MBB, MBBI, DL); } } diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 205fd24e6d40295..a405e5810c3de7f 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -9796,6 +9796,56 @@ X86InstrInfo::insertOutlinedCall(Module &M, MachineBasicBlock &MBB, return It; } +void X86InstrInfo::buildClearRegister(Register Reg, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const { + const MachineFunction &MF = *MBB.getParent(); + const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>(); + const TargetRegisterInfo &TRI = getRegisterInfo(); + + if (TRI.isGeneralPurposeRegister(MF, Reg)) { + BuildMI(MBB, Iter, DL, get(X86::XOR32rr), Reg) + .addReg(Reg, RegState::Undef) + .addReg(Reg, RegState::Undef); + } else if (X86::VR128RegClass.contains(Reg)) { + // XMM# + if (!ST.hasSSE1()) + return; + + BuildMI(MBB, Iter, DL, get(X86::PXORrr), Reg) + .addReg(Reg, RegState::Undef) + .addReg(Reg, RegState::Undef); + } else if (X86::VR256RegClass.contains(Reg)) { + // YMM# + if (!ST.hasAVX()) + return; + + BuildMI(MBB, Iter, DL, get(X86::VPXORrr), Reg) + .addReg(Reg, RegState::Undef) + .addReg(Reg, RegState::Undef); + } else if (X86::VR512RegClass.contains(Reg)) { + // ZMM# + if (!ST.hasAVX512()) + return; + + BuildMI(MBB, Iter, DL, get(X86::VPXORYrr), Reg) + .addReg(Reg, RegState::Undef) + .addReg(Reg, RegState::Undef); + } else if (X86::VK1RegClass.contains(Reg) || + X86::VK2RegClass.contains(Reg) || + X86::VK4RegClass.contains(Reg) || + X86::VK8RegClass.contains(Reg) || + X86::VK16RegClass.contains(Reg)) { + if (!ST.hasVLX()) + return; + + BuildMI(MBB, Iter, DL, get(ST.hasBWI() ? X86::KXORQrr : X86::KXORWrr), Reg) + .addReg(Reg, RegState::Undef) + .addReg(Reg, RegState::Undef); + } +} + bool X86InstrInfo::getMachineCombinerPatterns( MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns, bool DoRegPressureReduce) const { diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h index 9a072c6569fe978..8119302f73e8b36 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -573,6 +573,10 @@ class X86InstrInfo final : public X86GenInstrInfo { MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override; + void buildClearRegister(Register Reg, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const override; + bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override; #define GET_INSTRINFO_HELPER_DECLS >From 124727036eddf473ed3f57e7ce041011fb3f7877 Mon Sep 17 00:00:00 2001 From: Bill Wendling <5993918+bwendl...@users.noreply.github.com> Date: Wed, 20 Sep 2023 15:22:57 -0700 Subject: [PATCH 2/2] Update TargetInstrInfo.h Add comment and move declaration. --- llvm/include/llvm/CodeGen/TargetInstrInfo.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/llvm/include/llvm/CodeGen/TargetInstrInfo.h index 14a5a468d2df96a..04859a50d6fdeb4 100644 --- a/llvm/include/llvm/CodeGen/TargetInstrInfo.h +++ b/llvm/include/llvm/CodeGen/TargetInstrInfo.h @@ -2046,13 +2046,6 @@ class TargetInstrInfo : public MCInstrInfo { "Target didn't implement TargetInstrInfo::buildOutlinedFrame!"); } - virtual void buildClearRegister(Register Reg, MachineBasicBlock &MBB, - MachineBasicBlock::iterator Iter, - DebugLoc &DL) const { - llvm_unreachable( - "Target didn't implement TargetInstrInfo::buildClearRegister!"); - } - /// Insert a call to an outlined function into the program. /// Returns an iterator to the spot where we inserted the call. This must be /// implemented by the target. @@ -2064,6 +2057,14 @@ class TargetInstrInfo : public MCInstrInfo { "Target didn't implement TargetInstrInfo::insertOutlinedCall!"); } + /// Insert an architecture-specific instruction to clear a register. + virtual void buildClearRegister(Register Reg, MachineBasicBlock &MBB, + MachineBasicBlock::iterator Iter, + DebugLoc &DL) const { + llvm_unreachable( + "Target didn't implement TargetInstrInfo::buildClearRegister!"); + } + /// Return true if the function can safely be outlined from. /// A function \p MF is considered safe for outlining if an outlined function /// produced from instructions in F will produce a program which produces the _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits