Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NFC][CodeGen] Create method to clear registers #66958

Merged
merged 4 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/include/llvm/CodeGen/TargetInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2057,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,
nickdesaulniers marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
9 changes: 2 additions & 7 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 :
Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8329,6 +8329,26 @@ bool AArch64InstrInfo::shouldOutlineFromFunctionByDefault(
return MF.getFunction().hasMinSize();
}

void AArch64InstrInfo::buildClearRegister(Register Reg, MachineBasicBlock &MBB,
nickdesaulniers marked this conversation as resolved.
Show resolved Hide resolved
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 {

Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 4 additions & 35 deletions llvm/lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
bwendling marked this conversation as resolved.
Show resolved Hide resolved

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);
}
}

Expand Down
50 changes: 50 additions & 0 deletions llvm/lib/Target/X86/X86InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/X86/X86InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down