The builder instead creates a LetCont with an unused continuation to
hold the unreachable code following the non-tail throw.
This removes the cleanup pass after building and removes an awkward
CPS node.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1243063002.
We now only introduce one getInterceptor call per primitive.
(The main use for GVN seemed to be cleaning up these calls, but we
might as well not introduce them in the first place).
To propagate single-used interceptors to their use, propagation of
constant-like expressions has changed.
There is a new CPS pass, let sinking, which sinks single-used pure
primitives to their use when the use is not inside a loop.
Conversely, the tree IR's assignment propagation has been made less
aggressive to compensate for things now handled by let sinking.
R=floitsch@google.com
Review URL: https://codereview.chromium.org//1238163003.
SetStatic, SetField, and SetMutableVariable are now primitives instead
of interior expressions. They are valueless primitives, i.e. they are
bound by LetPrim but their value is never referenced.
This should simplify basic block traversal, since there are now fewer
types of interior expressions.
The four remaining interior expressions are: LetPrim, LetCont,
LetHandler, and LetMutable. Incidentally, these are exactly the four
expressions that can bind definitions.
GetMutableVariable and SetMutableVariable have also been renamed
to GetMutable and SetMutable to be uniform with LetMutable.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1240263002.
When running as a content script in a Chrome extension `document.contentScript` is set to `null`. We should take that value instead of trying to compute another one based on script tags (the work-around we have for IE). Since content-scripts are not part of the page, it might be that there aren't even any other scripts and the work-around mechanism simply fails (thus not starting the main function).
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1224363004 .
Main changes are in the added files, compiler/compiler.dart, src/compiler.dart and src/apiimpl.dart.
Start by looking at compiler/compiler_new.dart and compiler/compiler.dart.
BUG=
R=floitsch@google.com
Review URL: https://codereview.chromium.org//1235563003.
There is a new pass that optimizes for continuations that branch on a
parameter, where every invocation passes a constant as that parameter.
This avoids unnecessary boolean flags that can arise from specializing a
call to a method that returns a boolean.
A current short-coming is that this lives in its own pass.
I believe shrinking reductions and redundant joins elimination can
trigger redexes of each other, so in theory we may still get redundant
joins in the output. The two passes might need to be reorganized at
some point.
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1229893002.
For example, the code (assuming 'list' is a native list):
for (var x in list) {
print(x);
}
Becomes:
var i = 0, x = null, $length = list.length, v0;
while (true) {
if (i < list.length) {
x = list[i];
i = i + 1;
v0 = true;
} else {
x = null;
v0 = false;
}
if (!v0)
return null;
P.print(x);
if ($length !== list.length)
H.throwConcurrentModificationError(list);
}
This is clearly in need of redundant join elimination, which is an
optimization that I plan to land separately.
After redundant join elimination it becomes:
var i = 0, x = null, $length = list.length;
while (i < list.length) {
x = list[i];
i = i + 1;
P.print(x);
if ($length !== list.length)
H.throwConcurrentModificationError(list);
}
x = null;
There is still room for improvement regarding redundant assignemnts
to 'x'. They occur because x is a MutableVariable. Rewriting these
into "SSA variables" (continuation parameters) is another optimization
we may want to implement.
BUG=
R=floitsch@google.com
Review URL: https://codereview.chromium.org//1229563005.
Assignment propagation traverses the tree backwards, and should therefore
visit the branch condition of an 'if' after its two branches.
It happened to work (in the sense of not breaking the code) but
only for very subtle reasons.
This fixes an optimization bug that prevented assignments from
propagating to their first use when the first use was in a branch
condition.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1226353003.
Without reflection, redirecting factory constructor invocations are shortcut at the instantiation site. With reflection, code like
reflectClass(Foo).newInstance(const Symbol(''), [])
can hit a redirecting factory constructor and we need to emit a function that does the redirection and type substitution.
R=asgerf@google.com
Review URL: https://codereview.chromium.org//1227873004 .
We now split a LetCont before moving it, so we do not move other
continuation bindings.
The bug surfaced when working on redundant join elimination.
I don't think it can be reproduced with the current set of
optimizations, so the fix is not visible in the tests.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1222913009.
length, forEach, [], and []= are rewritten to direct array access nodes.
There are more methods to specialize, which will be added in separate
CLs.
This CL also contains a class CpsFragment to help build CPS code.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1223813006.
The world will refuse to emit getters and setters for field it thinks
will be accessed directly.
Rewriting getter/setter calls to field accesses must happen at
build-time so we do not rely on an optimization for correctness.
BUG=
R=karlklose@google.com
Review URL: https://codereview.chromium.org//1227543008.