Skip to content

Commit 5434c12

Browse files
authored
Move optimization pipeline from JS to Wasm (#1234)
1 parent f96d3fc commit 5434c12

File tree

4 files changed

+252
-305
lines changed

4 files changed

+252
-305
lines changed

cli/asc.js

+11-212
Original file line numberDiff line numberDiff line change
@@ -635,26 +635,22 @@ exports.main = function main(argv, options, callback) {
635635
if (args.trapMode === "clamp") {
636636
stats.optimizeCount++;
637637
stats.optimizeTime += measure(() => {
638-
module.runPasses([ "trap-mode-clamp" ]);
638+
module.runPass("trap-mode-clamp");
639639
});
640640
} else if (args.trapMode === "js") {
641641
stats.optimizeCount++;
642642
stats.optimizeTime += measure(() => {
643-
module.runPasses([ "trap-mode-js" ]);
643+
module.runPass("trap-mode-js");
644644
});
645645
} else if (args.trapMode !== "allow") {
646646
module.dispose();
647647
return callback(Error("Unsupported trap mode"));
648648
}
649649

650-
// Implicitly run costly non-LLVM optimizations on -O3 or -Oz
651-
// see: https://github.com/WebAssembly/binaryen/pull/1596
652-
if (optimizeLevel >= 3 || shrinkLevel >= 2) optimizeLevel = 4;
653-
654-
module.setOptimizeLevel(optimizeLevel);
655-
module.setShrinkLevel(shrinkLevel);
656-
module.setDebugInfo(args.debug);
657-
650+
// Optimize the module
651+
const debugInfo = args.debug;
652+
const usesARC = args.runtime == "half" || args.runtime == "full";
653+
const converge = args.converge;
658654
const runPasses = [];
659655
if (args.runPasses) {
660656
if (typeof args.runPasses === "string") {
@@ -668,213 +664,16 @@ exports.main = function main(argv, options, callback) {
668664
}
669665
}
670666

671-
function doOptimize() {
672-
const hasARC = args.runtime == "half" || args.runtime == "full";
673-
const passes = [];
674-
function add(pass) { passes.push(pass); }
675-
676-
if (optimizeLevel >= 2 && shrinkLevel === 0) {
677-
// tweak inlining options when speed more preferable than size
678-
module.setAlwaysInlineMaxSize(12);
679-
module.setFlexibleInlineMaxSize(70);
680-
module.setOneCallerInlineMaxSize(200);
681-
} else {
682-
// tweak inlining options when size matters
683-
optimizeLevel === 0 && shrinkLevel >= 0
684-
? module.setAlwaysInlineMaxSize(2)
685-
: module.setAlwaysInlineMaxSize(4); // default: 2
686-
module.setFlexibleInlineMaxSize(65); // default: 20
687-
module.setOneCallerInlineMaxSize(80); // default: 15
688-
}
689-
690-
// Optimize the module if requested
691-
if (optimizeLevel > 0 || shrinkLevel > 0) {
692-
// Binaryen's default passes with Post-AssemblyScript passes added.
693-
// see: Binaryen/src/pass.cpp
694-
695-
// PassRunner::addDefaultGlobalOptimizationPrePasses
696-
add("duplicate-function-elimination");
697-
add("remove-unused-module-elements"); // differs
698-
699-
// PassRunner::addDefaultFunctionOptimizationPasses
700-
if (optimizeLevel >= 3 || shrinkLevel >= 1) {
701-
add("ssa-nomerge");
702-
}
703-
if (optimizeLevel >= 3) {
704-
add("flatten"); // differs
705-
add("simplify-locals-notee-nostructure"); // differs
706-
add("vacuum"); // differs
707-
add("code-folding"); // differs
708-
add("flatten");
709-
add("local-cse");
710-
add("reorder-locals"); // differs
711-
}
712-
if (optimizeLevel >= 2 || shrinkLevel >= 1) { // differs
713-
add("rse");
714-
add("vacuum");
715-
}
716-
if (hasARC) { // differs
717-
if (optimizeLevel < 3) {
718-
add("flatten");
719-
}
720-
add("post-assemblyscript");
721-
}
722-
add("optimize-instructions"); // differs
723-
add("inlining"); // differs
724-
add("dce");
725-
add("remove-unused-brs");
726-
add("remove-unused-names");
727-
add("inlining-optimizing"); // differs
728-
if (optimizeLevel >= 2 || shrinkLevel >= 1) {
729-
add("pick-load-signs");
730-
add("simplify-globals-optimizing"); // differs
731-
}
732-
if (optimizeLevel >= 3 || shrinkLevel >= 2) {
733-
add("precompute-propagate");
734-
} else {
735-
add("precompute");
736-
}
737-
add("vacuum"); // differs
738-
// this will be done later (1)
739-
// if (optimizeLevel >= 2 || shrinkLevel >= 2) {
740-
// add("code-pushing");
741-
// }
742-
if (optimizeLevel >= 3 && shrinkLevel <= 1) { // differs
743-
add("licm");
744-
}
745-
add("simplify-locals-nostructure");
746-
add("vacuum");
747-
add("reorder-locals");
748-
add("remove-unused-brs");
749-
// if (optimizeLevel >= 3 || shrinkLevel >= 2) { // do it later
750-
// add("merge-locals");
751-
// }
752-
add("coalesce-locals");
753-
add("simplify-locals");
754-
add("vacuum");
755-
add("reorder-locals");
756-
add("coalesce-locals");
757-
add("reorder-locals");
758-
if (optimizeLevel >= 3 || shrinkLevel >= 1) { // differs
759-
add("merge-locals");
760-
}
761-
add("vacuum");
762-
if (optimizeLevel >= 3 || shrinkLevel >= 1) {
763-
add("code-folding");
764-
}
765-
if (optimizeLevel >= 2 || shrinkLevel >= 1) { // differs
766-
add("simplify-globals-optimizing");
767-
}
768-
add("merge-blocks");
769-
add("remove-unused-brs");
770-
add("remove-unused-names");
771-
add("merge-blocks");
772-
// make this later & move to (2)
773-
// if (optimizeLevel >= 3 || shrinkLevel >= 2) {
774-
// add("precompute-propagate");
775-
// } else {
776-
// add("precompute");
777-
// }
778-
if (optimizeLevel >= 3) {
779-
add("optimize-instructions");
780-
}
781-
if (optimizeLevel >= 2 || shrinkLevel >= 1) {
782-
add("rse");
783-
}
784-
add("vacuum");
785-
// PassRunner::addDefaultGlobalOptimizationPostPasses
786-
if (optimizeLevel >= 2 || shrinkLevel >= 1) {
787-
add("simplify-globals-optimizing"); // differs
788-
add("dae-optimizing");
789-
}
790-
if (optimizeLevel >= 2 || shrinkLevel >= 2) {
791-
add("inlining-optimizing");
792-
}
793-
if (module.getLowMemoryUnused()) {
794-
if (optimizeLevel >= 3 || shrinkLevel >= 1) {
795-
add("optimize-added-constants-propagate");
796-
} else {
797-
add("optimize-added-constants");
798-
}
799-
}
800-
// "duplicate-function-elimination" will better done later
801-
// add("duplicate-function-elimination");
802-
add("duplicate-import-elimination");
803-
if (optimizeLevel >= 2 || shrinkLevel >= 2) {
804-
add("simplify-globals-optimizing");
805-
} else {
806-
add("simplify-globals");
807-
add("vacuum"); // differs
808-
}
809-
// moved from (2)
810-
// it works better after globals optimizations like simplify-globals, inlining-optimizing and etc
811-
if (optimizeLevel >= 2 || shrinkLevel >= 1) { // differs
812-
add("precompute-propagate");
813-
} else {
814-
add("precompute");
815-
}
816-
// replace indirect calls with direct, reduce arity and
817-
// inline this calls if possible
818-
add("directize"); // differs
819-
add("dae-optimizing"); // differs
820-
add("inlining-optimizing"); // differs
821-
// ARC finalization should be done exactly after inlining for better release/retain reduction
822-
if (hasARC) { // differs
823-
add("post-assemblyscript-finalize");
824-
}
825-
if (optimizeLevel >= 2 || shrinkLevel >= 1) { // differs
826-
add("rse");
827-
// move some code after early return which potentially could reduce computations
828-
// do this after CFG cleanup (originally it was done before)
829-
// moved from (1)
830-
add("code-pushing");
831-
if (optimizeLevel >= 3) {
832-
// this quite expensive so do this only for highest opt level
833-
add("simplify-globals");
834-
add("vacuum");
835-
// replace indirect calls with direct and inline if possible again.
836-
add("inlining-optimizing");
837-
add("directize");
838-
add("dae-optimizing");
839-
add("precompute-propagate");
840-
add("vacuum");
841-
add("merge-locals");
842-
add("coalesce-locals");
843-
add("simplify-locals-nostructure");
844-
add("vacuum");
845-
add("inlining-optimizing");
846-
add("precompute-propagate");
847-
}
848-
add("remove-unused-brs");
849-
add("remove-unused-names");
850-
add("vacuum");
851-
add("optimize-instructions");
852-
add("simplify-globals-optimizing");
853-
}
854-
// remove unused elements of table and pack / reduce memory
855-
add("duplicate-function-elimination"); // differs
856-
add("remove-unused-nonfunction-module-elements"); // differs
857-
add("memory-packing");
858-
add("remove-unused-module-elements"); // differs
859-
// It seems stack-ir unuseful for our needs.
860-
// if (optimizeLevel >= 3 || shrinkLevel >= 1) { // differs. was optimizeLevel >= 2
861-
// add("generate-stack-ir");
862-
// add("optimize-stack-ir");
863-
// }
864-
}
865-
866-
// Append additional passes if requested and execute
867-
module.runPasses(passes.concat(runPasses));
868-
}
869-
870667
stats.optimizeTime += measure(() => {
871668
stats.optimizeCount++;
872-
doOptimize();
873-
if (args.converge) {
669+
module.optimize(optimizeLevel, shrinkLevel, debugInfo, usesARC);
670+
module.runPasses(runPasses);
671+
if (converge) {
874672
let last = module.toBinary();
875673
do {
876674
stats.optimizeCount++;
877-
doOptimize();
675+
module.optimize(optimizeLevel, shrinkLevel, debugInfo, usesARC);
676+
module.runPasses(runPasses);
878677
let next = module.toBinary();
879678
if (next.output.length >= last.output.length) {
880679
if (next.output.length > last.output.length) {

0 commit comments

Comments
 (0)