aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4ssa.cpp
Commit message (Collapse)AuthorAgeFilesLines
* V4: Replace QVector with (Q)VarLengthArray in BasicBlock.Erik Verbruggen2016-01-061-1/+1
| | | | | | | | | This prevents extra mallocs in nearly all cases, because the number of incoming edges is not that big. The outgoing edge count has a maximum of two. Change-Id: I89195809952ce6087c5af51d717a4c2d8ac6b853 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* V4: do not run optimizer for functions of >300 statements.Erik Verbruggen2015-10-231-2/+5
| | | | | | | | | | | | | | | | | | | The time it takes to run the optimizer depends on both the number of IR statements, and the number of basic-blocks. Many functions that have more than 300 statements are either the %entry point, or methods that set a large number of member variables. Both are not performance sensitive, so skipping them won't hurt execution speed. Actually, not optimizing them does improve startup speed. Basic blocks need to contain at least one statement (the terminator), so a large number basic blocks always results in at least an equal number of IR statements. Therefore they do not need to be taken into account. (An example of an excessive amount of basic blocks is a switch with 9000 cases: this will generate ~27000 basic blocks.) Change-Id: Iabf809d8ad293f4f27ece06d136aa281991a1b0f Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* QML: Sanitize reading environment variables.Friedemann Kleint2015-10-221-4/+4
| | | | | | | | | | | Where possible, use qEnvironmentVariableIsSet()/ qEnvironmentVariableIsEmpty() instead of checking on the return value of qgetenv(). Where the value is required, add a check using one of qEnvironmentVariableIsSet()/Empty(). Change-Id: Ia8b7534e6f5165bd8a6b4e63ccc139c42dd03056 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* Remove line numbers for statements without side-effects.Erik Verbruggen2015-10-151-46/+95
| | | | | | | | | | | | | When debug mode is not enabled, line numbers are only used in order to generate usable stack traces. Therefore statements that cannot fail/throw do not need line numbers associated with them. Of course, when debug mode is enabled, this is not applicable. The effect is that the generated code for such statements shrinks by 2 loads and 1 store. Change-Id: I4ec425dd20b56043e8ca0e4c68afc683eb9b50e7 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* Initialize member variable.Erik Verbruggen2015-10-131-0/+1
| | | | | | | It's never used (because it's qSwap()ed), but still. Change-Id: I64cbb39dcd9f9368c73b5b9bf98dc1f3a52a13ef Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* Minor cleanupLars Knoll2015-09-251-1/+1
| | | | | Change-Id: I478967dacc6f0e7b8a6df706bb878f46306871ce Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
* Merge remote-tracking branch 'origin/5.5' into 5.6Ulf Hermann2015-08-181-2/+2
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: src/qml/debugger/qv4debugservice.cpp src/qml/jsruntime/qv4value_inl_p.h src/qml/jsruntime/qv4value_p.h src/qml/memory/qv4mm.cpp src/qml/memory/qv4mm_p.h src/qml/qml/qqmlnotifier_p.h src/qml/qml/qqmlproperty.cpp src/quick/items/qquickflickable.cpp src/quick/items/qquicktextedit.cpp tests/auto/quick/qquickwindow/BLACKLIST The extra changes in qqmlbinding.cpp are ported from changes to qqmlproperty.cpp that occurred in parallel with writeBinding() being moved to qqmlbinding.cpp. Change-Id: I16d1920abf448c29a01822256f52153651a56356
| * Work around ICC 16 beta compiler bug in SFINAE expansionThiago Macieira2015-07-311-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Calling std::vector<int>'s constructor (or assign()) with two ints can select one of two different overloads: the (size_t, value_type) overload which fills with n copies of the value or (iterator, iterator) overload, which would copy a range. libstdc++ had some workarounds for this scenario, by using an indirect dispatch to determine whether it was a pair of integrals or not. But ever since the resolution of DR1234 (https://gcc.gnu.org/bugzilla/ show_bug.cgi?id=43813) with C++11's more expressive SFINAE, the dispatching is done actually by the outer template by adding an extra template parameter that requires std::iterator_traite<T> to expand. That's where ICC fails: it expands std::iterator_traits<int> and that fails. It should have ignored the expansion and discarded that overload. The workaround is simple: pass different types as the parameters, which means the compiler cannot select the overload containing a pair of iterators. /usr/include/c++/5/bits/stl_iterator_base_types.h(154): error: name followed by "::" must be a class or namespace name typedef typename _Iterator::iterator_category iterator_category; ^ detected during: instantiation of class "std::__iterator_traits<_Iterator, void> [with _Iterator=int]" at line 163 instantiation of class "std::iterator_traits<_Iterator> [with _Iterator=int]" at line 876 of "compiler/qv4ssa.cpp" Change-Id: I52dd43c12685407bb9a6ffff13f5f783820213a5 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
* | qml: Avoid heap allocations due to QString::fromLatin1()Sérgio Martins2015-08-131-1/+1
| | | | | | | | | | | | | | By using QStringLiteral when the argument is a literal. Change-Id: Ib25042d10f3d9d0aca81af74cde0107aba4f9432 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* | Access the id objects through a specialized runtime methodLars Knoll2015-08-121-2/+2
|/ | | | | | | | This brings us one step closer to getting rid of the QQmlContextWrapper. Change-Id: Ied57f4c174c2ebd95096310a4ad4c0c28787e7a4 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
* Add a version of BitVector that uses QBitArray.Erik Verbruggen2015-06-081-0/+54
| | | | | | | | | | Some C++ STL libraries are unable to ship a bug-free std::vector<bool>, and/or a bug-free specialization of std::find for std::vector<bool>. So, for those platforms there now is a slow version of BitVector, which relies on QBitArray, which we can fix if we find bugs. Change-Id: I5ddfb18cabe82049a7ede6083fe6ba142bca068b Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
* Wrap std::vector<bool> in our own class.Erik Verbruggen2015-06-081-74/+112
| | | | | | | | So we can replace the implementation when we encounter a broken version of std::vector<bool> or a broken specialization of std::find for it. Change-Id: I7d7c0af585388ddedf5167cd9863c52ab638442d Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
* V4: fix phi node use position calculation.Erik Verbruggen2015-03-031-1/+7
| | | | | | | | | | | | | | As phi-nodes get transformed into moves, and the moves end up right before the terminator of the basic block of the incoming edge, the use by that phi-node is the position of that terminator minus one. However, when checking if uses need a register, this was not taken into account, resulting in an invalid life-time interval split position calculation. Task-number: QTBUG-44687 Change-Id: I0edd416f7ee5c8ea16bf7133870be45d0e6efea9 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@theqtcompany.com>
* Update copyright headersJani Heikkinen2015-02-121-7/+7
| | | | | | | | | Qt copyrights are now in The Qt Company, so we could update the source code headers accordingly. In the same go we should also fix the links to point to qt.io. Change-Id: I61120571787870c0ed17066afb31779b1e6e30e9 Reviewed-by: Iikka Eklund <iikka.eklund@theqtcompany.com>
* Move Stmt::d to Phi::dRobin Burchell2015-01-231-2/+2
| | | | | | | Phi is the only thing using it. Change-Id: I2b6706884d9e41cc26632a6ad72281b391960f4f Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
* Get rid of most uses of ValueRefLars Knoll2015-01-231-8/+8
| | | | | | | | | | | | Instead pass a const Value & into the functions With our new inheritance structure, we can get rid of ValueRef and instead simply pass a pointer to a Value again. Pointers to Values are safe to use again now, as they are now guaranteed to be in a place where the GC knows about them. Change-Id: I44c606fde764db3993b8128fd6fb781d3a298e53 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* QML: Fix MSVC 2013/64bit warnings.Friedemann Kleint2015-01-221-14/+17
| | | | | | | | | | | | | | | | | | | | | | | | | compiler\qv4ssa.cpp(687) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data compiler\qv4ssa.cpp(950) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data compiler\qv4ssa.cpp(1117) : warning C4267: 'return' : conversion from 'size_t' to 'unsigned int', possible loss of data compiler\qv4ssa.cpp(1120) : warning C4267: 'return' : conversion from 'size_t' to 'unsigned int', possible loss of data compiler\qv4ssa.cpp(1148) : warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data compiler\qv4ssa.cpp(1266) : warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data compiler\qv4ssa.cpp(1622) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data compiler\qv4ssa.cpp(2246) : warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data compiler\qv4ssa.cpp(4289) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data compiler\qv4ssa.cpp(4351) : warning C4267: 'initializing' : conversion from 'size_t' to 'unsigned int', possible loss of data jit\qv4regalloc.cpp(1383) : warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data jit\qv4regalloc.cpp(1769) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data jit\qv4regalloc.cpp(1814) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data jsruntime\qv4mm.cpp(496) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data jsruntime\qv4mm.cpp(503) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data jsruntime\qv4mm.cpp(506) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data jsruntime\qv4regexp.cpp(60) : warning C4267: 'return' : conversion from 'size_t' to 'uint', possible loss of data jsruntime\qv4typedarray.cpp(85) : warning C4309: '=' : truncation of constant value Change-Id: I0b04e1a9d379c068fb3efe90a9db8b592061e448 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Remove not required std::vector::reserve() callsLars Knoll2015-01-201-2/+0
| | | | | | | | | | | These actually force more reallocations of the vector than required, and slow things down in practice. callgrind shows that this saves around 7% of the total instruction count for crypto.js Change-Id: Ibd6114d84ade2b484a5261b53c3299f48f79e633 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Implement DefUses::Temps with a QVarLengthArray.Robin Burchell2015-01-171-5/+2
| | | | | | | | Avoiding heap allocations here shaves 100ms or so off the optimizer runtime. Change-Id: If00c757532ffe90f2fa9c62dc999bb69e25bb71c Task-number: QTBUG-43719 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
* Merge remote-tracking branch 'origin/5.4' into devSimon Hausmann2015-01-161-10/+16
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: .qmake.conf src/qml/jsruntime/qv4context_p.h src/qml/jsruntime/qv4debugging.cpp src/qml/jsruntime/qv4engine.cpp src/qml/jsruntime/qv4functionobject_p.h src/qml/jsruntime/qv4qobjectwrapper.cpp src/quick/scenegraph/shaders/visualization.frag tests/auto/qml/qjsengine/tst_qjsengine.cpp Change-Id: I492e8546c278f80a300a2129e9a29d861e144a30
| * V4: fix reverse type propagationErik Verbruggen2014-12-181-8/+15
| | | | | | | | | | | | | | | | | | Only do integer add/sub/mul when all operands are known to be integers. [ChangeLog][QtQml] Fixed invalidly opportunistic truncating of non-integer values for additions/subtractions/multiplications in JavaScript and binding expressions. Change-Id: I21b3bede2fb3e8033305591110b98cc9e6bf52f8 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
| * V4: only optimize out to-int32 conversions when the operands are int32.Erik Verbruggen2014-12-181-2/+1
| | | | | | | | | | | | | | | | | | The operands of bit-ops are not typed as int32 when no type-inference is done, like for the interpreter. Task-number: QTBUG-43309 Change-Id: I67af18e14ddbc0649530ac23601332ee7d7a1f34 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: move the MemberResolver out of IR::Temp.Erik Verbruggen2015-01-121-12/+15
| | | | | | | | | | | | | | | | | | Temps are copied around a lot. This patch reduces the size by storing a single pointer to the resolver. Change-Id: I074b8b729fce310542cf4697ef42107085b304b3 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
* | QV4: Use QVarLengthArray in cleanupBasicBlocks.Robin Burchell2015-01-101-2/+1
| | | | | | | | | | | | | | | | | | Avoids heap allocations, drops around ~60ms off my morbid testcase in doing so. QBitArray is still allocating, meaning this function isn't "free", but it's now at 0.9% of runtime vs the 1.3% it was before, so something for another day. Change-Id: Ie0db8e0312bde5f67b37250d04b4d65e1f0b034d Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | QV4: Don't heap allocate blockNumbers.Robin Burchell2015-01-091-40/+32
| | | | | | | | | | | | | | | | | | | | | | | | Analysis of the allocations in BasicBlockSet show a huge amount of time spent in allocating and freeing BasicBlockSet, which involves heap allocations. Most of the time, blockNumbers is tiny (at least in my testing) - 0 to 1 in size at deletion time. By inlining the (small) array, we save a nasty penalty. This shaves around 400ms off the optimizer phase of my morbid QML testcase. Change-Id: I46319173b5408a0d7a1b9663fdc516c9e5ca410e Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
* | QV4: Lower time spent in indirections and allocations.Robin Burchell2015-01-071-3/+4
| | | | | | | | | | | | | | | | | | Change data type for defsUntyped from QList -> QVector & reserve space when creating the list. Drops ~250ms off a pretty morbid QML testcase, most, but not all of which was spent in allocations. Change-Id: I2ed8c62e7d41ab353a0194da268a2b430f079474 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | Replace usage of stdout for debug output by qDebugErik Verbruggen2014-12-191-149/+131
|/ | | | | | | | This way even paranoid Androids can be show interesting stuff. Task-number: QTBUG-43109 Change-Id: Ib0ef9e8f6c6fc66e9ea9bfcaf2cd9e33d7469070 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* qv4: assign split of edges to loop header to the correct groupFawzi Mohamed2014-11-051-1/+13
| | | | | | | | | | | | | | | (i.e assign split edges to the correct loop group, now for real) The fix of 25b6fae1eb26645a30b3e7e254ce0b585757351c did try fix QTBUG-41766 and simplify the logic to assign the inserted statement to a loop group. Unfortunately that was incorrect if the target basic block starts a group. In that case if the source was already inside the group we should add it to the target basic block, otherwise to the one containing the target block (as before). There was no visible regression caused by this. Change-Id: Id50c42305fc5ac6aedaffa89d8f8dc3b5e976aa4 Task-number: QTBUG-41766 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* qv4: assign split edges to the correct loop groupFawzi Mohamed2014-11-041-9/+1
| | | | | | | | | | | | | | | | | | | | | edge splitting had a strange logic to assign the inserted statement to a loop, which would go wrong for example for the statement just after the loop header. I guess that was done to increase the likelihood that the goto removed from the final instructions. Given that we are talking about critical edges it is always possible to emit them in a bad order, and I do not think that the old logic was really better than simply always use the loop group of the target which is always correct. It might be worthwhile to ensure that the block it is emitted just before the target block, or improve the handling of empty gotos in the backend, but in this patch we go for the simplest solution. If one would notice worse code, either one of the provious improvements could be done, or the old logic could be kept, changing just the if (container == 0) to container = toBB->containingGroup(); Change-Id: I26a488e9e2cb2b692fa8187ee658fb4dd98bfa8b Task-number: QTBUG-41766 Reviewed-by: Bernd Lamecker <bernd.lamecker@basyskom.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* V4: disable type inference and loop peeling for the interpreter.Erik Verbruggen2014-08-261-18/+27
| | | | | | | | | | Loop peeling is always disabled. Type inference is still enabled for QML code, because of the static-type nature of the properties. This speeds up crypto.js by 20%. Change-Id: Ibf51cb36f8904d64df0793980d463451dfd361e2 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix QML2 hang on gcc 4.6.3 armhfPelle Johnsen2014-08-251-4/+8
| | | | | | | | | | With gcc 4.6.3 armhf (defualt for Ubuntu 12.04) some optimization bug results in QML2 v4 compiler hang during type inference. Task-number: QTBUG-40364 Change-Id: Iea1a8be3b5a7d9410304110d89dae3735339cb72 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
* Update license headers and add new licensesJani Heikkinen2014-08-251-18/+10
| | | | | | | | | - Renamed LICENSE.LGPL to LICENSE.LGPLv21 - Added LICENSE.LGPLv3 & LICENSE.GPLv2 - Removed LICENSE.GPL Change-Id: I84a565e2e0caa3b76bf291a7d188a57a4b00e1b0 Reviewed-by: Jani Heikkinen <jani.heikkinen@digia.com>
* V4 IR: Add loop peeling.Erik Verbruggen2014-08-181-13/+231
| | | | | | | | | | | | By peeling the first iteration off of a loop and putting it in front of the loop, type inference can deduce more type information for esp. loop induction variables. To prevent increasing the code size too much, only the inner-most loops are peeled. This gives a 10% speed-up on crypto.js. Change-Id: I57f9611695bc8defc0bff84e440b8a20b2c8a34e Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
* V4 IR: add immediate dominator re-calculation.Erik Verbruggen2014-08-181-96/+272
| | | | | | | | | When removing edges, the control-flow graph changes, so some immediate dominators might need to be updated. This change collects all candidates and processes them in a single batch. Change-Id: I928f42232427a84bcb9658e314dadd0bd021b12f Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
* V4 IR: change IR printing to be more readable.Erik Verbruggen2014-08-131-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | New structure: - "comments" now start with a semi-colon, and have a list of key: values. ; predecessors: L17 L26 L36, loop_header: yes ; line: 30, column: 3 - when a temporary has a known type, it is written in front of the teporary when it is being assigned, and not repeated. var %109 = this double %42 = 42 - an expression starts with the operation, followed by the operands that are separated by commas. The type of the operands is the type mentioned when they are assigned. int32 %115 = sub %184, %185 if gt %27, 0 goto L40 else goto L41 - conversions do mention the operand type in order to make them easier to read. double %178 = convert var to double %60 - phi node operands are prefixed by the from-label to make it easy to match those operands with the from-block. double %62 = phi L35: %58, L34: %61 - all names except for "this" and built-ins are prefixed by a dot in order to make it clear that a lookup will occur, just like member accesses. $6 = call .int2char($0) %7 = this %8 = %7.toString() Change-Id: I9f626a91f97ca7c3f27e01a5539f3c4fc10a46b4 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* V4 JIT: tune generated instructions for inplace binopsErik Verbruggen2014-08-121-4/+13
| | | | | | | | | | Generate better code for in-place binary operations where the right-hand side is either a constant or a memory address. Now that the JIT can do this, also tell the register allocator not to un-spill that right-hand side. Change-Id: I0ab852f6b92f90dfed99c05fbaf91aad2549ecf4 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* V4 IR: extend BasicBlockSet functionality.Erik Verbruggen2014-08-081-4/+72
| | | | | | | To be used in later patches. Change-Id: I379addaea225482bcbfd7a0b03dbdbaa254dd579 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Make ssa compile on Android with gcc 4.6Laszlo Agocs2014-08-041-14/+15
| | | | | | | | | | | Avoid errors like compiler/qv4ssa.cpp:660:59: error: no matching function for call to 'sort(QVector<QV4::IR::BasicBlock*>::iterator, QVector<QV4::IR::BasicBlock*>::iterator, (anonymous namespace)::DominatorTree::calculateDFNodeIterOrder() const::Cmp)' Change-Id: I4189bd621f1cef5e00b06f5b6b6dd430fefe653f Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
* Merge remote-tracking branch 'origin/5.3' into devSimon Hausmann2014-07-261-15/+26
|\ | | | | | | | | | | | | | | | | Conflicts: src/qml/compiler/qv4ssa.cpp src/qml/jsruntime/qv4arrayobject.cpp src/qml/jsruntime/qv4engine.cpp Change-Id: Ie3ef6202b6a3a8521971e1be10c40c6a2db6989c
| * V4: work around a bug in libc++'s std::vector<bool>Erik Verbruggen2014-07-241-8/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ++operator of std::vector<bool>::iterator in libc++ has a bug when using it on an iterator pointing to the last element. It will not be set to ::end(), but beyond that. (It will be set to the first multiple of the native word size that is bigger than size().) See http://llvm.org/bugs/show_bug.cgi?id=19663 Task-number: QTBUG-39911 Change-Id: Ic244d9c90ee6b596261a6e322301c411a14820a8 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: loop detection: also record loop information separately.Erik Verbruggen2014-07-241-7/+133
| | | | | | | | | | | | | | | | Now loop-specific algorithms can easily query which blocks are loop headers, which blocks make up a loop body, and whether loops are nested. Change-Id: I442af34d3cca816b61ee761335ff3571b72a6d3e Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: change dominator tree to hold on to less memory.Erik Verbruggen2014-07-241-59/+72
| | | | | | | | | | | | | | | | Move all data needed to calculate the immediate dominators into a struct that is freed immediately after finishing this calculation. Change-Id: Id0cefa4088643539d59c4c593cba1848422c1726 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: add IR verification functions.Erik Verbruggen2014-07-241-1/+183
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - CFG verification: check if all edges are correctly registered on both the outgoing basic-block and the incoming one, and that jumps/cjumps targets correspond to outgoing edges. - immediate dominator verification: check if the current immediate dominators are the same as they would be if being recalculated from scratch. - no shared expressions/statements: check if not more than one IR node points to a statement/expression. Also add a function that writes out the CFG as a .dot file for graphviz. Will be used in upcoming patches. Change-Id: I784561f581f9f8ec22f3ab449afd87a9e7a8bdaf Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: change debug code enabling to use compile-time constantsErik Verbruggen2014-07-241-50/+68
| | | | | | | | | | | | | | | | This will make sure that debug code gets compiled/checked, even when it is disabled. An optimized build will remove the code. Change-Id: Ia32de550ea95c44afa5ed84bc17cfeeada06f2f4 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: copy arguments to temps at function start.Erik Verbruggen2014-07-231-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | When arguments cannot "escape" from the current context, and when the arguments array is not used, actual arguments can be treated the same as temporaries instead of memory locations. This has the benefits that they are subject to the same optimizations, and type deduction can assume that the value/type didn't change since its assignment. Another effect is that the values can be kept in registers, and loads from the stack take only 1 indirect load instead of 2 (from the formals array). Change-Id: I209da7991ec5d903b3c5acdbcaf6b1cc67502520 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* | V4 IR: (natural) loop detection.Erik Verbruggen2014-07-041-3/+223
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We perform loop detection to be able to assign to each block its loop, an chain them up from inner loop to outer loop. The new algorithm works on each basic block just once, and looks at a basic block just the number of connections it has. As it relies on the dominator tree it is more robust on actually finding al looping constructs and only those rather than relying on the statements used. It assumes that a basic block is analyzed before the one that dominate it (to guarantee finding outer loop headers before inner loop headers), so blocks are ordered to work on them in a way that guarantees that, using dominator tree depth, that is trivially available. Loop detection allows us to then schedule the loop body before the part after the loop (the header dominates both so just domination cannot choose between both), and can be used to optimize loops (either unrolling the first iteration or hoisting constant parts out of it). It also helps with generated JavaScript code: in order to simulate gotos or other unconditional branches, nested labeled do-while(false) loops are often used in combination with break/continue to "jump" between "loops". Change-Id: Idfcc74589e057b191f74880ffd309d0a9c301811 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
* | V4 JIT: add some documentation and literature references.Erik Verbruggen2014-06-191-0/+2
| | | | | | | | | | Change-Id: I67667b74672b94b951361bf2a446476edf44b826 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* | V4 RegAlloc: change life-time intervals from closed to half-open.Erik Verbruggen2014-06-131-22/+64
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two changes in this patch, that go hand-in-hand. First, when re-numbering the statements in order of occurrence in the scheduled basic-blocks, the (new) position is not stored in the statement itself, but in the LifeTimeIntervals class. This makes it possible to re-use information gathered during SSA formation or optimization. The re-numbering itself has also changed, resulting in some minor changes to the life-time interval calculation. The new numbering is described in LifeTimeIntervals::renumber(). The reason is to make it easy for the register allocator and stack-slot allocator to distinguish between definition of a temporary and its uses. Example: 20: %3 = %2 + %1 22: print(%3) If the life-time of %2 or %1 ends at 20, then at the point that %3 gets assigned, it can re-use the storage occupied by %1 or %2. Also, when both %1 and %2 need to get a register assigned (because they were spilled to the stack, for example), %3 should be allocated "after" both %1 and %2. So, instead of having a closed interval of [20-22] for %3, we want to use an open interval of (20-22]. To simulate the "open" part, the life-time of %3 is set to [21-22]. So, all statements live on even positions, and temporaries defined by a statement start at statmentPosition + 1. Change-Id: I0eda2c653b0edf1a529bd0762d338b0ea9a66aa0 Sanity-Review: Qt Sanity Bot <qt_sanitybot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
* | V4 IR: Store positions for life-time intervals outside the statement.Erik Verbruggen2014-06-061-12/+47
| | | | | | | | | | | | | | | | | | | | | | | | The statement ids are now stable, so the life-time interval calculation can re-use information calculated by the optimizer. This re-use will be done in a separate patch. It also allows for changes to the numbering in a non-intrusive way. This will also come in a later patch. Change-Id: Ie3a2e1d9e3537cc8070ff3e3007f3a5e8ca0579a Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* | V4 IR: add def statements to the worklist when removing uses.Erik Verbruggen2014-06-061-13/+11
| | | | | | | | | | | | | | | | | | | | When removing a phi node, add the def statement for the (previously) used temps to the worklist. These statements might now be eligible for further optimizations (specifically removal when there are no uses left). Change-Id: I05d7c7bc0a243d328b5f9d1c2dcc53a10bd7491d Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>