Place describes a location that code can load from or store to.
Start forwarding loads through phis.
Previously load forwarding operated directly on load instructions which complicated certain things e.g. implementation of a hash map had to allow looking up a load instruction by store instruction, forwarding through phis might have required introducing synthetic load instructions to be put into the map.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//17101028
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@24426 260f80e4-7a28-3924-810f-c04153c831b5
Add profiling support to select OSR candidates and launch the compiler
for OSR, followed by entry to the function at the OSR entry point.
Implemented only on IA32 and X64. The initial implementation can be
improved in various ways --- specifically: tuning of profiling
parameters and incorporation of feedback about the actual values seen
at OSR entry.
R=fschneider@google.com
Review URL: https://codereview.chromium.org//16693006
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@24024 260f80e4-7a28-3924-810f-c04153c831b5
Previously we could not eliminate bounds checks for
growable lists, even though the length is not modified.
This CL removes obsolete restrictions and enables elimination
of checks as long as the length does not change.
This restriction were there originally because the CheckArrayBounds
instruction loaded the length from the array itself. Now, the length-load
and the actual check are split into separate instructions.
Tracking side-effects for normal loads determines can now determine if
the length-load is invariant.
R=vegorov@google.com
Review URL: https://codereview.chromium.org//15984010
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@23688 260f80e4-7a28-3924-810f-c04153c831b5
This CL affects a subset of expressions that use temporary locals: constructor
calls, array literals and and instance getter postfix-ops.
For expressions that are de-sugared in the parser I added LetNode.
It creates a scoped temporary local bound to an initializing expression.
For expressions where we need a temporary local at graph-building time,
I added a helper class TempLocalScope to easily create a single temporary
local in the graph builder since this is a frequently recurring pattern.
This simplifies code in the parser and the graph builder and also fixes a
bug with indexed-super invocation and NoSuchMethod.
BUG=dart:8918
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//14942010
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@23401 260f80e4-7a28-3924-810f-c04153c831b5
This is a first step towards fully optimizing try-catch-finally.
At a catch entry, all local variables and parameters are
expected at a fixed stack location. There is a list of
initial definitions at the catch entry block, similar to
the initial definitions at graph entry.
Inside every try-block there is a special prologue code before each
call (instruction that may throw) inside the try-block. This prologue
is similar to a parallel move instruction: It moves all locals+parameters
to the locations expected by the catch-entry block. The stack frame
is extended with the corresponding number of fixed slots right below
the normal spill slots.
Every function containing try-catch has additional compiler-
generated local variables to pass the context, the exception and
the stack trace.
Variable liveness analysis is adapted to treat locals inside try{} blocks
specially: Every call has an implicit LoadLocal of every local variable.
This CL uses a safe approximiation of liveness which can be optimized further.
Current restrictions which are planned for future CLs:
* No inlining inside try-blocks.
* No inlining of functions containing try-catch.
* No try-finally yet.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//14682020
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22615 260f80e4-7a28-3924-810f-c04153c831b5
AllocationSinking pass discovers non-escaping allocations that have no input uses other than uses in the stores into its own fields.
Every environment use of such allocation is replaced by a state snapshot (MaterializeObject instruction) that describes the state of each initialized field in the object. State snapshots are computed through an additional round of load-forwarding.
Once snapshots are computed allocations are removed from the graph.
MaterializeObject instructions are not compiled into native code but produce deoptimization instructions instead that describe how object should be materialized at deoptimization.
Deoptimization instructions now follow the following format:
[mat obj #1]...[mat obj #N][ret addr][... mat arguments ...][... real frames ...]
- the prefix describes each object to materialize on deopt via kMaterializeObject instruction;
- actual values that are needed for materialization are emited as a part of bottom-most stack frame. This is done to simplify implementation: they need to be discoverable by a GC during materialization phase. At the end of deoptimization they will be removed from the stack;
- normal stack slots can refer to materialized objects via kMaterializedObjectRef instruction.
Additionally this change contains fixes in load-forwarding that are needed to guarantee that all artificial LoadField instructions inserted during AllocationSinking are correctly replaced with actual values.
Limitations of the current implementation:
- can't eliminate allocations that flow into phis but otherwise don't actually escape;
- can't sink allocations out of loops;
- allocation with type arguments are not handled.
R=regis@google.com, srdjan@google.com, zra@google.com
Review URL: https://codereview.chromium.org//14935005
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22485 260f80e4-7a28-3924-810f-c04153c831b5
- stores/loads that access different fields can't alias each other;
- if result of the AllocateObject does not escape then stores/loads to it does not alias stores/loads to other objects.
Other:
- rename LoadFieldInstr's value to instance to better convey meaning and match StoreInstanceFieldInstr;
- slightly bump inlining_size_threshold;
- canonicalize UnboxDouble(BoxDouble(v)) and BoxDouble(UnboxDouble(v)) patterns;
R=srdjan@google.com
BUG=
Review URL: https://codereview.chromium.org//14872002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22340 260f80e4-7a28-3924-810f-c04153c831b5
This CL runs a second round of constant propagation after range
analysis to eliminate additional unreachable code. Range analysis
is changed to mark branches as constant if the constraints they
generate are unsatisfiable.
The second pass of constant propagation only visits branches and
removes unreachable code, but does not do full constant propagation.
This proves useful when inlining array view operations where the
following pattern occurs:
for (i = 0; i < length; i++) {
if (i < 0 || i >= length) {
throw 123;
}
foo();
}
In this example the if-statement will be eliminated completely.
Also, fix a bug in range analyis where constraints of already
constrained values were missing.
Review URL: https://codereview.chromium.org//13469013
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@20914 260f80e4-7a28-3924-810f-c04153c831b5
This CL removes optimized access for scalarlist, and only the new TypedData classes
are optimized. I changed the runtime libraries core and math to use typedData
instead of scalarlist (Uint16List is used in StringBuffer, Uint32List by Math.random).
Instead of using LoadIndexed for internal and external arrays,
split external loads into a load of the backing store and a load
of the element.
v3 <- LoadIndexed(v1, index)
becomes
v2 <- LoadUntagged(v1, ExternalTypedData::data_offset)
v3 <- LoadIndexed(v2, index);
For this I introduce two new representations in the IL:
kUntagged (for values that hold a untagged pointer) and
kNoRepresentation (for instructions accept any input
representation)
Deoptimization does not need to know about kUntagged
since these values can never occur in the environment.
Also with this change:
* fix COMPILE_ASSERT and use it in one place.
* Cleanup IL printer output of deopt ids.
Review URL: https://codereview.chromium.org//12871010
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@20198 260f80e4-7a28-3924-810f-c04153c831b5
This is a preparation CL for supporting try-catch in optimized code. Until
now, we used normal TargetEntryInstr for catch blocks.
This meant carrying around handler_types_ and catch_try_index_ for blocks
that are not catch blocks which is not needed.
For now, CatchBlockEntry behaves the same as TargetBlockEntry except for
the additional members needed for catch blocks.
Review URL: https://codereview.chromium.org//12600012
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@19864 260f80e4-7a28-3924-810f-c04153c831b5
Branch optimization pushes some branches that test the value of a phi
to the predecessor blocks. This can avoid materializing a boolean
object solely for the purposes of branching on its boolean value.
The optimization is performed after inlinining which creates
opportunities, and before constant propagation, because it exposes
opportunities for unreachable code elimination.
R=vegorov@google.com
BUG=
Review URL: https://codereview.chromium.org//12540002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@19682 260f80e4-7a28-3924-810f-c04153c831b5
Previously we removed dead phis late, in the register allocator. This
change removes them as soon as they are discovered to be dead and packs the
phi array to squeeze out NULLs. This speeds iteration but doesn't save
space because the phi array is zone-allocated.
The PhiIterator is used everywhere to iterate phis except a few places that
need to know the phi index (e.g., SSA construction, phi elimination).
R=vegorov@google.com
Review URL: https://codereview.chromium.org//12340108
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@19206 260f80e4-7a28-3924-810f-c04153c831b5