Skip to content

Commit

Permalink
feat(compiler)!: Replace optimization levels with compilation profiles (
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed May 29, 2022
1 parent 96e8ecb commit 1a27c12
Show file tree
Hide file tree
Showing 333 changed files with 44,252 additions and 31,217 deletions.
41 changes: 30 additions & 11 deletions cli/bin/grain.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,34 @@ class ForwardOption extends program.Option {
}
}

class ProfileOption extends program.Option {
// Like ForwardOption, ProfileOption is forwarded to the underlying program
// but we convert the flag into a profile flag, i.e. `--release` becomes `--profile=release`
forward = true;

toFlag(opts) {
const attribute = this.attributeName();
if (opts[attribute]) {
return `--profile=${attribute}`;
}
}
}

const optionApplicator = (Option) =>
function (flags, description, parser, defaultValue) {
const option = new Option(flags, description);
if (parser) option.argParser(parser);
if (typeof defaultValue !== "undefined") option.default(defaultValue);
return this.addOption(option);
};

// Adds .forwardOption to commands. Similar to Commander's native .option,
// but will forward the flag to the underlying program.
program.Command.prototype.forwardOption = function (
flags,
description,
parser,
defaultValue
) {
const option = new ForwardOption(flags, description);
if (parser) option.argParser(parser);
if (typeof defaultValue !== "undefined") option.default(defaultValue);
return this.addOption(option);
};
program.Command.prototype.forwardOption = optionApplicator(ForwardOption);

// Adds .profileOption to commands. Similar to Commander's native .option,
// but will convert the flag from the shorthand to the full form.
program.Command.prototype.profileOption = optionApplicator(ProfileOption);

