After the stack is unwound due to a thrown exception, the
__stack_pointer global can point to an invalid address. This inserts
instructions that restore __stack_pointer global.
Details
Diff Detail
- Repository
- rL LLVM
- Build Status
Buildable 21677 Build 21677: arc lint + arc unit
Event Timeline
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
58 | This is kinda awkwardly indented, was this clang-formatted? ... Reading further down this patch, can we just call needsPrologForEH here? |
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
73 | This comment is a little confusing. Looking at the code, I guess it means we just always insert the fixup at the top of the BB, (but after the catch if it hasn't been moved)? | |
lib/Target/WebAssembly/WebAssemblyFrameLowering.h | ||
49 | Since SP is now a global and not a memory address anymore, we should change this function name. I realize that's pre-existing for this change, so it can be in a different CL (either before or after this one, whatever is convenient). |
Address comments
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
58 |
Yes it was.
Good idea. Done.
Done in WebAssemblyFrameLowering::needsPrologForEH. | |
73 |
Yes that's what it tries to do. Do you have any suggestions on making it less confusing? What I tried to say is, at this point, we have catch by this point but not catch_all (it will be generated later in LateEHPrepare). And even if we have catch, it may not be staying at the top. But here we don't want to go out of the way to find the catch instruction and generate these instructions after it because it will be done in LateEHPrepare anyway.
I'm not exactly sure about this. What prevents normal epilogues generated by WebAssemblyFrameLowering::emitEpilogue being moved after a call within the same BB? | |
lib/Target/WebAssembly/WebAssemblyFrameLowering.h | ||
49 | Done in D51046, which should land before this one. |
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
73 | Stepping back, why can catch instructions get reordered? It seems odd that they should be if we model them as having side effects or control flow or whatever. Stepping back, if we move catches later, and insert catch_all later, is there a reason we even need to put the catch in the BB early? Why not just add them when we add catch_all? Is it just because we ISel it from catchpad? I guess if we could avoid reordering, then it wouldn't be so confusing.
I think actually what happens is that calls are modeled as modifying SP, so that is ordered wrt anything else that modifies SP. So maybe that should just work for us too |
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
73 |
It is currently marked as hasCtrlDep, but I still have noticed cases that catches are reordered (mostly something like i32.const is hoisted before catch). I added hasSideEffects in D50919 just to be safer. But even with that I don't think we can be sure instructions like i32.const will not be reordered before catch, or something like this won't happen: ehpad: br bb2 bb3: catch So LateEHPrepare even considers cases like the latter and make sure catch will be the first instruction of an EH pad.
The reason we select catch in the isel stage is because unlike catch_all, it produces a value. Instructions below catch use the value produced by the catch. |
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
73 |
Hm, interesting. So getting back to this code, I guess it's not actually necessary to move the insert point below catch, and it makes the explanation funny, but OTOH it probably results in more readable IR in the common case. |
Fix comments
lib/Target/WebAssembly/WebAssemblyEHRestoreStackPointer.cpp | ||
---|---|---|
73 | Yes, it's not strictly necessary to move the insert point below catch. I did it because as you said it's gonna make code more readable in common cases. Fixed comments; I agree this is simpler and easier to understand. Thanks. |
This is kinda awkwardly indented, was this clang-formatted?
Might be worth extracting a temporary variable here for the getExceptionHandlingType() call, i.e. auto EHType = MF.getTarget().getMCAsmInfo()->getExceptionHandlingType();, which should make the line-breaks more consistent.
... Reading further down this patch, can we just call needsPrologForEH here?