Skip to content

Commit 2fe24fd

Browse files
reapply "[TargetInstrInfo] enable foldMemoryOperand for InlineAsm (#70743)" (#72910)
This reverts commit 42204c9. It was accidentally backed out. #20571 #70743
1 parent 28f62d7 commit 2fe24fd

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,16 @@ class TargetInstrInfo : public MCInstrInfo {
21882188
// Get the call frame size just before MI.
21892189
unsigned getCallFrameSizeAt(MachineInstr &MI) const;
21902190

2191+
/// Fills in the necessary MachineOperands to refer to a frame index.
2192+
/// The best way to understand this is to print `asm(""::"m"(x));` after
2193+
/// finalize-isel. Example:
2194+
/// INLINEASM ... 262190 /* mem:m */, %stack.0.x.addr, 1, $noreg, 0, $noreg
2195+
/// we would add placeholders for: ^ ^ ^ ^
2196+
virtual void
2197+
getFrameIndexOperands(SmallVectorImpl<MachineOperand> &Ops) const {
2198+
llvm_unreachable("unknown number of operands necessary");
2199+
}
2200+
21912201
private:
21922202
mutable std::unique_ptr<MIRFormatter> Formatter;
21932203
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;

llvm/lib/CodeGen/TargetInstrInfo.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,64 @@ static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI,
565565
return NewMI;
566566
}
567567

568+
static void foldInlineAsmMemOperand(MachineInstr *MI, unsigned OpNo, int FI,
569+
const TargetInstrInfo &TII) {
570+
MachineOperand &MO = MI->getOperand(OpNo);
571+
const VirtRegInfo &RI = AnalyzeVirtRegInBundle(*MI, MO.getReg());
572+
573+
// If the machine operand is tied, untie it first.
574+
if (MO.isTied()) {
575+
unsigned TiedTo = MI->findTiedOperandIdx(OpNo);
576+
MI->untieRegOperand(OpNo);
577+
// Intentional recursion!
578+
foldInlineAsmMemOperand(MI, TiedTo, FI, TII);
579+
}
580+
581+
// Change the operand from a register to a frame index.
582+
MO.ChangeToFrameIndex(FI, MO.getTargetFlags());
583+
584+
SmallVector<MachineOperand, 4> NewOps;
585+
TII.getFrameIndexOperands(NewOps);
586+
assert(!NewOps.empty() && "getFrameIndexOperands didn't create any operands");
587+
MI->insert(MI->operands_begin() + OpNo + 1, NewOps);
588+
589+
// Change the previous operand to a MemKind InlineAsm::Flag. The second param
590+
// is the per-target number of operands that represent the memory operand
591+
// excluding this one (MD). This includes MO.
592+
InlineAsm::Flag F(InlineAsm::Kind::Mem, NewOps.size() + 1);
593+
F.setMemConstraint(InlineAsm::ConstraintCode::m);
594+
MachineOperand &MD = MI->getOperand(OpNo - 1);
595+
MD.setImm(F);
596+
597+
// Update mayload/maystore metadata.
598+
MachineOperand &ExtraMO = MI->getOperand(InlineAsm::MIOp_ExtraInfo);
599+
if (RI.Reads)
600+
ExtraMO.setImm(ExtraMO.getImm() | InlineAsm::Extra_MayLoad);
601+
if (RI.Writes)
602+
ExtraMO.setImm(ExtraMO.getImm() | InlineAsm::Extra_MayStore);
603+
}
604+
605+
// Returns nullptr if not possible to fold.
606+
static MachineInstr *foldInlineAsmMemOperand(MachineInstr &MI,
607+
ArrayRef<unsigned> Ops, int FI,
608+
const TargetInstrInfo &TII) {
609+
assert(MI.isInlineAsm() && "wrong opcode");
610+
if (Ops.size() > 1)
611+
return nullptr;
612+
unsigned Op = Ops[0];
613+
assert(Op && "should never be first operand");
614+
assert(MI.getOperand(Op).isReg() && "shouldn't be folding non-reg operands");
615+
616+
if (!MI.mayFoldInlineAsmRegOp(Op))
617+
return nullptr;
618+
619+
MachineInstr &NewMI = TII.duplicate(*MI.getParent(), MI.getIterator(), MI);
620+
621+
foldInlineAsmMemOperand(&NewMI, Op, FI, TII);
622+
623+
return &NewMI;
624+
}
625+
568626
MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
569627
ArrayRef<unsigned> Ops, int FI,
570628
LiveIntervals *LIS,
@@ -612,6 +670,8 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
612670
NewMI = foldPatchpoint(MF, MI, Ops, FI, *this);
613671
if (NewMI)
614672
MBB->insert(MI, NewMI);
673+
} else if (MI.isInlineAsm()) {
674+
NewMI = foldInlineAsmMemOperand(MI, Ops, FI, *this);
615675
} else {
616676
// Ask the target to do the actual folding.
617677
NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, FI, LIS, VRM);
@@ -683,6 +743,8 @@ MachineInstr *TargetInstrInfo::foldMemoryOperand(MachineInstr &MI,
683743
NewMI = foldPatchpoint(MF, MI, Ops, FrameIndex, *this);
684744
if (NewMI)
685745
NewMI = &*MBB.insert(MI, NewMI);
746+
} else if (MI.isInlineAsm() && isLoadFromStackSlot(LoadMI, FrameIndex)) {
747+
NewMI = foldInlineAsmMemOperand(MI, Ops, FrameIndex, *this);
686748
} else {
687749
// Ask the target to do the actual folding.
688750
NewMI = foldMemoryOperandImpl(MF, MI, Ops, MI, LoadMI, LIS);

0 commit comments

Comments
 (0)