-
Notifications
You must be signed in to change notification settings - Fork 745
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
[EH] Change catch_all's opcode #3574
Conversation
We decided to change `catch_all`'s opcode from 0x05, which is the same as `else`, to 0x19, to avoid some complicated handling in the tools. See: WebAssembly/exception-handling#147 --- dwarf_with_exceptions.wasm was added in WebAssembly#3496 but we didn't comment on how that file was created, so I'll add some comment on that here, in case we need to regenerate this file with some modifications. I regenerated dwarf_with_exceptions.wasm, so some variable names and such have changed. cpp file: ```cpp void foo(); void test_debuginfo() { try { foo(); } catch (...) { foo(); } } ``` Run: ``` $ clang++ -std=c++14 -stdlib=libc++ --target=wasm32-unknown-unknown -fwasm-exceptions -Xclang -disable-O0-optnone -c -S -emit-llvm test_debuginfo.cpp -o temp.ll $ opt -S -mem2reg -simplifycfg temp.ll -o test_debuginfo.ll ``` (`opt -mem2reg -simplifycfg` was run to make the code little tidier. This basically promotes stack loads/saves to registers and simplifies the CFG.) Resulting ll file, after modifying some function names and removing personal info in directory names: ```llvm source_filename = "test_debuginfo.cpp" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" $__clang_call_terminate = comdat any ; Function Attrs: noinline mustprogress define hidden void @test_debuginfo() #0 personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) !dbg !7 { entry: invoke void @foo() to label %try.cont unwind label %catch.dispatch, !dbg !10 catch.dispatch: ; preds = %entry %0 = catchswitch within none [label %catch.start] unwind to caller, !dbg !12 catch.start: ; preds = %catch.dispatch %1 = catchpad within %0 [i8* null], !dbg !12 %2 = call i8* @llvm.wasm.get.exception(token %1), !dbg !12 %3 = call i32 @llvm.wasm.get.ehselector(token %1), !dbg !12 %4 = call i8* @__cxa_begin_catch(i8* %2) WebAssembly#2 [ "funclet"(token %1) ], !dbg !12 invoke void @foo() [ "funclet"(token %1) ] to label %invoke.cont1 unwind label %ehcleanup, !dbg !13 invoke.cont1: ; preds = %catch.start call void @__cxa_end_catch() [ "funclet"(token %1) ], !dbg !15 catchret from %1 to label %try.cont, !dbg !15 try.cont: ; preds = %entry, %invoke.cont1 ret void, !dbg !16 ehcleanup: ; preds = %catch.start %5 = cleanuppad within %1 [], !dbg !15 invoke void @__cxa_end_catch() [ "funclet"(token %5) ] to label %invoke.cont2 unwind label %terminate, !dbg !15 invoke.cont2: ; preds = %ehcleanup cleanupret from %5 unwind to caller, !dbg !15 terminate: ; preds = %ehcleanup %6 = cleanuppad within %5 [], !dbg !15 %7 = call i8* @llvm.wasm.get.exception(token %6), !dbg !15 call void @__clang_call_terminate(i8* %7) WebAssembly#5 [ "funclet"(token %6) ], !dbg !15 unreachable, !dbg !15 } declare void @foo() WebAssembly#1 declare i32 @__gxx_wasm_personality_v0(...) ; Function Attrs: nounwind declare i8* @llvm.wasm.get.exception(token) WebAssembly#2 ; Function Attrs: nounwind declare i32 @llvm.wasm.get.ehselector(token) WebAssembly#2 ; Function Attrs: nounwind readnone declare i32 @llvm.eh.typeid.for(i8*) WebAssembly#3 declare i8* @__cxa_begin_catch(i8*) declare void @__cxa_end_catch() ; Function Attrs: noinline noreturn nounwind define linkonce_odr hidden void @__clang_call_terminate(i8* %0) WebAssembly#4 comdat { %2 = call i8* @__cxa_begin_catch(i8* %0) WebAssembly#2 call void @_ZSt9terminatev() WebAssembly#5 unreachable } declare void @_ZSt9terminatev() attributes #0 = { noinline mustprogress "disable-tail-calls"="false" "frame-pointer"="none" "min-legal-vector-width"="0" "no-jump-tables"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" } attributes WebAssembly#1 = { "disable-tail-calls"="false" "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+exception-handling" } attributes WebAssembly#2 = { nounwind } attributes WebAssembly#3 = { nounwind readnone } attributes WebAssembly#4 = { noinline noreturn nounwind } attributes WebAssembly#5 = { noreturn nounwind } !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!3, !4, !5} !llvm.ident = !{!6} !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) !1 = !DIFile(filename: "test_debuginfo.cpp", directory: "/") !2 = !{} !3 = !{i32 7, !"Dwarf Version", i32 4} !4 = !{i32 2, !"Debug Info Version", i32 3} !5 = !{i32 1, !"wchar_size", i32 4} !6 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git 3c4c205060c9398da705eb71b63ddd8a04999de9)"} !7 = distinct !DISubprogram(name: "test_debuginfo", linkageName: "test_debuginfo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) !8 = !DISubroutineType(types: !9) !9 = !{null} !10 = !DILocation(line: 5, column: 5, scope: !11) !11 = distinct !DILexicalBlock(scope: !7, file: !1, line: 4, column: 7) !12 = !DILocation(line: 6, column: 3, scope: !11) !13 = !DILocation(line: 7, column: 5, scope: !14) !14 = distinct !DILexicalBlock(scope: !7, file: !1, line: 6, column: 17) !15 = !DILocation(line: 8, column: 3, scope: !14) !16 = !DILocation(line: 9, column: 1, scope: !7) ``` Run: ``` $ llc -exception-model=wasm -mattr=+exception-handling -filetype=obj test_debuginfo.ll -o test_debuginfo.o $ wasm-ld --no-entry --no-gc-sections --allow-undefined test_debuginfo.o -o test_debuginfo.wasm ```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the dwarf changes are mostly because there is an extra line early in the file - all the line numbers are pushed down by 1. If it's easy to do then removing that line and rebuilding the file could make the diff here almost go away. But if it's not trivial then I wouldn't worry about it.
Also may be worth checking in that file as a .cpp
alongside the wasm.
I removed the extra line, but this time I didn't try to 'clean up' demangled function names, like, Yeah I'll also upload the cpp file. |
I don't understand the error for emscripten CI faling. Does any one have a clue? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The $foo => $foo\28\29
change is from C => C++ I think? Not sure how it compiled as C before, maybe some extern "C", but looks better as it is now.
The emscripten errors are on missing symbols for |
As I said, I manually modified ll file to "clean up" demangled names 😂 That's the reason how it was compiled as just |
Oh I meant manually modified "ll" file.... (fixed the comment) |
Oh, heh, I missed that part about the manual cleanup... 😄 anyhow, looks good as it is. Testing locally, I can't reproduce the emscripten error, even with this PR applied. Maybe it was previous tot breakage? Anyhow, unrelated to this PR. |
Will land the PR; the CI failure doesn't seem to be related. |
We decided to change
catch_all
's opcode from 0x05, which is the sameas
else
, to 0x19, to avoid some complicated handling in the tools.See: WebAssembly/exception-handling#147
lso this contains the original cpp file used to generate
dwarf_with_exceptions.wasm; instructions to generate the wasm from that
cpp file are in the comments.