mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Add compiler hints
This commit is contained in:
parent
3ed4f3331e
commit
82da2d1f6d
84
cli/asc.js
84
cli/asc.js
@ -384,6 +384,45 @@ exports.main = function main(argv, options, callback) {
|
||||
// Finish parsing
|
||||
const program = assemblyscript.finishParsing(parser);
|
||||
|
||||
// Set up optimization levels
|
||||
var optimizeLevel = -1;
|
||||
var shrinkLevel = 0;
|
||||
var debugInfo = !args.noDebug;
|
||||
if (args.optimize !== false) {
|
||||
if (typeof args.optimize === "number") {
|
||||
optimizeLevel = args.optimize;
|
||||
} else if (args["0"]) {
|
||||
optimizeLevel = 0;
|
||||
} else if (args["1"]) {
|
||||
optimizeLevel = 1;
|
||||
} else if (args["2"]) {
|
||||
optimizeLevel = 2;
|
||||
} else if (args["3"]) {
|
||||
optimizeLevel = 3;
|
||||
} else if (args.optimize === true) {
|
||||
optimizeLevel = exports.defaultOptimizeLevel;
|
||||
shrinkLevel = exports.defaultShrinkLevel;
|
||||
} else
|
||||
optimizeLevel = 0;
|
||||
}
|
||||
if (args["s"]) {
|
||||
shrinkLevel = 1;
|
||||
} else if (args["z"]) {
|
||||
shrinkLevel = 2;
|
||||
}
|
||||
if (typeof args.optimizeLevel === "number") {
|
||||
optimizeLevel = args.optimizeLevel;
|
||||
}
|
||||
if (typeof args.shrinkLevel === "number") {
|
||||
shrinkLevel = args.shrinkLevel;
|
||||
} else if (args.shrinkLevel === "s") {
|
||||
shrinkLevel = 1;
|
||||
} else if (args.shrinkLevel === "z") {
|
||||
shrinkLevel = 2;
|
||||
}
|
||||
optimizeLevel = Math.max(optimizeLevel, 0);
|
||||
shrinkLevel = Math.max(shrinkLevel, 0);
|
||||
|
||||
// Begin compilation
|
||||
const compilerOptions = assemblyscript.createOptions();
|
||||
assemblyscript.setTarget(compilerOptions, 0);
|
||||
@ -393,6 +432,7 @@ exports.main = function main(argv, options, callback) {
|
||||
assemblyscript.setImportTable(compilerOptions, !!args.importTable);
|
||||
assemblyscript.setMemoryBase(compilerOptions, args.memoryBase >>> 0);
|
||||
assemblyscript.setSourceMap(compilerOptions, args.sourceMap != null);
|
||||
assemblyscript.setOptimizeLevelHints(compilerOptions, optimizeLevel, shrinkLevel);
|
||||
|
||||
// Initialize default aliases
|
||||
assemblyscript.setGlobalAlias(compilerOptions, "Math", "NativeMath");
|
||||
@ -469,51 +509,11 @@ exports.main = function main(argv, options, callback) {
|
||||
return callback(Error("Unsupported trap mode"));
|
||||
}
|
||||
|
||||
var optimizeLevel = -1;
|
||||
var shrinkLevel = 0;
|
||||
var debugInfo = !args.noDebug;
|
||||
|
||||
if (args.optimize !== false) {
|
||||
if (typeof args.optimize === "number") {
|
||||
optimizeLevel = args.optimize;
|
||||
} else if (args["0"]) {
|
||||
optimizeLevel = 0;
|
||||
} else if (args["1"]) {
|
||||
optimizeLevel = 1;
|
||||
} else if (args["2"]) {
|
||||
optimizeLevel = 2;
|
||||
} else if (args["3"]) {
|
||||
optimizeLevel = 3;
|
||||
} else if (args.optimize === true) {
|
||||
optimizeLevel = exports.defaultOptimizeLevel;
|
||||
shrinkLevel = exports.defaultShrinkLevel;
|
||||
} else
|
||||
optimizeLevel = 0;
|
||||
}
|
||||
|
||||
if (args["s"]) {
|
||||
shrinkLevel = 1;
|
||||
} else if (args["z"]) {
|
||||
shrinkLevel = 2;
|
||||
}
|
||||
|
||||
if (typeof args.optimizeLevel === "number") {
|
||||
optimizeLevel = args.optimizeLevel;
|
||||
}
|
||||
|
||||
if (typeof args.shrinkLevel === "number") {
|
||||
shrinkLevel = args.shrinkLevel;
|
||||
} else if (args.shrinkLevel === "s") {
|
||||
shrinkLevel = 1;
|
||||
} else if (args.shrinkLevel === "z") {
|
||||
shrinkLevel = 2;
|
||||
}
|
||||
|
||||
// Implicitly run costly non-LLVM optimizations on -O3 or -Oz
|
||||
// see: https://github.com/WebAssembly/binaryen/pull/1596
|
||||
if (optimizeLevel >= 3 || shrinkLevel >= 2) optimizeLevel = 4;
|
||||
|
||||
module.setOptimizeLevel(optimizeLevel > 0 ? optimizeLevel : 0);
|
||||
module.setOptimizeLevel(optimizeLevel);
|
||||
module.setShrinkLevel(shrinkLevel);
|
||||
module.setDebugInfo(debugInfo);
|
||||
|
||||
@ -531,7 +531,7 @@ exports.main = function main(argv, options, callback) {
|
||||
}
|
||||
|
||||
// Optimize the module if requested
|
||||
if (optimizeLevel >= 0) {
|
||||
if (optimizeLevel > 0 || shrinkLevel > 0) {
|
||||
stats.optimizeCount++;
|
||||
stats.optimizeTime += measure(() => {
|
||||
module.optimize();
|
||||
|
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -177,15 +177,20 @@ export class Options {
|
||||
importMemory: bool = false;
|
||||
/** If true, imports the function table provided by the embedder. */
|
||||
importTable: bool = false;
|
||||
/** Static memory start offset. */
|
||||
memoryBase: u32 = 0;
|
||||
/** If true, generates information necessary for source maps. */
|
||||
sourceMap: bool = false;
|
||||
/** Static memory start offset. */
|
||||
memoryBase: i32 = 0;
|
||||
/** Global aliases. */
|
||||
globalAliases: Map<string,string> | null = null;
|
||||
/** Additional features to activate. */
|
||||
features: Feature = Feature.NONE;
|
||||
|
||||
/** Hinted optimize level. Not applied by the compiler itself. */
|
||||
optimizeLevelHint: i32 = 0;
|
||||
/** Hinted shrink level. Not applied by the compiler itself. */
|
||||
shrinkLevelHint: i32 = 0;
|
||||
|
||||
/** Tests if the target is WASM64 or, otherwise, WASM32. */
|
||||
get isWasm64(): bool {
|
||||
return this.target == Target.WASM64;
|
||||
@ -251,8 +256,8 @@ export class Compiler extends DiagnosticEmitter {
|
||||
module: Module;
|
||||
/** Current function in compilation. */
|
||||
currentFunction: Function;
|
||||
/** Outer function in compilation, if compiling a function expression. */
|
||||
outerFunction: Function | null = null;
|
||||
/** Current outer function in compilation, if compiling a function expression. */
|
||||
currentOuterFunction: Function | null = null;
|
||||
/** Current enum in compilation. */
|
||||
currentEnum: Enum | null = null;
|
||||
/** Current type in compilation. */
|
||||
@ -2045,13 +2050,20 @@ export class Compiler extends DiagnosticEmitter {
|
||||
let local = new Local(program, name, -1, type);
|
||||
switch (getExpressionType(initExpr)) {
|
||||
case NativeType.I32: {
|
||||
local = local.withConstantIntegerValue(getConstValueI32(initExpr), 0);
|
||||
local = local.withConstantIntegerValue(
|
||||
i64_new(
|
||||
getConstValueI32(initExpr),
|
||||
0
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
case NativeType.I64: {
|
||||
local = local.withConstantIntegerValue(
|
||||
getConstValueI64Low(initExpr),
|
||||
getConstValueI64High(initExpr)
|
||||
i64_new(
|
||||
getConstValueI64Low(initExpr),
|
||||
getConstValueI64High(initExpr)
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
@ -134,6 +134,12 @@ export function enableFeature(options: Options, feature: Feature): void {
|
||||
options.features |= feature;
|
||||
}
|
||||
|
||||
/** Gives the compiler a hint at the optimize levels that will be used later on. */
|
||||
export function setOptimizeLevelHints(options: Options, optimizeLevel: i32, shrinkLevel: i32): void {
|
||||
options.optimizeLevelHint = optimizeLevel;
|
||||
options.shrinkLevelHint = shrinkLevel;
|
||||
}
|
||||
|
||||
/** Finishes parsing. */
|
||||
export function finishParsing(parser: Parser): Program {
|
||||
return parser.finish();
|
||||
|
@ -15,7 +15,8 @@ import {
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Options
|
||||
Options,
|
||||
Feature
|
||||
} from "./compiler";
|
||||
|
||||
import {
|
||||
@ -371,6 +372,8 @@ export class Program extends DiagnosticEmitter {
|
||||
/** Initializes the program and its elements prior to compilation. */
|
||||
initialize(options: Options): void {
|
||||
this.options = options;
|
||||
|
||||
// add built-in types
|
||||
this.typesLookup = new Map([
|
||||
["i8", Type.i8],
|
||||
["i16", Type.i16],
|
||||
@ -390,6 +393,25 @@ export class Program extends DiagnosticEmitter {
|
||||
["boolean", Type.bool]
|
||||
]);
|
||||
|
||||
// add compiler hints
|
||||
this.setConstantInteger("ASC_TARGET", Type.i32,
|
||||
i64_new(options.isWasm64 ? 2 : 1));
|
||||
this.setConstantInteger("ASC_NO_TREESHAKING", Type.bool,
|
||||
i64_new(options.noTreeShaking ? 1 : 0, 0));
|
||||
this.setConstantInteger("ASC_NO_ASSERT", Type.bool,
|
||||
i64_new(options.noAssert ? 1 : 0, 0));
|
||||
this.setConstantInteger("ASC_MEMORY_BASE", Type.i32,
|
||||
i64_new(options.memoryBase, 0));
|
||||
this.setConstantInteger("ASC_OPTIMIZE_LEVEL", Type.i32,
|
||||
i64_new(options.optimizeLevelHint, 0));
|
||||
this.setConstantInteger("ASC_SHRINK_LEVEL", Type.i32,
|
||||
i64_new(options.shrinkLevelHint, 0));
|
||||
this.setConstantInteger("ASC_FEATURE_MUTABLE_GLOBAL", Type.bool,
|
||||
i64_new(options.hasFeature(Feature.MUTABLE_GLOBAL) ? 1 : 0, 0));
|
||||
this.setConstantInteger("ASC_FEATURE_SIGN_EXTENSION", Type.bool,
|
||||
i64_new(options.hasFeature(Feature.SIGN_EXTENSION) ? 1 : 0, 0));
|
||||
|
||||
// remember deferred elements
|
||||
var queuedImports = new Array<QueuedImport>();
|
||||
var queuedExports = new Map<string,QueuedExport>();
|
||||
var queuedExtends = new Array<ClassPrototype>();
|
||||
@ -617,6 +639,24 @@ export class Program extends DiagnosticEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets a constant integer value. */
|
||||
setConstantInteger(globalName: string, type: Type, value: I64): void {
|
||||
assert(type.is(TypeFlags.INTEGER));
|
||||
this.elementsLookup.set(globalName,
|
||||
new Global(this, globalName, globalName, type, null, DecoratorFlags.NONE)
|
||||
.withConstantIntegerValue(value)
|
||||
);
|
||||
}
|
||||
|
||||
/** Sets a constant float value. */
|
||||
setConstantFloat(globalName: string, type: Type, value: f64): void {
|
||||
assert(type.is(TypeFlags.FLOAT));
|
||||
this.elementsLookup.set(globalName,
|
||||
new Global(this, globalName, globalName, type, null, DecoratorFlags.NONE)
|
||||
.withConstantFloatValue(value)
|
||||
);
|
||||
}
|
||||
|
||||
/** Tries to resolve an import by traversing exports and queued exports. */
|
||||
private tryResolveImport(
|
||||
externalName: string,
|
||||
@ -2670,9 +2710,9 @@ export class VariableLikeElement extends Element {
|
||||
this.declaration = declaration;
|
||||
}
|
||||
|
||||
withConstantIntegerValue(lo: i32, hi: i32): this {
|
||||
withConstantIntegerValue(value: I64): this {
|
||||
this.constantValueKind = ConstantValueKind.INTEGER;
|
||||
this.constantIntegerValue = i64_new(lo, hi);
|
||||
this.constantIntegerValue = value;
|
||||
this.set(CommonFlags.CONST | CommonFlags.INLINED);
|
||||
return this;
|
||||
}
|
||||
|
17
std/assembly.d.ts
vendored
17
std/assembly.d.ts
vendored
@ -34,6 +34,23 @@ declare type f32 = number;
|
||||
/** A 64-bit float. */
|
||||
declare type f64 = number;
|
||||
|
||||
/** Compiler target. 0 = JS, 1 = WASM32, 2 = WASM64. */
|
||||
declare const ASC_TARGET: i32;
|
||||
/** Provided noTreeshaking option. */
|
||||
declare const ASC_NO_TREESHAKING: bool;
|
||||
/** Provided noAssert option. */
|
||||
declare const ASC_NO_ASSERT: bool;
|
||||
/** Provided memoryBase option. */
|
||||
declare const ASC_MEMORY_BASE: i32;
|
||||
/** Provided optimizeLevel option. */
|
||||
declare const ASC_OPTIMIZE_LEVEL: i32;
|
||||
/** Provided shrinkLevel option. */
|
||||
declare const ASC_SHRINK_LEVEL: i32;
|
||||
/** Whether the mutable global feature is enabled. */
|
||||
declare const ASC_FEATURE_MUTABLE_GLOBAL: bool;
|
||||
/** Whether the sign extension feature is enabled. */
|
||||
declare const ASC_FEATURE_SIGN_EXTENSION: bool;
|
||||
|
||||
/** Converts any other numeric value to an 8-bit signed integer. */
|
||||
declare function i8(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i8 {
|
||||
|
3
std/portable.d.ts
vendored
3
std/portable.d.ts
vendored
@ -28,6 +28,9 @@ declare type usize = number;
|
||||
declare type f32 = number;
|
||||
declare type f64 = number;
|
||||
|
||||
/** Compiler target. 0 = JS, 1 = WASM32, 2 = WASM64. */
|
||||
declare const ASC_TARGET: i32;
|
||||
|
||||
/** Converts any other numeric value to an 8-bit signed integer. */
|
||||
declare function i8(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
|
||||
declare namespace i8 {
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self;
|
||||
|
||||
globalScope.ASC_TARGET = 0;
|
||||
|
||||
Object.defineProperties(
|
||||
globalScope["i8"] = function i8(value) { return value << 24 >> 24; }
|
||||
, {
|
||||
|
4
tests/compiler/asc-constants.optimized.wat
Normal file
4
tests/compiler/asc-constants.optimized.wat
Normal file
@ -0,0 +1,4 @@
|
||||
(module
|
||||
(memory $0 0)
|
||||
(export "memory" (memory $0))
|
||||
)
|
8
tests/compiler/asc-constants.ts
Normal file
8
tests/compiler/asc-constants.ts
Normal file
@ -0,0 +1,8 @@
|
||||
ASC_TARGET;
|
||||
ASC_NO_TREESHAKING;
|
||||
ASC_NO_ASSERT;
|
||||
ASC_MEMORY_BASE;
|
||||
ASC_OPTIMIZE_LEVEL;
|
||||
ASC_SHRINK_LEVEL;
|
||||
ASC_FEATURE_MUTABLE_GLOBAL;
|
||||
ASC_FEATURE_SIGN_EXTENSION;
|
33
tests/compiler/asc-constants.untouched.wat
Normal file
33
tests/compiler/asc-constants.untouched.wat
Normal file
@ -0,0 +1,33 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $HEAP_BASE i32 (i32.const 8))
|
||||
(memory $0 0)
|
||||
(export "memory" (memory $0))
|
||||
(start $start)
|
||||
(func $start (; 0 ;) (type $v)
|
||||
(drop
|
||||
(i32.const 1)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
(drop
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
@ -1,9 +1,16 @@
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
var colors = require("../cli/util/colors");
|
||||
var glob = require("glob");
|
||||
var diff = require("./util/diff");
|
||||
|
||||
require("ts-node").register({ project: require("path").join(__dirname, "..", "src", "tsconfig.json") });
|
||||
require("ts-node").register({
|
||||
project: require("path").join(__dirname, "..", "src", "tsconfig.json"),
|
||||
files: [ // see: https://github.com/TypeStrong/ts-node/issues/620
|
||||
path.join(__dirname, "..", "std", "portable.d.ts"),
|
||||
path.join(__dirname, "..", "src", "glue", "binaryen.d.ts")
|
||||
]
|
||||
});
|
||||
require("../src/glue/js");
|
||||
|
||||
var Parser = require("../src/parser").Parser;
|
||||
|
Loading…
x
Reference in New Issue
Block a user