Skip to content

Use spill-bundles directly for stack-constrained uses #48

@cfallin

Description

@cfallin

In bytecodealliance/wasmtime#3785, we discovered a case where an unnecessary register-to-register move occurs. The pattern is like:

  • Def of value, constrained to a caller-saved register;
  • Callsite, clobbering all caller-saves;
  • Safepoint, requiring above value on stack.

Currently, we start a liverange for the value, and split just before the safepoint (due to conflict in requirements). We then chop off the tail of the tail of the first liverange and put it in the spillbundle instead. The first liverange gets the register from its constraint; the last gets a stackslot; and the spillbundle gets a callee-save register, because it's live across a callsite.

In this particular case, it would be better to move straight to the stackslot before the callsite. We could probably most easily achieve this by (i) putting all stack-constrained uses directly on the spillbundle, and (ii) in such cases, skipping second-chance register allocation for the spillbundle.

This would require some careful evaluation to ensure that it doesn't regress cases where there happens to be a stack constraint in one place but we mostly want to benefit from second-chance allocation for the spillbundle.

A more general solution is for the spillbundle allocation to take hint(s) from the allocations of all the other LRs it is tied to, possibly weighted somehow. However, in this case it would be pretty fragile because one could equally take a hint from either the first LR (constrained to a reg that is clobbered by the callsite) or the last LR; we somehow need to know to prefer the last. And whatever logic we come up with for the above, one could imagine the inverse case (safepoint first, then callsite, then use in register) where we would want the opposite hinting preference. So, this more general solution likely needs a lot more careful thought re: cost model if it were to be viable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions