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
This works because I changed the compiler so that it always emit
the full unoptimized code for all intrinsic methods in a previous CL
As a result deoptimization works for those methods like for normal
methods.
Also, code for some recognized getter methods is moved to the flow
graph builder, so that there is no need for special handling in
the flow graph optimizer. This part of the change is
should be performance-neutral.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//23756002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@26867 260f80e4-7a28-3924-810f-c04153c831b5
The optimizing compiler currently recognizes a certain frequent native methods
like array length or string length and provides an inlined implementation.
Inlining does currently not work for polymorphic call sites of these methods.
This CL enables also polymorphic inlining in the case of .length getters for
arrays and strings.
1. The method is recognized at flow graph build time. The builder creates
the body of the method for both compilers (non-optimizing and optimizing).
Native methods that are not recognized, are translated as before using a NativeCall
IL instruction.
2. The flow graph inliner handles recognized methods in the same manner as normal methods.
Until now intrinsic and recognized method could not be inlined. This CL enables it.
3. There is no need for an intrinsic assembly implementation because recognized methods
have an IL implementation that does not call into the C++ runtime. I left the intrinsics
in for now, but they can be removed if there is not noticable performance benefit anymore.
4. The inlining heuristics are tweaked in a way that enables more aggressive inlining
of recognized methods: +1 level of inlining depths, call sites of recognized methods are
not counted in the inlining heuristic.
R=kmillikin@google.com, srdjan@google.com
Review URL: https://codereview.chromium.org//22839003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@26429 260f80e4-7a28-3924-810f-c04153c831b5
Fix a bug in relational operations in 64 bit mode: if ICData specifies double and Smi as possible arguments, we generate code for double and unbox or convert to double the inputs. These works only if smi can fit into the double. Current solution for 64-bit architecture is to disallow two smi-s as input to a polymorphic comparison instruction (equality, relational).
R=johnmccutchan@google.com
Review URL: https://codereview.chromium.org//20468002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25522 260f80e4-7a28-3924-810f-c04153c831b5
1. When comparing numbers, or strict-comparing objects, this can be folded into
true/false. Since this often occurs after inlining and store-to-load forwarding,
constant propagation is repeated after these phases. The pattern looks like:
o.x = o.y;
if (o.x == o.y) { ... }
2. Load elimination may introduce new phis that may have smi-type. In order to
get range information for these phis, I added a second phase of type propagation after
load elimination.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//16813002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@23901 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
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
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
This CL provides inline IL code for the getters _getInt8, _getInt16, etc.
to speed up [] and byte array views.
The code uses the existing LoadIndexed instructions by passing a index
scale factor explicitly: For normal arrays loads, the scale factor is equal
to the element size. For byte array access, the scale factor is always 1.
I'm adding inlined setters in a separate CL.
Review URL: https://codereview.chromium.org//12218008
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@18173 260f80e4-7a28-3924-810f-c04153c831b5
Introduce InvokeMathCFunction that can be used to directly invoke mathematical
function provided by runtime.
Use it to unconditionally inline _Double.pow.
Use it to inline floor, ceil, round, truncate, round when SSE4.1 is not
available.
Perform representation selection phase after constant propagation to minimize
boxing.
Add support for enter instruction in the x64 disassembler.
Add test for optimized pow and fix compilation on windows.
R=fschneider@google.com
BUG=dart:8002
Review URL: https://codereview.chromium.org//12038013
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@17393 260f80e4-7a28-3924-810f-c04153c831b5
This allows to cache and optimize method extraction requests as normal method invocations and at hot method extraction sites that significantly decreases overhead of method extraction which previously required two trips into runtime system and was not cached at all.
BUG=
Review URL: https://codereview.chromium.org//11642003
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@17261 260f80e4-7a28-3924-810f-c04153c831b5