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
This CL is the first step in refactoring the way branches and comparisons
are generated.
1. Move helper functions from flow_graph_compiler_xyz.cc to
intermediate_language_xyz.cc.
2. Remove IL class ControlInstruction. It was only implemented by BranchInstr.
All functions provided are moved to BranchInstr.
3. When generating branch code for comparisons, pass the successor labels explicitly
instead of getting them from the branch. This will allow us to provide different labels
when materialize a bool value of a comparison.
4. Move some common code for IfThenElseInstr from the platform-specific files
into intermediate_language.cc and simplify it.
The goal is to enable if-conversion of arbitrary comparisons. Right now,
the code for == is hard-coded in IfThenElseInstr (and duplicated, too). This
means that e.g. "a < b ? 0 : 1" cannot be optimized.
As a result, IfThenElseInstr can be used to materialize the boolean value of
a comparison. This way the complication of having ComparisonInstr both as a
normal instruction and as wrapped inside a BranchInstr can be simplified.
Comparisons would no longer appear as plain instructions in the IL, but only
wrapped inside either a Branch or an IfThenElse(true, false).
R=zra@google.com
Review URL: https://codereview.chromium.org//62133002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@30042 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
Branches that have the same true/false target, or where both
target blocks reach the same common join block via empty blocks
can be replaced by a goto to the common join block.
In code like this
var a = unknown();
var b = null;
if (a == null || b == null) {
...
}
it eliminates the test (a == null) if b is known to be null. Until now,
the compiler could only eliminate the test for b, if a was known.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//23549020
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28050 260f80e4-7a28-3924-810f-c04153c831b5
This CL adds the necessary parts to enable polymorphic
inlining of recognized methods. For now it handles only
[]-calls. This helps code that deals with e.g. growable
and fixed-length lists.
The basic idea is to adapt the code in the flow graph
optimizer so that it can be used from the generic inliner.
Currently this adds a bit of boilerplate code which I intend
to reduce when adding more recognized methods to be handled.
R=johnmccutchan@google.com
Review URL: https://codereview.chromium.org//23684059
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27627 260f80e4-7a28-3924-810f-c04153c831b5
This CL is the first step in enabling full inlining of == calls.
Previously, calls to any function with the name "==" were not considered
for inlining because super-calls were not handled correctly. Instead
of implementing == semantics for super calls in the back-end, the parser
now expands super calls to == into
let t1 = left, t2 = right {
(t1 === null || t2 === null) ? t1 === t2
: static_call(super.==, t1, t2)
}
This change removes a bit of platform-specific assembly. Normal instance calls
to == are still translated as before. Expanding those at the AST level would
incur a too high cost in terms of (unoptimized) code size, and also would be
an obstruction for optimizations of equality. The plan is to expand those
only at optimization time if there is an inlineable instance call to ==.
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//23627009
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27248 260f80e4-7a28-3924-810f-c04153c831b5
The IsPowerOfTwo function is used together with ShiftForPowerOfTwo. Both function
do not work with zero. This caused the optimizing compiler to generate invalid code
for the expression
x ? 0 : 0
where it assumed that if one of the constants is a power-of-two, it can
be computed by (1 << n). We check for 0 in a number of places, but instead
I decided to fix Utils::IsPowerOfTwo itself and remove unnecessary checks
for the zero case.
TEST=tests/language/vm/if_conversion_vm_test.dart, runtime/vm/utils_test.cc
R=kmillikin@google.com
Review URL: https://codereview.chromium.org//23604024
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@27033 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