Change default feature set to MVP#1993
Conversation
This greatly simplifies the feature handling logic and does not change the user experience when a target features section is present. Also refactors features to be stored on the Module after they are read out of the target features section, allowing us to emit a (potentially modified) target features section and conditionally emit sections based on features, such as the DataCount section.
| @@ -1 +1 @@ | |||
| {"version":3,"sources":["tests/hello_world.c","tests/other_file.cpp","return.cpp","even-opted.cpp","fib.c","/tmp/emscripten_test_binaryen2_28hnAe/src.c","(unknown)"],"names":[],"mappings":"yLAIA,IACA,ICyylTA,aC7vlTA,OAkDA,0BCnGA,OACA,OACA,uBCAA,4BAKA,QAJA,OADA,8CAKA,0ICsi1DA,MCrvyDA"} No newline at end of file | |||
There was a problem hiding this comment.
TBH I have no idea what this change means.
There was a problem hiding this comment.
I think it means that things moved around - the location of code is not the same as before. That's surprising, I think?
There was a problem hiding this comment.
Aha, this is because I changed the element section to only be emitted if it has any elements. That moved the code section up in the file.
| run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm']) | ||
| after = os.stat('c.wasm').st_size | ||
| assert after < 0.6 * before, [before, after] | ||
| assert after < 0.7 * before, [before, after] |
There was a problem hiding this comment.
I haven't really examined why this changed yet.
There was a problem hiding this comment.
We should definitely look into that before landing, yeah, since this PR should be NFC wrt this test?
kripken
left a comment
There was a problem hiding this comment.
Nice, mostly lgtm, but some issues left for discussion first.
| run_command(WASM_REDUCE + ['a.wasm', '--command=%s b.wasm --fuzz-exec' % WASM_OPT[0], '-t', 'b.wasm', '-w', 'c.wasm']) | ||
| after = os.stat('c.wasm').st_size | ||
| assert after < 0.6 * before, [before, after] | ||
| assert after < 0.7 * before, [before, after] |
There was a problem hiding this comment.
We should definitely look into that before landing, yeah, since this PR should be NFC wrt this test?
| }; | ||
|
|
||
| Pass *createStripTargetFeaturesPass() { | ||
| return new FeaturesStrip(); |
There was a problem hiding this comment.
why is the pass StripTargetFeatures and the instance FeaturesStrip? I think the convention we have is to keep them the same (i.e. both are the former).
| std::vector<std::string> debugInfoFileNames; | ||
|
|
||
| FeatureSet features = FeatureSet::MVP; | ||
| bool emitFeaturesSection = false; |
There was a problem hiding this comment.
Perhaps we should handle the features section the same way we handle the names section - we read it if it's there, but we don't emit it unless the user specifically asks us to?
There was a problem hiding this comment.
Hmm, it would make sense to unify what we do with the features section and the names section (and the producers section? I forget what we do there). OTOH, it is very useful to preserve the features section through long chains of wasm-opt calls such as when running the reducer. Otherwise all but the first call of wasm-opt would have a validation failure.
There was a problem hiding this comment.
I believe we decided offline to leave this how it is for now but to leave this open for unification with how we treat other sections in the future.
There was a problem hiding this comment.
(and rename to hasFeaturesSection)
| } | ||
|
|
||
| void WasmBinaryWriter::writeFeaturesSection() { | ||
| if (!wasm->emitFeaturesSection || wasm->features <= FeatureSet{}) { |
There was a problem hiding this comment.
does the right side of the if mean "if MVP, don't emit the features section"?
There was a problem hiding this comment.
Yes, I forgot about the isMVP() method which I should definitely use here.
| @@ -1 +1 @@ | |||
| {"version":3,"sources":["tests/hello_world.c","tests/other_file.cpp","return.cpp","even-opted.cpp","fib.c","/tmp/emscripten_test_binaryen2_28hnAe/src.c","(unknown)"],"names":[],"mappings":"yLAIA,IACA,ICyylTA,aC7vlTA,OAkDA,0BCnGA,OACA,OACA,uBCAA,4BAKA,QAJA,OADA,8CAKA,0ICsi1DA,MCrvyDA"} No newline at end of file | |||
There was a problem hiding this comment.
I think it means that things moved around - the location of code is not the same as before. That's surprising, I think?
The change in debug location is due to the newly-elided element section.
|
Having to sprinkle |
|
I believe WABT simply enables all features all the time (AFAIK it doesn't have any feature options). This makes sense for tools that read but do not modify modules and is what we do for wasm-as and wasm-dis. Tools that can modify modules need to know what features they are allowed to use, and it seems best to be conservative about that. That being said, we probably do have more |
Also: - Error when target features do not exactly match feature options - Add --print-features pass and use it in testing
|
@kripken PTAL. This PR move towards implementing the plan described in #2004. I also expect this to fix current waterfall breakage, though I have not finished testing locally.
There is not yet a way to crawl a binary and detect what features it uses. |
kripken
left a comment
There was a problem hiding this comment.
lgtm with those comments fixed
| Module wasm; | ||
| ModuleReader reader; | ||
| reader.read(working, *module); | ||
| wasm.features = FeatureSet::All; |
There was a problem hiding this comment.
I'm not sure this is optimal - it might lead the optimizer to attempt odd things that hurt reduction. Please add a comment that we should likely autodetect features from the binary here instead, once we can do that.
| { | ||
| // read and write it | ||
| auto cmd = Path::getBinaryenBinaryTool("wasm-opt") + " " + input + " -o " + test; | ||
| auto cmd = Path::getBinaryenBinaryTool("wasm-opt") + " " + input + " -all -o " + test; |
| if (debug) std::cerr << "getInt8: " << (int)(uint8_t)input[pos] << " (at " << pos << ")" << std::endl; | ||
| return input[pos++]; | ||
| if (debug) std::cerr << "getInt8: " << (int)(uint8_t)input.at(pos) << " (at " << pos << ")" << std::endl; | ||
| return input.at(pos++); |
There was a problem hiding this comment.
why is this change here? seems offtopic for the PR; also we already have a check right above it that throws an error.
There was a problem hiding this comment.
Right, sorry. My reverting of this change in #2001 was not backported to this branch. Fixing.
| - Add `segmentPassive` argument to `BinaryenSetMemory` for marking segments | ||
| passive. | ||
| - Make `-o -` print to stdout instead of a file named "-". | ||
| - Change default feature set in the absence of a target features section from |
There was a problem hiding this comment.
This should go up above in Current Trunk
| testcase.assertEqual(str(p.stdout), str(f.read())) | ||
|
|
||
|
|
||
| def disassemble(self, filename): |
There was a problem hiding this comment.
Surely these should be left as members? They take self as arg0 after all.
There was a problem hiding this comment.
Yes, but I want to share them across multiple unittest.TestCase subclasses. I suppose the proper way to do that would be to make all my test cases inherit from a new class that contains these methods.
Sorry, missed this. Wabt does have feature flags for all tools. But |
This reverts commit cb2d635. The issues with feature validation were mostly resolved in WebAssembly#1993, and this PR finishes the job by adding feature flags to wasm-as to avoid emitting the DataCount section when bulk-memory is not enabled.
This greatly simplifies the feature handling logic and does not
change the user experience when a target features section is present.
Also refactors features to be stored on the Module after they are read
out of the target features section, allowing us to emit a (potentially
modified) target features section and conditionally emit sections
based on features, such as the DataCount section.