This allows the optimizing compiler to generate unboxed loads/stores
to fields containing double values. The double value is stored
in a reusable double object.
Unboxed loads/stores are generated for optimized code. Unoptimized code
allocates a new double on loads. To avoid performance regressions
for fields that are only written few times (e.g. only in the constructor)
I put a heuristic in place that
compares the usage count of setters and getters. Unboxed operations
are only generated if the setter is invoked a significant amount of
times (threshold is 10% of getter invocations).
The CL is so big because it changes the way LocationSummmary
is allocated: We now have a bit to generate different summaries
for optimized and unoptimized code.
R=srdjan@google.com
Review URL: https://codereview.chromium.org//99573005
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@31164 260f80e4-7a28-3924-810f-c04153c831b5
In unoptimized code equality is now just another instance call.
The optimizer replaces it with a specialized implementation based on static
type information and type feedback.
Many of the manual optimizations of == in the optimizer are now just handled
by the generic inliner, plus polymorphic inlining of == calls is now possible.
This also eliminates the need for a lot of duplicated code in the backend.
I adapted the inlining heuristics to compensate for the slightly larger
inital flow graph size.
Review URL: https://codereview.chromium.org//27307005
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@29800 260f80e4-7a28-3924-810f-c04153c831b5
If the propagated type allows, eliminate the check for numbers at
identical operations in optimized code.
The previous optimizaton was done before full type propagation was run
and was therefore not very effective.
* Made flow-graph printing having no side-effects: calling Type() lazily
initializes the type_ and reaching_type_ fields of Value and Definition.
Access fields directly when printing instead.
Also, fixed two random spelling mistakes.
R=srdjan@google.com
Review URL: https://codereview.chromium.org//27727002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28851 260f80e4-7a28-3924-810f-c04153c831b5
Handle LoadClassId in constant propagation. This helps with eliminating
unreachable code after polymorphic inlining. It exposed a bug which is
also fixed in this CL.
Redefinitions of values have to be considered for load/store forwarding:
Loads/stores to an object defined by a RedefinitionInstr (inserted by
polymorphic inlining) must be treated properly as loads/stores to the
original object.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//25640004
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28159 260f80e4-7a28-3924-810f-c04153c831b5
Instead of having a separate IL instructions relational comparisons
are built as normal instance calls initially. When optimized, we replace
the instance call with a smi/double/mint comparison instruction.
This enables generic inlining of relational operator calls and simplifies
code generation, too.
Merging comparisons with branches is done in the optimizing compiler's
branch simplification phase.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//23757016
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27058 260f80e4-7a28-3924-810f-c04153c831b5
When nesting try-finally, the outer finally was incorrectly executed
twice under certain conditions (a return in the inner try-block and a outer
finally-block that ends with throw)
This was because finally-code was inlined at return/break/continue statements
and it was associated with the wrong catch-handler when compiling.
This CL tracks indices of try-blocks in the parser so that each inlined
finally block has the correct catch handler index.
BUG=https://code.google.com/p/dart/issues/detail?id=11972
TEST=test/language/throw8_test.dart
R=hausner@google.com
Review URL: https://codereview.chromium.org//22184003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25767 260f80e4-7a28-3924-810f-c04153c831b5
In optimized code we can eliminate the allocation of closures that are not
escaping and where all calls are inlined.
Closures are currently allocated with a special IL instruction (CreateClosure).
This CL changes this for non-implicit closures and allocates them
like normal objects. The fields for the function and the context are
initialized like instance fields. This way object allocation sinking can
handle closures like any other objects.
R=srdjan@google.com
Review URL: https://codereview.chromium.org//19370003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25706 260f80e4-7a28-3924-810f-c04153c831b5
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
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 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
Turn CompileType into a value object instead of zone object. Provide a transparent zone allocated wrapper for CompileType. This simplifies code paths that recompute and update type and reduces number of allocated zone objects.
Split ComputeInitialType into ComputeInitialType and ComputeType.
ComputeType returns values type as a value object. ComputeInitialType returns a pointer and by default it delegates to ComputeType.
This split reflects differences between instructions: majority of them have their own type, but some can return the type of an input which should not be unwrapped and rewrapped again because this will destroy the connection between types.
R=kmillikin@google.com
BUG=
Review URL: https://codereview.chromium.org//12330072
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18895 260f80e4-7a28-3924-810f-c04153c831b5
Remove SminessPropagator and FlowGraphTypePropagator and all associated infrastructure and fields.
Replace multiple fields (result_cid_, propagated_cid_, propagated_type_, reaching_cid_) with a single field of type CompileType which represents an element of type analysis lattice and incorporates information about: value's nullability, concrete class id and abstract super type. This ensures that propagated cid and type are always in sync and complement each other
Implement a new FlowGraphPropagator that propagates types over the CompileType-lattice.
R=fschneider@google.com
Review URL: https://codereview.chromium.org//12260008
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18456 260f80e4-7a28-3924-810f-c04153c831b5
Replace multiple fields (result_cid_, propagated_cid_, propagated_type_, reaching_cid_) with a single field of type CompileType which represents an element of type analysis lattice and incorporates information about: value's nullability, concrete class id and abstract super type. This ensures that propagated cid and type are always in sync and complement each other
Implement a new FlowGraphPropagator that propagates types over the CompileType-lattice.
BUG=
Review URL: https://codereview.chromium.org//12221119
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18377 260f80e4-7a28-3924-810f-c04153c831b5