[clang] [NFC][CodeGen] Create method to clear registers (PR #66958)
Bill Wendling via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 21 12:02:56 PDT 2023
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 <morbo at 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+bwendling at 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
More information about the cfe-commits
mailing list