This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Fix debug_value's when registers are stackified.
AbandonedPublic

Authored by aardappel on Apr 24 2020, 10:24 AM.

Details

Summary

This is a WiP for review, missing tests etc.

Diff Detail

Event Timeline

aardappel created this revision.Apr 24 2020, 10:24 AM

Uploading this for early feedback to see if this goes the right direction.

This correctly outputs a DW_AT_location of the correct type TI_OPERAND_STACK where previously there was nothing being output at all (because the debug_value referred to an orphan register). Only tested for the simplest case of one def + one use.

Besides tests, this does not update the PC range, which is currently incorrect. The range should probably just be shrunk to exactly the PC just between the def and use.

Also entirely not sure if my calls to replaceWithStackOffset are a) operating on the correct debug_values and b) have the correct stack offset. This in particular needs tests. Anyone familiar with WebAssemblyRegStackify would love to hear if you think I am capturing the various cases correctly. Also one case where we un-stackify.

There are many places that calls MFI.stackifyVReg. I guess we should handle them too? Not very sure if it'll be easy to compute stack offset in all those cases though.

llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
22

IIRC this WebAssemblyDebugValueManager class was first written when we didn't have multivalue defs, so I think this class needs to be extended to handle multivalue defs. For a multivalue instruction, in theory each of defs can have different stack status, for example,

r1, r2, r3 = some_call(...);

In this instruction, it is possible that only r1 is stackified and r2 and r3 are not. So maybe this class now needs to take not only a MachineInstr but also a def register or def index or something. Also this MachineInstr::collectDebugValues does not seem to handle multiple def registers either, so we might need to fix this first.

61

Is this function used to mark an instruction as a register before it is marked as a local in ExplicitLocals? If so maybe a comment saying this register marking is tentative would be good.

llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
709

I don't think Worklist.size() is the depth of the stack. Worklist contains not MachineOperands but ranges. Each range contains multiple MachineOperands. So you have to count MachineOperands in each of ranges within Worklist.

951

I think this needs to be handled per def register (within a possibly multi-def instruction). Related to the comment in WebAssemblyDebugValueManager.

aardappel marked 3 inline comments as done.Apr 27 2020, 3:58 PM

@aheejin thanks for the comments! As you say, given that stackifying happens across multiple passes, it may be that the approach here is going to be too clumsy/fragile. I am going to first see if a solution that works at or just before MC lowering can work instead, that way all the stackifying changes can remain as they are.

llvm/lib/Target/WebAssembly/WebAssemblyDebugValueManager.cpp
22

Ah yes, hadn't thought of multivalue :( Though maybe its worth adding multi-value support in a separate CL.

61

No, it is used to change a register that was changed to a stack value back to a register. Hopefully its not necessary.

llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
709

I did think about this and somehow thought it was equivalent. Will check if I revisit.

aardappel abandoned this revision.May 7 2020, 3:22 PM

This patch abandoned in favor of the approach in https://reviews.llvm.org/D79428