summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* Code pushing support for br_on_exn (#2660)Heejin Ahn2020-02-194-2/+7
| | | | | | | | | Like `br_if`, `br_on_exn` is a conditional branch and across which code can be pushed past when conditions are satisfied. Also adds a few lines of comments and NFC changes in a couple places. Changes in Vacuum are NFC because they were being handled in `default:` in the same way anyway, but I added them to be more explicit and consistent with existing code.
* Concise error output (#2652)Alon Zakai2020-02-182-12/+18
| | | | | | | | | | | Don't print the entire module on an error. Instead, just print the validation errors. However, if the user passed --print, then do print it, as otherwise nothing would get printed - the error would be before the pass to print happens. And in general a user passing in a request to print would expect a printed module anyhow. fixes #2634
* DWARF: Fix debug_range handling of invalid entries (#2662)Alon Zakai2020-02-181-18/+14
| | | | | | | | | | | | | | If an invalid entry appears - either it began as such, or became invalid after optimization - we should not emit (0, 0) which is an end marker. Instead, emit an invalid entry marker, something with (0, x) for x != 0. As a bonus, if a test/passes case has "noprint" in the name, don't print the wasm, which we do by default. In the testcase here for example we just care about the dwarf, and the printed module would be quite large. Thank you to @paolosevMSFT for identifying and suggesting the fix.
* Add C-/JS-APIs for inlining options (#2655)Daniel Wirtz2020-02-133-0/+102
| | | | | | | | | | Allows a user to modify the inlining limits using the C- and JS-APIs. * binaryen.**getAlwaysInlineMaxSize**(): `number` * binaryen.**setAlwaysInlineMaxSize**(size: `number`): `void` * binaryen.**getFlexibleInlineMaxSize**(): `number` * binaryen.**setFlexibleInlineMaxSize**(size: `number`): `void` * binaryen.**getOneCallerInlineMaxSize**(): `number` * binaryen.**setOneCallerInlineMaxSize**(size: `number`): `void`
* Convert remaining python scripts to run under python3 (#2643)Sam Clegg2020-02-111-1/+4
|
* Fix missing newline after // EMSCRIPTEN_START_FUNCS and // ↵juj2020-02-101-2/+3
| | | | | | | | | | EMSCRIPTEN_END_FUNCS markers. (#2626) * Fix missing newline after // EMSCRIPTEN_START_FUNCS and // EMSCRIPTEN_END_FUNCS markers. * Flake * Update tests
* Optimize base64 decoding (#2623)juj2020-02-091-22/+26
| | | | | | | | | | | | | | * Optimize base64 decoding (about 7x-10x faster and temporary garbage-free compared to the original version) * new Uint8Array * Reuse Uint8Array view * Fix end handling * Code format * Update tests
* Optimize Try in Vacuum (#2644)Heejin Ahn2020-02-071-0/+9
| | | | If try's body does not throw, the whole try-catch can be replaced with the try body.
* Add C-/JS-APIs for lowMemoryUnused and pass arguments (#2639)Daniel Wirtz2020-02-073-3/+113
| | | | | | | | | Allows a user to enable/disable the `lowMemoryUnused` option and to get/set/clear arbitrary pass arguments when using the C- or JS-APIs. * binaryen.**getLowMemoryUnused**(): `boolean` * binaryen.**setLowMemoryUnused**(on: `boolean`): `void` * binaryen.**getPassArgument**(key: `string`): `string | null` * binaryen.**setPassArgument**(key: `string`, value: `string | null`): `void` * binaryen.**clearPassArguments**(): `void`
* DWARF: Disable optimization passes not fully compatible with DWARF yet (#2640)Alon Zakai2020-02-061-11/+42
| | | | | | | | | | | Anything that merges/swaps/etc. locals, or inlines, or merges functions, must be disabled for now. However, that does still leave almost all passes, so this should not affect output sizes much (and the full LLVM optimizer can be run before too). Over time we can resolve each of those FIXMEs. The test output here shows how disabling those allows over twice as much debug_line info to be preserved.
* Fix LocalCSE's usable local selection (#2638)Heejin Ahn2020-02-052-24/+29
| | | | | | | | | | | | | | | | Now that we have subtypes, we cannot reuse any local that contains the same expression, because that local's type can be a supertype. For example: ``` (local $0 anyref) (local $1 nullref) ... (local.set $0 (ref.null)) (local.set $1 (ref.null)) ;; cannot be replaced with (local.get $0) ``` This extends `usables` map's key to contain both `HashedExpression` and the local's type, so we can get the right usable local in presence of subtypes.
* Add EH support for OptimizeInstructions (#2608)Heejin Ahn2020-02-055-25/+69
| | | | | | - Adds support for `Try` in `optimizeBoolean` function - Adds support for `Try` in `getFallThrough` function - Adds approximate cost values for instructions in EH and reference types proposals.
* Avoid an infinite loop in `-ttf` generation (#2637)Alex Crichton2020-02-041-1/+1
| | | | | | | | | | | | | | | We've been throwing some fuzzing at some wasm implementations recently and one of our strategies is to use `wasm-opt -ttf` with the fuzzer's input to generate a wasm module. Some of our tests, though, have been failing due to out-of-memory while `wasm-opt` is generating a module. This loop appears to be infinitely executing since the input just-so-happens that `oneIn(3)` returns true for every byte of the input file, or at least enough such that when the xor factor is merged in it at least generates very long sequence of `true`. It looks like elsewhere in the file when `while (oneIn(N))` is used it's also guarded by `!finishedInput`, so I've added a similar guard here as well.
* Trap when call_indirect's signatures mismatch (#2636)Heejin Ahn2020-02-033-1/+11
| | | | | | | | | | | This makes the interpreter trap when the signature in `call_indirect` instruction and that of the actual function in the table mismatch. This also makes the `wasm-ctor-eval` not evaluate `call_indirect` in case the signatures mismatch. Before we only compared the arguments' signature and the function signature, which was sufficient before we had subtypes, but now the signature in `call_indirect` and that of the actual function can be different even if the argument's signature is OK.
* Add EH support for EffectAnalyzer (#2631)Heejin Ahn2020-02-0319-132/+271
| | | | | | | | | | | | | | | | | | | | This adds EH support to `EffectAnalyzer`. Before `throw` and `rethrow` conservatively set property. Now `EffectAnalyzer` has a new property `throws` to represent an expression that can throw, and expression that can throw sets `throws` correctly. When EH is enabled, any calls can throw too, so we cannot reorder them with another expression with any side effects, meaning all calls should be treated in the same way as branches when evaluating `invalidate`. This prevents many reorderings, so this patch sets `throws` for calls only when the exception handling features is enabled. This is also why I passed `--disable-exception-handling` to `wasm2js` tests. Most of code changes outside of `EffectAnalyzer` class was made in order to pass `FeatureSet` to it. `throws` isn't always set whenever an expression contains a throwable instruction. When an throwable instruction is within an inner try, it will be caught by the corresponding inner catch, so it does not set `throws`.
* Fix for cmake 3.10 (eg on Ubuntu LTS) (#2632)Brion Vibber2020-01-301-1/+1
| | | | | | | | | CMAKE_PROJECT_VERSION is only predefined on cmake 3.12 and later, so the previous code produced an empty version number which leads to parsing errors when emcc checks the version. Use of the older PROJECT_VERSION variable as the source of the original version works here, as there's only one toplevel project defined.
* DWARF: Update DW_AT_stmt_list which are offsets into the debug_line section ↵Alon Zakai2020-01-281-21/+51
| | | | | | | | (#2628) The debug_line section is the only one in which we change sizes and so must update offsets. It turns out that there are such offsets, DW_AT_stmt_list, so without updating them we can't handle multi-unit dwarf files.
* Optionally minify imported module names (#2620)Alon Zakai2020-01-273-8/+53
| | | | | | | | | | | | | | | | This replaces imports like env.foo with a.foo, which can save a bunch of bytes when there are many imported functions. Note that by changing all the import names to a it ends up requiring a single merged import module. Note also that when doing this we modify all the imports, minifying their modules and names (since it makes no sense to be careful about minifying only modules known to us - env/wasi - if we are minifyin the names of all modules). This will require an emscripten PR to benefit from it.
* DWARF: Properly emit signed 32 bit values for advance_line (#2625)Alon Zakai2020-01-241-1/+4
| | | | | | | | | The LLVM SData field is 64-bit (to support 64-bit addresses I suppose) so when we assigned to it we actually led it to emit an LEB for a signed 64-bit value that is an unsigned 32-bit one. This worked in LLVM (where I guess it forces the value to 32-bit anyhow?) but failed in gimli (where I guess it doesn't?).
* Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" (#2622)Sam Clegg2020-01-241-15/+26
| | | | | This reverts commit 132daae1e9154782bb1afa5df80dfe7ea35f0369. This change is the same as before but the fix in #2619 should now make it safe.
* Handle indirect calls in CallGraphPropertyAnalysis (#2624)Alon Zakai2020-01-243-4/+18
| | | | | | | | | | | | | We ignored them, which is a bad default, as typically they imply we can call anything in the table (and the table might change). Instead, notice indirect calls during traversal, and force the user to decide whether to ignore them or not. This was only an issue in PostEmscripten because the other user, Asyncify, already had indirect call analysis because it needed it for other things. Fixes a bug uncovered by #2619 and fixes the current binaryen roll.
* Consistent detection of invoke_ functions in PostEmscripten.cpp (#2619)Sam Clegg2020-01-231-3/+6
| | | | | | | We should be looking at the import name when determining if a function is an invoke function. This is a precursor to re-landing the fix for https://github.com/emscripten-core/emscripten/issues/9950.
* DWARF: Update .debug_loc (#2616)Alon Zakai2020-01-231-47/+117
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Add support for that section to the YAML layer, and add code to update it. The updating is slightly tricky - unlike .debug_ranges, the size of entries is not fixed. So we can't just skip entries, as the end marker is smaller than a normal entry. Instead, replace now-invalid segments with (1, 1) which is of size 0 and so should be ignored by the debugger (we can't use (0, 0) as that would be an end marker, and (-1, *) is the special base marker). In the future we probably do want to do this in a more sophisticated manner, completely rewriting the indexes into the section as well. For now though this should be enough for when binaryen does not optimize (as we don't move/reorder anything). Note that this doesn't update the location description (like where on the wasm expression stack the value is). Again, that is correct for when binaryen doesn't optimize, but for fully optimized builds we would need to track things (which would be hard!). Also clean up some code that uses "Extra" instead of "Delimiter" that was missed before, and shorten some unnecessarily long names.
* Initialize the LegalizeJSInterface vector once, not once in each function ↵Alon Zakai2020-01-231-6/+6
| | | | | | | | | | | | | (#2614) I missed this in the review of #2451 - this was doing quadratic work, each function touched the entire array which is the size of the functions. This speeds up the pspdfkit testcase from the mailing list from several minutes (15 on CI; I stopped measuring after 2 minutes locally) to 5 seconds. I suspect this was not noticed earlier because that testcase has a very large number of functions, which hit this issue especially hard.
* Limit the number of passive segments to work around a Chrome bug (#2613)Thomas Lively2020-01-222-2/+10
| | | | | | Chrome is currently decoding the segment indices as signed numbers, so some ranges of indices greater than 63 do not work. As a temporary workaround, limit the number of segments produced by MemoryPacking to 63 when bulk-memory is enabled.
* DWARF: Update debug_ranges (#2612)Alon Zakai2020-01-221-2/+55
| | | | | | | | | | | | | | | | | | Pretty straightforward given all we have so far. Note that fannkuch3_manyopts has an example of a sequence of ranges of which some must be skipped while others must not, showing we handle that by skipping the bad ones and updating the remaining. That is, if that we have a sequence of two (begin, end) spans [(10, 20), (30, 40)] It's possible (10, 20) maps in the new binary to (110, 120) while (30, 40) was eliminated by the optimizer and we have nothing valid to map it to. In that case we emit [(110, 120)]
* DWARF: Fix debug lines in fannkuch -O0 (#2611)Alon Zakai2020-01-221-6/+18
| | | | | | | | | | | | | | | | Just some trivial fixes: * Properly reset prologue after each line (unlike others, this flag should be reset immediately). * Test for a function's end address first, as LLVM output appears to use 1-past-the-end-of-the-function as a location in that function, and not the next (note the first byte of the next function, which is ambiguously identical to that value, is used at least in low_pc; I'm not sure if it's used in debug lines too). * Ignore the same address if LLVM emitted it more than once, which it does sometimes.
* DWARF: Use end_sequence and copy properly (#2610)Alon Zakai2020-01-221-6/+12
| | | | | | | We need to track end_sequence directly, and use either end_sequence or copy (copy emits a line without marking it as ending a sequence). After this, fib2 debug line output looks perfect.
* DWARF: Allow debug lines with column 0 (#2609)Alon Zakai2020-01-221-2/+2
| | | | While line and address values of 0 should be skipped, it seems like column 0 are valid lines emitted by LLVM.
* DWARF: Track more function locations (#2604)Alon Zakai2020-01-223-37/+92
| | | | | | | | | | | | | | DWARF from LLVM can refer to the first byte belonging to the function, where the size LEB is, or to the first byte after that, where the local declarations are, or the end opcode, or to one byte past that which is one byte past the bytes that belong to the function. We aren't sure why LLVM does this, but track it all for now. After this all debug line positions are identified. However, in some cases a debug line refers to one past the end of the function, which may be an LLVM bug. That location is ambiguous as it could also be the first byte of the next function (what made this discovery possible was when this happened to the last function, after which there is another section).
* DWARF: Track the positions of 'end', 'else', 'catch' binary locations (#2603)Alon Zakai2020-01-216-32/+196
| | | | | | | | | | | | | | | | | Control flow structures have those in addition to the normal span of (start, end), and we need to track them too. Tracking them during reading requires us to track control flow structures while parsing, so that we can know to which structure an end/else/catch refers to. We track these locations using a map on the side of instruction to its "extra" locations. That avoids increasing the size of the tracking info for the much more common non-control flow instructions. Note that there is one more 'end' location, that of the function (not referring to any instruction). I left that to a later PR to not increase this one too much.
* Handle an invalid AbbrCode in DWARF handling (#2607)Alon Zakai2020-01-211-1/+1
| | | | | | | | | | | | | Fixes the testcase in #2343 (comment) Looks like that's from Rust. Not sure why it would have an invalid abbreviation code, but perhaps the LLVM there emits dwarf differently than we've tested on so far. May be worth investigating further, but for now emit a warning, skip that element, and don't crash. Also fix valgrind warnings about Span values not being initialized, which was invalid and bad as well (wasted memory in our maps, and might have overlapped with real values), and interfered with figuring this out.
* Unify JS memory segment API (#2533)Daniel Wirtz2020-01-213-2/+19
| | | | | | | | | | Binaryen.js now uses offset instead of byteOffset when inspecting a memory segment, matching the arguments on memory segment creation. Also adds inspection of the passive property. Previously, one would specify { offset, data, passive } on creation and get back { byteOffset, data } upon inspection. This PR unifies both to the keys on creation while also adding the respective C-API to retrieve passive status, which was missing.
* Simplify binary parsing a little (#2602)Alon Zakai2020-01-211-2/+4
| | | | | Instead of hackishly advancing the read position in the binary buffer, call readExpression which will do that, and also do all the debug info handling for us.
* Update debug line info with function entries (#2600)Alon Zakai2020-01-171-1/+12
| | | | | | LLVM points to the start of the function in some debug line entries - right after the size LEB of the function, which is where the locals are declared, and before any instructions.
* Expose ExpressionAnalyzer in C-/JS-API (#2585)Daniel Wirtz2020-01-174-0/+155
| | | | | | | Instead of reinventing the wheel on our side, this adds ExpressionAnalyzer bindings to the C- and JS-APIs, which can be useful for generators. For example, a generator may decide to simplify a compilation step if a subexpression doesn't have any side effects, or simply skip emitting something that is likely to compile to a drop or an empty block right away.
* Use BinaryLocation instead of hardcoding uint32_t (#2598)Alon Zakai2020-01-163-26/+32
| | | | This will make it easier to switch to something else for offsets in wasm binaries if we get >4GB files.
* DWARF: high_pc computation (#2595)Alon Zakai2020-01-166-54/+139
| | | | | | | Update high_pc values. These are interesting as they may be a relative offset compared to the low_pc. For functions we already had both a start and an end. Add such tracking for instructions as well.
* Add EH support for CFGWalker (#2597)Heejin Ahn2020-01-161-0/+84
| | | | | | | | This adds EH instruction support for `CFGWalker`. This also implements `call` instruction handling within a try-catch; every call can possibly throw and unwind to the innermost catch block. This adds tests for RedundantSetElimination pass, which uses `CFGWalker`.
* DWARF: Function location tracking (#2592)Alon Zakai2020-01-166-65/+142
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Track the beginning and end of each function, both when reading and writing. We track expressions and functions separately, instead of having a single big map of (oldAddr) => (newAddr) because of the potentially ambiguous case of the final expression in a function: it's end might be identical in offset to the end of the function. So we have two different things that map to the same offset. However, if the context is "the end of the function" then the updated address is the new end of the function, even if the function ends with a different instruction now, as the old last instruction might have moved or been optimized out. Concretely, we have getNewExprAddr and getNewFuncAddr, so we can ask to update the location of either an expression or a function, and use that contextual information. This checks for the DIE tag in order to know what we are looking for. To be safe, if we hit an unknown tag, we halt, so that we don't silently miss things. As the test updates show, the new things we can do thanks to this PR are to update compile unit and subprogram low_pc locations. Note btw that in the first test (dwarfdump_roundtrip_dwarfdump.bin.txt) we change 5 to 0: that is correct since that test does not write out DWARF (it intentionally has no -g), so we do not track binary locations while writing, and so we have nothing to update to (the other tests show actual updating). Also fix the order in the python test runner code to show a diff of expected to encountered, and not the reverse, which confused me.
* Optimize passive segments in memory-packing (#2426)Thomas Lively2020-01-154-121/+616
| | | | | | | | | When memory is packed and there are passive segments, bulk memory operations that reference those segments by index need to be updated to reflect the new indices and possibly split into multiple instructions that reference multiple split segments. For some bulk-memory operations, it is necessary to introduce new globals to explicitly track the drop state of the original segments, but this PR is careful to only add globals where necessary.
* DWARF updating: update DW_AT_low_pc attributes (#2584)Alon Zakai2020-01-141-18/+102
| | | | | | | Mostly straightforward: go over the dwarf entries, find the low_pc ones, and update their positions. A slight oddity is that we must traverse both the dwarf context - which has the rich APIs for analsis - and the YAML data structure - which is minimal but is used for writing out.
* Omit DWARF debug line ranges starting with 0 (#2587)Alon Zakai2020-01-141-0/+25
| | | | | | | | | | | Check if an entry starts a new range of addresses. Each range is a set of related addresses, where in particular, if the first has been zeroed out by the linker, we must omit the entire range. If we do not, then the initial range is 0 and the others are offsets relative to it, which will look like random addresses, perhaps into the middle of instructions, and perhaps that happen to collide with real ones (a debugger would ignore those, so we must too; it's easier and better to simply omit them). See https://bugs.llvm.org/show_bug.cgi?id=44516#c2
* Clear Mixedarena in ModuleUtils::clearModule (#2588)Heejin Ahn2020-01-131-0/+1
|
* Verify --version output matches CHANGELOG (#2580)Sam Clegg2020-01-101-1/+1
| | | | | | | | | | | | | | | | | The new version string looks like this: wasm-opt version 90 (version_90-18-g77329439d) The version reported here is the version from the CMakeLists.txt file followed by the git version in brackets. We verify that the main version here matches the CHANGELOG to prevent people from changing one without changeing the other. This will help with emscripten that wants to be able to programaticaly check the --version of binaryen tools. See https://github.com/emscripten-core/emscripten/issues/10175
* wasm2js: Do not convert x >>> 0 | 0 to x >>> 0 (#2581)Alon Zakai2020-01-101-2/+10
| | | | | | | | | | | | isBinary was used where we should only accept a signed binary, as removing the | 0 from an unsigned value may be incorrect. This does regress a few small things (as can be seen in the diff). If it's important we can add more sophisticated optimizations here, perhaps like an assumption that the signedness of a local never matters. Fixes emscripten-core/emscripten#10173
* DWARF support for multiple line tables (#2557)Alon Zakai2020-01-091-23/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Multiple tables appear to be emitted when linking files together. This fixes our support for that, which did not update their size properly. This required patching the YAML emitting code from LLVM in order to measure the size and then emit it, as that code is apparently not designed to handle changes in line table contents. Other minor fixes: * Set the flags for our dwarfdump command to emit the same as llvm-dwarfdump does with -v -all. * Add support for a few more opcodes, set_discriminator, set_basic_block, fixed_advance_pc, set_isa. * Handle a compile unit without abbreviations in the YAML code (again, apparently not something this LLVM code was intended to do). * Handle a compile unit with zero entries in the YAML code (ditto). * Properly set the AddressSize - we use the DWARFContext in a different way than LLVM expects, apparently. With this the emscripten test suite passes with -gforce_dwarf without crashing. My overall impression so from the the YAML code is that it probably isn't a long-term solution for us. Perhaps it may end up being scaffolding, that is, we can replace it with our own code eventually that is based on it, and remove most of the LLVM code. Before deciding that we should get everything working first, and this seems like the quickest path there.
* Remove implicit conversion operators from Type (#2577)Thomas Lively2020-01-0830-208/+217
| | | | | | | | | | * Remove implicit conversion operators from Type Now types must be explicitly converted to uint32_t with Type::getID or to ValueType with Type::getVT. This fixes #2572 for switches that use Type::getVT. * getVT => getSingle
* Remove git dependency (#2578)Sam Clegg2020-01-081-1/+1
| | | | | | | Only use git to set version number if .git directory is present. This means that for release archives the VERSION string will be used as-is. Fixes #2563
* Revert "Reland "Fix renaming in FixInvokeFunctionNamesWalker (#2513)" ↵Sam Clegg2020-01-071-26/+15
| | | | | (#2542)" (#2576) This reverts commit f62e171c38bea14302f9b79f7941a248ea704425.