Skip to content

Commit

Permalink
Ensure spillmap entries are properly killed where necessary.
Browse files Browse the repository at this point in the history
In a couple of places we were failing to clear associations between
locations where an MIR instruction defined or killed a register. This
lead to us deopting dead stale values at runtime.

Co-authored-by: Lukas Diekmann <[email protected]>
  • Loading branch information
vext01 and ptersilie committed Dec 13, 2024
1 parent 3549259 commit 61c1f9a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 9 deletions.
36 changes: 30 additions & 6 deletions llvm/lib/Target/X86/X86AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetMachine.h"

#include <map>
#include <cstdint>
#include <set>

Expand All @@ -62,6 +63,7 @@ X86AsmPrinter::X86AsmPrinter(TargetMachine &TM,

const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const MCRegisterInfo *MRI;

/// Clear any mappings that map to the given register.
void clearRhs(Register Reg, std::map<Register, std::set<int64_t>> &SpillMap) {
Expand All @@ -82,6 +84,12 @@ void clearOffset(unsigned int Reg, int Offset, std::map<Register, std::set<int64
}
}

/// Remove all mentions of the DWARF register `DwReg` from `SpillMap`.
void killRegister(const Register DwReg, std::map<Register, std::set<int64_t>> &SpillMap) {
SpillMap.erase(DwReg);
clearRhs(DwReg, SpillMap);
}

/// Given a MachineBasicBlock, analyse its instructions to build a mapping of
/// where duplicate values live. This can be either in another register or on
/// the stack. Since registers are always positive and stack offsets negative,
Expand All @@ -98,13 +106,25 @@ void processInstructions(
// encoded in the stackmap when it is lowered.
if (Instr.getOpcode() == TargetOpcode::STACKMAP) {
StackmapSpillMaps[&Instr] = SpillMap;
for (const MachineOperand MO : Instr.uses()) {
if (MO.isReg() && MO.isKill()) {
auto DwReg = getDwarfRegNum(MO.getReg(), TRI);
killRegister(DwReg, SpillMap);
}
}
continue;
}

// Because a patchpoint already captures the live values at the exact
// moment we desire, there's no need to compute a spillmap for them nor do
// we have to "patch them up". We can just skip them.
if (Instr.getOpcode() == TargetOpcode::PATCHPOINT) {
for (const MachineOperand MO : Instr.uses()) {
if (MO.isReg() && MO.isKill()) {
auto DwReg = getDwarfRegNum(MO.getReg(), TRI);
killRegister(DwReg, SpillMap);
}
}
continue;
}

Expand Down Expand Up @@ -133,6 +153,9 @@ void processInstructions(
SpillMap[LhsDwReg].insert(Other.begin(), Other.end());
// Also add Lhs to the mapping of Rhs.
SpillMap[RhsDwReg].insert(LhsDwReg);
if (Rhs.isKill()) {
killRegister(RhsDwReg, SpillMap);
}
continue;
}

Expand Down Expand Up @@ -175,18 +198,18 @@ void processInstructions(
for (const MachineOperand MO : Instr.defs()) {
assert(MO.isReg() && "Is register.");
auto DwReg = getDwarfRegNum(MO.getReg(), TRI);
SpillMap.erase(DwReg);
clearRhs(DwReg, SpillMap);
killRegister(DwReg, SpillMap);
}

// Delete registers that are "killed" (no longer live) after this
// intsruction. This prevents us deopting values at runtime that will never
// be used.
for (const MachineOperand MO : Instr.uses()) {
if (MO.isReg() && MO.isKill()) {
auto DwReg = getDwarfRegNum(MO.getReg(), TRI);
SpillMap.erase(DwReg);
clearRhs(DwReg, SpillMap);
if (MO.isReg() && (MO.isKill() || MO.isDef())) {
int DwReg = MRI->getDwarfRegNum(MO.getReg(), false);
if (DwReg >= 0) {
killRegister(DwReg, SpillMap);
}
}
}
}
Expand Down Expand Up @@ -218,6 +241,7 @@ void findSpillLocations(
///
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
TRI = MF.getSubtarget().getRegisterInfo();
MRI = TM.getMCRegisterInfo();
Subtarget = &MF.getSubtarget<X86Subtarget>();

SMShadowTracker.startFunction(MF);
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/CodeGen/X86/yk-stackmaps-extrareg.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@
; NOTE: Reserved
; CHECK-NEXT: .short 0
; NOTE: Number of extra locations.
; CHECK-NEXT: .short 2
; CHECK-NEXT: .short 1
; NOTE: Stack offset this value is stored in.
; CHECK-NEXT: .short -80
; NOTE: Extra register this value is stored in.
; CHECK-NEXT: .short 8

source_filename = "ld-temp.o"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
Expand Down

0 comments on commit 61c1f9a

Please sign in to comment.