Skip to content

[CalcSpillWeights] don't mark live intervals with spillable inlineasm ops as having infinite spill weight #70747

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

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Changes from all 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
13 changes: 12 additions & 1 deletion llvm/lib/CodeGen/CalcSpillWeights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ void VirtRegAuxInfo::calculateSpillWeightAndHint(LiveInterval &LI) {
LI.setWeight(Weight);
}

static bool canMemFoldInlineAsm(LiveInterval &LI,
const MachineRegisterInfo &MRI) {
for (const MachineOperand &MO : MRI.reg_operands(LI.reg())) {
const MachineInstr *MI = MO.getParent();
if (MI->isInlineAsm() && MI->mayFoldInlineAsmRegOp(MI->getOperandNo(&MO)))
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a register is both foldable and not foldable?
I.e., something like asm "rm, r", %0, %0.

Given the second constraints force %0 to stay in register, we can't fold right.

In other words, depending on the semantic that we want, we may want to check all the operands.
Now, I still approved this PR because although the resulting LI won't actually be spillable in this case, regalloc will still handle it correctly.

Copy link
Member Author

@nickdesaulniers nickdesaulniers Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a register is both foldable and not foldable?
I.e., something like asm "rm, r", %0, %0.

I'm not sure that can be expressed from inline asm.

Do you mean something like:

asm ("# %0 %1"::"rm"(x), "r"(x));

?

I that case, %0 would have a distinct storage location from %1. x would be copied into the inline asm twice. %0's constraint is rm (register OR memory), %1's constraint is r (register). I don't think AND NOT is expressible via the constraint language.

}

return false;
}

float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
SlotIndex *End) {
MachineRegisterInfo &MRI = MF.getRegInfo();
Expand Down Expand Up @@ -315,7 +326,7 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start,
// into instruction itself makes perfect sense.
if (ShouldUpdateLI && LI.isZeroLength(LIS.getSlotIndexes()) &&
!LI.isLiveAtIndexes(LIS.getRegMaskSlots()) &&
!isLiveAtStatepointVarArg(LI)) {
!isLiveAtStatepointVarArg(LI) && !canMemFoldInlineAsm(LI, MRI)) {
LI.markNotSpillable();
return -1.0;
}
Expand Down