This is an archive of the discontinued LLVM Phabricator instance.

[WebAssembly] Ensure terminate pads are a single BB
ClosedPublic

Authored by aheejin on Jan 4 2021, 3:50 PM.

Details

Summary

This ensures every single terminate pad is a single BB in the form of:

%exn = catch $__cpp_exception
call @__clang_call_terminate(%exn)
unreachable

This is a preparation for HandleEHTerminatePads pass, which will be
added in a later CL and will run after CFGStackify. That pass duplicates
terminate pads with a catch_all instruction, and duplicating it
becomes simpler if we can ensure every terminate pad is a single BB.

Diff Detail

Event Timeline

aheejin created this revision.Jan 4 2021, 3:50 PM
aheejin requested review of this revision.Jan 4 2021, 3:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 4 2021, 3:50 PM
dschuff accepted this revision.Jan 6 2021, 5:43 PM
This revision is now accepted and ready to land.Jan 6 2021, 5:43 PM
tlively added inline comments.Jan 7 2021, 10:15 AM
llvm/test/CodeGen/WebAssembly/exception.ll
225

Where does this global.set come from? If I understand the code correctly, the call __clang_call_terminate should have been directly after the catch.

239

Is it possible for call __clang_call_terminate to have been duplicated as well so that it could appear in this basic block as well? If so, I don't think the code in this diff would handle deduplicating it.

aheejin added inline comments.Jan 9 2021, 4:40 AM
llvm/test/CodeGen/WebAssembly/exception.ll
225

It is added in restoreStackPointer in LateEHPrepare. When WebAssemblyFrameLowering::needsPrologForEH returns true, i.e., a function has calls, __stack_pointer has to be saved in the function prolog and restored after each catch.

239

Wouldn't the second __clang_call_terminate within the same EH pad be caught in this code and just skipped?

// If it is already the form we want, skip it
if (Call->getParent() == EHPad &&
    Call->getNextNode()->getOpcode() == WebAssembly::UNREACHABLE)
  continue;
aheejin marked an inline comment as done.Jan 9 2021, 10:26 PM
aheejin added inline comments.
llvm/test/CodeGen/WebAssembly/exception.ll
239

Sorry, the current code turns out to have a problem. Because eraseDeadBBsAndChildren deletes all child BBs and instructions in there, when we encounter the second __clang_call_terminate call within the terminate pad, it is possible that instruction has been already deleted and its pointer is stale, and accessing it causes a segmentation fault. I fixed the code to only count one __clang_call_terminate per terminate pad. Also added a second __clang_call_terminate call in this BB to test the duplicated calls case you pointed out. PTAL.

aheejin updated this revision to Diff 315651.Jan 9 2021, 10:27 PM

Fix duplicate __clang_call_terminate call case

tlively accepted this revision.Jan 11 2021, 11:30 AM
tlively added inline comments.
llvm/test/CodeGen/WebAssembly/exception.ll
225

Makes sense, thanks!

This revision was automatically updated to reflect the committed changes.