| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Every statement in the IR now gets a fixed unique number. This number
can be used to store statements or information for a statement into an
array where the number is used as an index. This removes the need for
many hashes.
In the process of changing the code the two statement worklists in the
optimizer are merged into one. A single instance can be (and is) re-used
by the various algorithms.
Change-Id: I8f49ec7b1df79cf6914c5747f5d2c994dad110b2
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| | |
Change-Id: Ibf21f5fe0f8ab035add5354f45f7869f4cdfead8
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| | |
Change-Id: I09f9aa1921745b9aa323349d90c334b156f690cb
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
There are a couple of reasons to split the temporaries off from the
arguments and locals:
Temporaries are invisible, and changes to them cannot be observed.
On the other hand, arguments and locals are visible, and writes to them
can be seen from other places (nested functions), or by using the
arguments array. So, in practice these correspond to memory locations.
(One could argue that if neither nested functions, nor eval(), nor
arguments[] is used, the loads/stores are invisible too. But that's an
optimization, and changing locals/arguments to temporaries can be done
in a separate pass.)
Because of the "volatile" nature of arguments and locals, their usage
cannot be optimized. All optimizations (SSA construction, register
allocation, copy elimination, etc.) work on temporaries. Being able to
easily ignore all non-temporaries has the benefit that optimizations can
be faster.
Previously, Temps were not uniquely numbered: argument 1, local 1, and
temporary 1 all had the same number and were distinguishable by their
type. So, for any mapping from Temp to something else, a QHash was used.
Now that Temps only hold proper temporaries, the indexes do uniquely
identify them. Add to that the fact that after transforming to SSA form
all temporaries are renumbered starting from 0 and without any holes in
the numbering, many of those datastructures can be changed to simple
vectors. That change gives a noticeable performance improvement.
One implication of this change is that a number of functions that took
a Temp as their argument, now need to take Temp-or-ArgLocal, so Expr.
However, it turns out that there are very few places where that applies,
as many of those places also need to take constants or names. However,
explicitly separating memory loads/stores for arguments/locals from
temporaries adds the benefit that it's now easier to do a peep-hole
optimizer for those load/store operations in the future: when a load is
directly preceded by a store, it can be eliminated if the value is
still available in a temporary.
Change-Id: I4114006b076795d9ea9fe3649cdb3b9d7b7508f0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |\ \
| | |
| | |
| | | |
refs/staging/dev
|
| | |\|
| | |
| | |
| | | |
Change-Id: I0dd91626837276f5811e4830f4a4e9f89bf1e1bd
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When the storage in the BasicBlockSet is a std::vector<bool>, the
begin() iterator and the ++operator now use std::find. Good STL
implementations have an optimized version specifically for
std::vector<bool> that is a lot faster than the iterating that was used
before. The change also makes the code more readable.
Change-Id: Ic37bac694c133c597b3d61a91b04a0b758516dc3
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |/ /
| |
| |
| |
| |
| |
| |
| |
| |
| | |
No sets, no cry, and no mallocs of QHashNodes.
QBitArray is not used on purpose: good STL implementations specialize
std::find for std::vector<bool>, with a significant speed gain.
Change-Id: Ic986bbd746e96eb494496f0508acb17318f4f0fb
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |/
|
|
|
|
|
|
| |
This allows for overriding methods to customize the printing of nodes.
It also removes some duplicate code.
Change-Id: Ieb9eec2fa7d4e211932d7772586a1d62b119a90a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |\
| |
| |
| | |
Change-Id: I996a85744753598bb48c7e0d7954049202f4f037
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This is among other things needed to fix the qml import scanner to detect
dependencies from .js files correctly.
The patch also fixes the use of Q_QML_EXPORT towards Q_QML_PRIVATE_EXPORT
where appropriate and corrects the wrong include path for the double conversion
code to actually be relative to the file it is included from. This worked by
accident because of other include paths present in the build.
Change-Id: I338583dad2f76300819af8ab0dae8e5724c84430
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| | |
| |
| |
| |
| | |
Change-Id: Ie86bf5902328ad105fb07eb3e2809db21ff024d9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| | |
Change-Id: I565e0a22d4e94495eb427b85a59a62733a815527
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
- Replace 2 QHash<BasicBlock *, ...> with QVector<...>, where the
basic-block index is the index of the vector.
- Nearly all QHashes and QSets will have a minimal fill rate. So,
initialize/reserve all of them with a reasonable minimal size to
prevent re-allocations and re-hashing.
Change-Id: Iade857991d73fddd0b92cecb8d458064b253a08d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | |
| |
| |
| |
| | |
Change-Id: I20ebf44ff0609f6833f7e59a4f2fb312be11b8c1
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
BasicBlocks have an index property which points to the index of that
basic block in the container array in Function. This property can be
used to store calculated information about basic blocks in a vector,
where the vector index corresponds to the basic block index. This is
a lot cheaper than storing any information in a
QHash<BasicBlock *, ....>.
However, this numbering requires that no re-ordering or deletion of
blocks happens. This change cleans up all that handling which was
scattered over a number of places.
Change-Id: I337abd39c030b9d30c82b7bbcf2ba89e50a08e63
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
| |
So far constant propagation was only enabled for
numbers and booleans. Enable it for all types now
and make sure the propagation does the right thing.
Change-Id: I202b0073f463d8a42e34931a736544207284b6dc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
| |
Move all our runtime methods into the QV4::Runtime
struct and give them nicer names without underscores.
Sort them logically and remove a few unused methods.
Change-Id: Ib69b71764ff194d0ba211aac581f9a99734d8180
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
| |
Change-Id: I56b3e5400e7b9880b9534117ac17a80436ff1733
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |
|
|
|
|
|
| |
All are conversions from size_t to int or to unsigned.
Change-Id: Ic94c938dcad6d50a32dd6ec62da2341869cf994d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
| |
QQmlJS::MASM -> QV4::JIT
QQmlJS::V4IR -> QV4::IR
Change-Id: I707e8990459114a699c200fe3c22cec3c8df1afc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
| |
The old code wasn't doing what it promised to do
and failed to remove these expressions.
Change-Id: I6718539fd528f293db537e47ff1c9ac4b27ada55
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
| |
Saves an instruction for shifts with contants
Change-Id: Ia12355d2fe2b9f80631056cda5edd79b45189e99
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
| |
Change-Id: I23a1f5f2c6f782fab315db4725412a9473178b70
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
| |
Change-Id: If336731a49bcb5e1812d50a39cb97e263f23b183
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
| |
Pass in the function object instead of the variablesCanEscape
flag. Cleans up the code a bit.
Change-Id: If2d24b30fb223fa03e27f75f40ad42b881b2b3a0
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |\
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
src/qml/jsruntime/qv4functionobject.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
Change-Id: Id164f6c3b45501aa466908659ec4e3b957323753
|
| | |\
| | |
| | |
| | | |
Change-Id: I5ac68cc3ad3926190817f0d3d5b4526e70badff6
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Statically initializing QObjects will cause e.g. the main
thread pointer in QCoreApplication to be set when the library
is loading. On Android, this is never the real main thread.
The effect was a warning about QApplication not being initialized
on main thread, and a race condition which sometimes caused
apps to hang on startup.
[ChangeLog][Android] Fixed possible hang on startup for Qt Quick
applications.
Task-number: QTBUG-36426
Change-Id: I7bd8a8f35ef1a2548949978563e3157f8dc854c7
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Conversion to int32 might truncate, and because int32 is two's
complement, INT_MIN might get converted incorrectly.
Change-Id: Iaf893d3bd619f4c5791654e609f96cffca5c6917
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Remove all phi nodes whose target temps have no uses. This obvious
optimization was missing.
Change-Id: I24354e225ba7b01a3c2a6f4b2e40dd78d6ee3d7d
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Change the worklist in the optimizeSSA function to allow only one entry
for a statement. This prevents re-processing a statement multiple times,
and could lead to crashes when the statement was removed in an earlier
pass.
Change-Id: I2f09cf74525cfe19708ec7a8bc6d555218625e87
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |\| |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Conflicts:
src/qml/compiler/qv4ssa.cpp
src/qml/jsruntime/qv4arrayobject.cpp
src/qml/jsruntime/qv4context.cpp
Change-Id: Ied5b23bec4dc14abe51127c507aed668f855c1e1
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When a life-time interval is split from another interval, it has to come
before an interval that starts at the same position but is not split.
This also means that a means that the all ranges in a split interval
are uses, which is important for allocation: all incoming parameters for
an operation need to be allocated before allocating a register for the
result as the result will only start its life "at the end" of the
operation.
This patch fixes a problem register allocation is done in a function
where register pressure is high (e.g. on platforms that have few
registers to start with). Specifically, crypto.js on x86 triggered it.
Change-Id: Iee3e5d82a887b8de573dfc23513844143d0c8073
Reviewed-by: Albert Astals Cid <albert.astals@canonical.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | | |
Change-Id: Id1edc073db349cfc7e4b5a9dca045760016ebacf
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Use the life-time intervals to track which temps go out of scope, in
order to re-use the stack-slots they occupied. This reduces the memory
consumption on the JavaScript stack and allows for deeper call stacks.
For the ECMA tests, this reduces the number of slots needed for the
main/entry function from more than 650 to about 10 (depending on the
test).
Change-Id: Iff4044f5ff7f25e1f88ff1a04f4e80dd99a67590
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When a temp is defined by a phi-node, but never used, still insert the
(very short) life range.
Change-Id: Ia976f496736a1606108fab7597c5d90048d9d55a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |/ /
| |
| |
| |
| |
| | |
Change-Id: Ic62ac6be99b79aa2f8c37fc386fef6b04b480247
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |/
|
|
|
|
|
|
|
|
|
| |
Also added some "white-box" unit tests and sprinkled in a bit of
documentation. The case that went wrong is covered by the test
rangeSplitting_1: before the fix, the new interval would have
two ranges: [66-64],[70-71]. The first range is invalid and should not
be there at all.
Change-Id: If0742f4e6a96d98ea5d696f95126886ba66f92bb
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reduces the work for the dominator tree/frontier calculations,
because there are less blocks to consider. All blocks inserted by
splitting the critical edges, have (by definition) no effect on the
dominator calculations. However, the immediate dominators for all new
blocks needs to be added, because this information is used by the block
scheduling.
This change reduces memory/time usage during optimization passes,
especially when processing excessively big switch statements.
Change-Id: Ia69882e9dabdddffa1c98b1079012d8d988e1e8f
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Changes to datastructures and more re-using of locally used temporary
vectors. For the test regress-74474-002.js this lowers the total
allocated memory from 1.98GB to 158MB. Thse peak memory usage stays at
75MB. There is no functional change.
This should give a modest performance improvement which mainly depends
on the speed of malloc()/free().
Change-Id: I1877c1903e59a33ee79ff2b801ef6f2c1cee30a6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
| |
The basic block scheduling uses this information to place loops. When
the immediate dominator information is invalid, the scheduling can be
sub-optimal, or will sometimes forget to schedule some blocks.
Change-Id: Iaeb45f2b757b676310be25a658ceadc07d5722ec
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When doing edge resolving, too many spills were generated, and the
dependency tracking of moves was not complete. Now we only insert spills
that are caused by phi-nodes (because any other spill would be generated
at the point a variable was defined). However, there can still be
multiple dependencies between the moves generated by the edge resolving.
Instead of only checking the first dependency, all of them are tracked.
The bug report was a case where an unneccesary spill was generated, that
got tracked, but "suppressed" the other (valid!) dependent move. The
randomness was caused by the hash seeding of QHash.
Task-number: QTBUG-35840
Change-Id: Ifbc3c8fc13de53c46a8b5859721b2497189921a3
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Changes the dominator frontier storage from a set of basic-blocks for
every basic-block to a BasicBlockSet for every basic-block. This new
class stores a maximum of 8 nodes in a vector, and switches to a bit
vector when going beyond 8 nodes.
This is important in two cases: most basic-blocks have 2-3 nodes in the
frontier, and an array is faster than a set in these cases. The few
cases where the frontier goes beyond 8 nodes, is when a switch
statement is used with lots of cases that all fall-through.
On regress-74474-003.js this reduces peak memory usage from 1.68G
to 60M. The switch statement in this test results in 27000 basic-blocks.
Change-Id: I42646522ba9f8642d42a5d70fc6b760bb47ae69f
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
|
| |
|
|
|
|
|
|
|
| |
Calculation of all the children of nodes in the dominator tree is now
calculated as a local variable right before computing the dominator
frontier. The effect is that they are not retained after their only use.
Change-Id: I83c962c691b78cb767708eb04cf30d3b7a760deb
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |
|
|
|
|
|
|
|
|
| |
Both type inference and the optimization pass do not do anything with
unconditional jumps. So, instead of adding them to the worklist and
later on removing them again, it’s faster to never add them in the first
place.
Change-Id: Ib81d43e9ea6df2b1a70e9dd1e9b9c29cb6d345d2
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |
|
|
|
|
|
|
| |
Replace hashes from basic-block to basic-block with vectors that
associate basic-block index to basic-block index.
Change-Id: I834ea3d825e4d2b02c075b1b0f080f5a65f41317
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
|
| |
|
|
|
|
|
| |
Also fixed some comments.
Change-Id: I4aedff84bdbf8de248025bc48805a859704bdd8a
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
|
| |
|
|
|
|
|
|
| |
This makes time- and memory-complexity a lot better when compiling
big JavaScript functions.
Change-Id: I2a7cb9b5979844254747fa5cf7355cca0b113904
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
|
| |
|
|
|
|
|
|
|
| |
Replace the recursive calls and subsequent clean-ups by pushing actions
on a to-do stack, and processing that stack in a loop.
Change-Id: I83536e88d400592b6e9f5fda3d795e41711a131a
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
|