program
.option("-v, --version", "output CLI and compiler versions")
Expand Down Expand Up @@ -123,6 +138,10 @@ program
"--elide-type-info",
"don't include runtime type information used by toString/print"
)
.profileOption(
"--release",
"compile using the release profile (production mode)"
)
.forwardOption(
"--experimental-wasm-tail-call",
"enables tail-call optimization"
Expand Down
8 changes: 3 additions & 5 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -3866,11 +3866,9 @@ let compile_wasm_module = (~env=?, ~name=?, prog) => {
);
validate_module(~name?, wasm_mod);

switch (Config.optimization_level^) {
| Level_three => Optimize_mod.optimize(wasm_mod)
| Level_zero
| Level_one
| Level_two => ()
switch (Config.profile^) {
| Some(Release) => Optimize_mod.optimize(wasm_mod)
| None => ()
};
wasm_mod;
};
Expand Down
8 changes: 1 addition & 7 deletions compiler/src/compile.re
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,7 @@ let next_state = (~is_root_file=false, {cstate_desc, cstate_filename} as cs) =>
TypedWellFormed(typed_mod);
| TypedWellFormed(typed_mod) =>
Linearized(Linearize.transl_anf_module(typed_mod))
| Linearized(anfed) =>
switch (Grain_utils.Config.optimization_level^) {
| Level_one
| Level_two
| Level_three => Optimized(Optimize.optimize_program(anfed))
| Level_zero => Optimized(anfed)
}
| Linearized(anfed) => Optimized(Optimize.optimize_program(anfed))
| Optimized(optimized) =>
Mashed(Transl_anf.transl_anf_program(optimized))
| Mashed(mashed) =>
Expand Down
8 changes: 3 additions & 5 deletions compiler/src/linking/link.re
Original file line number Diff line number Diff line change
Expand Up @@ -611,11 +611,9 @@ let link_modules = ({asm: wasm_mod, signature}) => {
if (Module.validate(linked_mod) != 1) {
failwith("Generated invalid linked module");
};
switch (Config.optimization_level^) {
| Level_three => Optimize_mod.optimize(linked_mod)
| Level_zero
| Level_one
| Level_two => ()
switch (Config.profile^) {
| Some(Release) => Optimize_mod.optimize(linked_mod)
| None => ()
};
linked_mod;
};
23 changes: 7 additions & 16 deletions compiler/src/utils/config.re
Original file line number Diff line number Diff line change
Expand Up @@ -384,24 +384,15 @@ let option_conv = ((prsr, prntr)) => (
| Some(x) => prntr(ppf, x),
);

type optimization_level =
| Level_zero
| Level_one
| Level_two
| Level_three;
type profile =
| Release;

let optimization_level =
let profile =
opt(
~doc="Set the optimization level.",
~names=["O"],
~conv=
Cmdliner.Arg.enum([
("0", Level_zero),
("1", Level_one),
("2", Level_two),
("3", Level_three),
]),
Level_three,
~doc="Set a compilation profile.",
~names=["profile"],
~conv=Cmdliner.Arg.enum([("release", Some(Release))]),
None,
);

let default_memory_base = 0x400;
Expand Down
11 changes: 4 additions & 7 deletions compiler/src/utils/config.rei
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
type optimization_level =
| Level_zero
| Level_one
| Level_two
| Level_three;
type profile =
| Release;

/** The Grain stdlib directory, based on the current configuration */
let stdlib_directory: unit => option(string);
Expand Down Expand Up @@ -43,9 +40,9 @@ let wasi_polyfill: ref(option(string));

let use_start_section: ref(bool);

/** Whether optimizations should be run */
/** Compilation profile, e.g. release for production builds */

let optimization_level: ref(optimization_level);
let profile: ref(option(profile));

// [NOTE] This default is here because it is used in multiple locations,
// and it doesn't make sense for it to be "owned" by any of them.
Expand Down
215 changes: 130 additions & 85 deletions compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ arrays › array_access
(type $none_=>_i32 (func (result i32)))
(type $none_=>_none (func))
(import \"_grainEnv\" \"mem\" (memory $0 0))
(import \"_grainEnv\" \"tbl\" (table $tbl 0 funcref))
(import \"_grainEnv\" \"relocBase\" (global $relocBase_0 i32))
(import \"_grainEnv\" \"moduleRuntimeId\" (global $moduleRuntimeId_0 i32))
(import \"GRAIN$MODULE$runtime/exception\" \"GRAIN$EXPORT$printException\" (global $GRAIN$EXPORT$printException_0 (mut i32)))
(import \"GRAIN$MODULE$runtime/exception\" \"GRAIN$EXPORT$IndexOutOfBounds\" (global $GRAIN$EXPORT$IndexOutOfBounds_0 (mut i32)))
(import \"GRAIN$MODULE$runtime/gc\" \"GRAIN$EXPORT$malloc\" (global $GRAIN$EXPORT$malloc_0 (mut i32)))
Expand All @@ -16,104 +18,147 @@ arrays › array_access
(import \"GRAIN$MODULE$runtime/exception\" \"printException\" (func $printException_0 (param i32 i32) (result i32)))
(global $x_1131 (mut i32) (i32.const 0))
(global $GRAIN$TABLE_SIZE i32 (i32.const 0))
(elem $elem (global.get $relocBase_0))
(export \"memory\" (memory $0))
(export \"_gmain\" (func $_gmain))
(export \"_start\" (func $_start))
(export \"GRAIN$TABLE_SIZE\" (global $GRAIN$TABLE_SIZE))
(func $_gmain (; has Stack IR ;) (result i32)
(func $_gmain (result i32)
(local $0 i32)
(local $1 i32)
(i32.store
(local.tee $0
(call $malloc_0
(global.get $GRAIN$EXPORT$malloc_0)
(i32.const 20)
)
)
(i32.const 4)
)
(i32.store offset=4
(local.get $0)
(i32.const 3)
)
(i32.store offset=8
(local.get $0)
(i32.const 3)
)
(i32.store offset=12
(local.get $0)
(i32.const 5)
)
(i32.store offset=16
(local.get $0)
(i32.const 7)
)
(global.set $x_1131
(tuple.extract 0
(tuple.make
(local.get $0)
(call $decRef_0
(global.get $GRAIN$EXPORT$decRef_0)
(global.get $x_1131)
)
)
)
)
(if
(i32.lt_s
(local.tee $0
(i32.const 0)
)
(i32.sub
(i32.const 0)
(i32.load offset=4
(local.tee $1
(global.get $x_1131)
(local $2 i32)
(local $3 i64)
(local $4 f32)
(local $5 f64)
(return
(block $cleanup_locals.8 (result i32)
(local.set $0
(block $compile_block.7 (result i32)
(block $compile_store.3
(global.set $x_1131
(tuple.extract 0
(tuple.make
(block $allocate_array.1 (result i32)
(i32.store
(local.tee $0
(call $malloc_0
(global.get $GRAIN$EXPORT$malloc_0)
(i32.const 20)
)
)
(i32.const 4)
)
(i32.store offset=4
(local.get $0)
(i32.const 3)
)
(i32.store offset=8
(local.get $0)
(i32.const 3)
)
(i32.store offset=12
(local.get $0)
(i32.const 5)
)
(i32.store offset=16
(local.get $0)
(i32.const 7)
)
(local.get $0)
)
(call $decRef_0
(global.get $GRAIN$EXPORT$decRef_0)
(global.get $x_1131)
)
)
)
)
(block $do_backpatches.2
)
)
(block $MArrayGet.6 (result i32)
(local.set $1
(i32.shr_s
(i32.const 1)
(i32.const 1)
)
)
(local.set $2
(global.get $x_1131)
)
(if
(i32.gt_s
(i32.mul
(i32.load offset=4
(local.get $2)
)
(i32.const -1)
)
(local.get $1)
)
(drop
(block $call_error_handler.5
(drop
(call $printException_0
(global.get $GRAIN$EXPORT$printException_0)
(global.get $GRAIN$EXPORT$IndexOutOfBounds_0)
)
)
(unreachable)
)
)
)
(if
(i32.le_s
(i32.load offset=4
(local.get $2)
)
(local.get $1)
)
(drop
(block $call_error_handler.4
(drop
(call $printException_0
(global.get $GRAIN$EXPORT$printException_0)
(global.get $GRAIN$EXPORT$IndexOutOfBounds_0)
)
)
(unreachable)
)
)
)
(call $incRef_0
(global.get $GRAIN$EXPORT$incRef_0)
(i32.load offset=8
(i32.add
(i32.mul
(if (result i32)
(i32.lt_s
(local.get $1)
(i32.const 0)
)
(i32.add
(local.get $1)
(i32.load offset=4
(local.get $2)
)
)
(local.get $1)
)
(i32.const 4)
)
(local.get $2)
)
)
)
)
)
)
)
(block
(drop
(call $printException_0
(global.get $GRAIN$EXPORT$printException_0)
(global.get $GRAIN$EXPORT$IndexOutOfBounds_0)
)
)
(unreachable)
)
)
(if
(i32.le_s
(i32.load offset=4
(local.get $1)
)
(local.get $0)
)
(block
(drop
(call $printException_0
(global.get $GRAIN$EXPORT$printException_0)
(global.get $GRAIN$EXPORT$IndexOutOfBounds_0)
)
)
(unreachable)
)
)
(call $incRef_0
(global.get $GRAIN$EXPORT$incRef_0)
(i32.load offset=8
(i32.add
(i32.shl
(local.get $0)
(i32.const 2)
)
(local.get $1)
)
)
)
)
(func $_start (; has Stack IR ;)
(func $_start
(drop
(call $_gmain)
)
Expand Down
Loading

0 comments on commit 1a27c12

Please sign in to comment.