[GlobalISel] Propagate PCSections metadata to MachineInstr

Propagate (most) PC sections metadata to MachineInstr when GlobalISel is
doing instruction selection.

This change results in support for architectures using GlobalISel (such
as -O0 with AArch64). Not all instructions may be supported yet, and
requires further target-specific handling (such as done for AArch64
pseudo-atomics). Expanding supported instructions is planned on a
case-by-case basis and new use cases for PC sections metadata.

Reviewed By: vitalybuka

Differential Revision: https://reviews.llvm.org/D130886
This commit is contained in:
Marco Elver 2022-09-06 15:49:23 +02:00
parent f0d6709e4a
commit 31a548021b
5 changed files with 32 additions and 22 deletions

View File

@ -865,7 +865,7 @@ bool InstructionSelector::executeMatchTable(
OutMIs.resize(NewInsnID + 1);
OutMIs[NewInsnID] = BuildMI(*State.MIs[0]->getParent(), State.MIs[0],
State.MIs[0]->getDebugLoc(), TII.get(Opcode));
MIMetadata(*State.MIs[0]), TII.get(Opcode));
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
dbgs() << CurrentIdx << ": GIR_BuildMI(OutMIs["
<< NewInsnID << "], " << Opcode << ")\n");

View File

@ -50,6 +50,8 @@ struct MachineIRBuilderState {
MachineRegisterInfo *MRI = nullptr;
/// Debug location to be set to any instruction we create.
DebugLoc DL;
/// PC sections metadata to be set to any instruction we create.
MDNode *PCSections = nullptr;
/// \name Fields describing the insertion point.
/// @{
@ -341,6 +343,7 @@ public:
assert(MI.getParent() && "Instruction is not part of a basic block");
setMBB(*MI.getParent());
State.II = MI.getIterator();
setPCSections(MI.getPCSections());
}
/// @}
@ -364,6 +367,12 @@ public:
/// Get the current instruction's debug location.
const DebugLoc &getDebugLoc() { return State.DL; }
/// Set the PC sections metadata to \p MD for all the next build instructions.
void setPCSections(MDNode *MD) { State.PCSections = MD; }
/// Get the current instruction's PC sections metadata.
MDNode *getPCSections() { return State.PCSections; }
/// Build and insert <empty> = \p Opcode <empty>.
/// The insertion point is the one set by the last call of either
/// setBasicBlock or setMI.

View File

@ -3008,6 +3008,7 @@ void IRTranslator::finishPendingPhis() {
bool IRTranslator::translate(const Instruction &Inst) {
CurBuilder->setDebugLoc(Inst.getDebugLoc());
CurBuilder->setPCSections(Inst.getMetadata(LLVMContext::MD_pcsections));
auto &TLI = *MF->getSubtarget().getTargetLowering();
if (TLI.fallBackToDAGISel(Inst))

View File

@ -27,6 +27,7 @@ void MachineIRBuilder::setMF(MachineFunction &MF) {
State.MRI = &MF.getRegInfo();
State.TII = MF.getSubtarget().getInstrInfo();
State.DL = DebugLoc();
State.PCSections = nullptr;
State.II = MachineBasicBlock::iterator();
State.Observer = nullptr;
}
@ -36,8 +37,7 @@ void MachineIRBuilder::setMF(MachineFunction &MF) {
//------------------------------------------------------------------------------
MachineInstrBuilder MachineIRBuilder::buildInstrNoInsert(unsigned Opcode) {
MachineInstrBuilder MIB = BuildMI(getMF(), getDL(), getTII().get(Opcode));
return MIB;
return BuildMI(getMF(), {getDL(), getPCSections()}, getTII().get(Opcode));
}
MachineInstrBuilder MachineIRBuilder::insertInstr(MachineInstrBuilder MIB) {

View File

@ -186,7 +186,7 @@ bool AArch64ExpandPseudo::expandCMP_SWAP(
unsigned StlrOp, unsigned CmpOp, unsigned ExtendImm, unsigned ZeroReg,
MachineBasicBlock::iterator &NextMBBI) {
MachineInstr &MI = *MBBI;
DebugLoc DL = MI.getDebugLoc();
MIMetadata MIMD(MI);
const MachineOperand &Dest = MI.getOperand(0);
Register StatusReg = MI.getOperand(1).getReg();
bool StatusDead = MI.getOperand(1).isDead();
@ -212,15 +212,15 @@ bool AArch64ExpandPseudo::expandCMP_SWAP(
// cmp xDest, xDesired
// b.ne .Ldone
if (!StatusDead)
BuildMI(LoadCmpBB, DL, TII->get(AArch64::MOVZWi), StatusReg)
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::MOVZWi), StatusReg)
.addImm(0).addImm(0);
BuildMI(LoadCmpBB, DL, TII->get(LdarOp), Dest.getReg())
BuildMI(LoadCmpBB, MIMD, TII->get(LdarOp), Dest.getReg())
.addReg(AddrReg);
BuildMI(LoadCmpBB, DL, TII->get(CmpOp), ZeroReg)
BuildMI(LoadCmpBB, MIMD, TII->get(CmpOp), ZeroReg)
.addReg(Dest.getReg(), getKillRegState(Dest.isDead()))
.addReg(DesiredReg)
.addImm(ExtendImm);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::Bcc))
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::Bcc))
.addImm(AArch64CC::NE)
.addMBB(DoneBB)
.addReg(AArch64::NZCV, RegState::Implicit | RegState::Kill);
@ -230,10 +230,10 @@ bool AArch64ExpandPseudo::expandCMP_SWAP(
// .Lstore:
// stlxr wStatus, xNew, [xAddr]
// cbnz wStatus, .Lloadcmp
BuildMI(StoreBB, DL, TII->get(StlrOp), StatusReg)
BuildMI(StoreBB, MIMD, TII->get(StlrOp), StatusReg)
.addReg(NewReg)
.addReg(AddrReg);
BuildMI(StoreBB, DL, TII->get(AArch64::CBNZW))
BuildMI(StoreBB, MIMD, TII->get(AArch64::CBNZW))
.addReg(StatusReg, getKillRegState(StatusDead))
.addMBB(LoadCmpBB);
StoreBB->addSuccessor(LoadCmpBB);
@ -265,7 +265,7 @@ bool AArch64ExpandPseudo::expandCMP_SWAP_128(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI) {
MachineInstr &MI = *MBBI;
DebugLoc DL = MI.getDebugLoc();
MIMetadata MIMD(MI);
MachineOperand &DestLo = MI.getOperand(0);
MachineOperand &DestHi = MI.getOperand(1);
Register StatusReg = MI.getOperand(2).getReg();
@ -318,27 +318,27 @@ bool AArch64ExpandPseudo::expandCMP_SWAP_128(
// cmp xDestLo, xDesiredLo
// sbcs xDestHi, xDesiredHi
// b.ne .Ldone
BuildMI(LoadCmpBB, DL, TII->get(LdxpOp))
BuildMI(LoadCmpBB, MIMD, TII->get(LdxpOp))
.addReg(DestLo.getReg(), RegState::Define)
.addReg(DestHi.getReg(), RegState::Define)
.addReg(AddrReg);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::SUBSXrs), AArch64::XZR)
.addReg(DestLo.getReg(), getKillRegState(DestLo.isDead()))
.addReg(DesiredLoReg)
.addImm(0);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg)
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::CSINCWr), StatusReg)
.addUse(AArch64::WZR)
.addUse(AArch64::WZR)
.addImm(AArch64CC::EQ);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::SUBSXrs), AArch64::XZR)
.addReg(DestHi.getReg(), getKillRegState(DestHi.isDead()))
.addReg(DesiredHiReg)
.addImm(0);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::CSINCWr), StatusReg)
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::CSINCWr), StatusReg)
.addUse(StatusReg, RegState::Kill)
.addUse(StatusReg, RegState::Kill)
.addImm(AArch64CC::EQ);
BuildMI(LoadCmpBB, DL, TII->get(AArch64::CBNZW))
BuildMI(LoadCmpBB, MIMD, TII->get(AArch64::CBNZW))
.addUse(StatusReg, getKillRegState(StatusDead))
.addMBB(FailBB);
LoadCmpBB->addSuccessor(FailBB);
@ -347,25 +347,25 @@ bool AArch64ExpandPseudo::expandCMP_SWAP_128(
// .Lstore:
// stlxp wStatus, xNewLo, xNewHi, [xAddr]
// cbnz wStatus, .Lloadcmp
BuildMI(StoreBB, DL, TII->get(StxpOp), StatusReg)
BuildMI(StoreBB, MIMD, TII->get(StxpOp), StatusReg)
.addReg(NewLoReg)
.addReg(NewHiReg)
.addReg(AddrReg);
BuildMI(StoreBB, DL, TII->get(AArch64::CBNZW))
BuildMI(StoreBB, MIMD, TII->get(AArch64::CBNZW))
.addReg(StatusReg, getKillRegState(StatusDead))
.addMBB(LoadCmpBB);
BuildMI(StoreBB, DL, TII->get(AArch64::B)).addMBB(DoneBB);
BuildMI(StoreBB, MIMD, TII->get(AArch64::B)).addMBB(DoneBB);
StoreBB->addSuccessor(LoadCmpBB);
StoreBB->addSuccessor(DoneBB);
// .Lfail:
// stlxp wStatus, xDestLo, xDestHi, [xAddr]
// cbnz wStatus, .Lloadcmp
BuildMI(FailBB, DL, TII->get(StxpOp), StatusReg)
BuildMI(FailBB, MIMD, TII->get(StxpOp), StatusReg)
.addReg(DestLo.getReg())
.addReg(DestHi.getReg())
.addReg(AddrReg);
BuildMI(FailBB, DL, TII->get(AArch64::CBNZW))
BuildMI(FailBB, MIMD, TII->get(AArch64::CBNZW))
.addReg(StatusReg, getKillRegState(StatusDead))
.addMBB(LoadCmpBB);
FailBB->addSuccessor(LoadCmpBB);