1. 05 Nov, 2014 - 1 commit
    • Fawzi Mohamed's avatar
      qv4: assign split of edges to loop header to the correct group · b74268ef
      Fawzi Mohamed authored
      (i.e assign split edges to the correct loop group, now for real)
      The fix of 25b6fae1
      
       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: default avatarSimon Hausmann <simon.hausmann@digia.com>
      b74268ef
  2. 04 Nov, 2014 - 1 commit
    • Fawzi Mohamed's avatar
      qv4: assign split edges to the correct loop group · 25b6fae1
      Fawzi Mohamed authored
      
      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: default avatarBernd Lamecker <bernd.lamecker@basyskom.com>
      Reviewed-by: default avatarSimon Hausmann <simon.hausmann@digia.com>
      25b6fae1
  3. 26 Aug, 2014 - 1 commit
  4. 25 Aug, 2014 - 2 commits
  5. 18 Aug, 2014 - 2 commits
    • Erik Verbruggen's avatar
      V4 IR: Add loop peeling. · 2ae518d3
      Erik Verbruggen authored
      
      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: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
      2ae518d3
    • Erik Verbruggen's avatar
      V4 IR: add immediate dominator re-calculation. · 7e5a589b
      Erik Verbruggen authored
      
      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: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
      7e5a589b
  6. 13 Aug, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: change IR printing to be more readable. · 2fea3d18
      Erik Verbruggen authored
      
      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: default avatarSimon Hausmann <simon.hausmann@digia.com>
      2fea3d18
  7. 12 Aug, 2014 - 1 commit
  8. 08 Aug, 2014 - 1 commit
  9. 04 Aug, 2014 - 1 commit
    • Laszlo Agocs's avatar
      Make ssa compile on Android with gcc 4.6 · a1dd62ce
      Laszlo Agocs authored
      
      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: default avatarErik Verbruggen <erik.verbruggen@digia.com>
      a1dd62ce
  10. 24 Jul, 2014 - 5 commits
  11. 23 Jul, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: copy arguments to temps at function start. · 07bee265
      Erik Verbruggen authored
      
      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: default avatarLars Knoll <lars.knoll@digia.com>
      07bee265
  12. 04 Jul, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: (natural) loop detection. · 48dcabdb
      Erik Verbruggen authored
      
      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: default avatarFawzi Mohamed <fawzi.mohamed@digia.com>
      48dcabdb
  13. 19 Jun, 2014 - 1 commit
  14. 13 Jun, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 RegAlloc: change life-time intervals from closed to half-open. · d74927cf
      Erik Verbruggen authored
      
      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: default avatarLars Knoll <lars.knoll@digia.com>
      d74927cf
  15. 06 Jun, 2014 - 3 commits
  16. 05 Jun, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 RegAlloc: store, pass, and use life-time intervals by pointer. · 788b8bbf
      Erik Verbruggen authored
      
      By storing LifeTimeIntervals by pointer (instead of by value), other
      data-structures can safely use pointers too. This removes a lot of
      copies, especially in vectors that act as worklists.
      
      Also change the order of the "unhandled" list of intervals to be sorted
      in descending order. Not only is this more efficient, but it also
      removes the need to reverse the results of the life-range calculation
      (which produces the list in exactly this order).
      
      This change speeds up register allocation by about 20%.
      
      Change-Id: I6ea3dcd110f250d9ccc881753dc7392510a26d87
      Reviewed-by: default avatarSimon Hausmann <simon.hausmann@digia.com>
      788b8bbf
  17. 03 Jun, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: lower the number of memory allocations. · 481447ae
      Erik Verbruggen authored
      
      By using vectors indexed on temp-id instead of hashes.
      
      Also record the order in which intervals are removed from the list of
      life ranges. This order is the inverse of the list of ranges sorted by
      start position. So instead of building _sortedIntervals and then sorting
      them, reverse iterating over the finished intervals will do the same.
      
      This speeds up the interval calculation by 40%.
      
      Change-Id: If3c78496d7ca2d0e23f0a51302dcd1094dad7d4a
      Reviewed-by: default avatarSimon Hausmann <simon.hausmann@digia.com>
      481447ae
  18. 02 Jun, 2014 - 2 commits
  19. 28 May, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: make statement numbering fixed and clean up statement worklists. · 4a2c3f31
      Erik Verbruggen authored
      
      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: default avatarSimon Hausmann <simon.hausmann@digia.com>
      4a2c3f31
  20. 27 May, 2014 - 1 commit
  21. 26 May, 2014 - 1 commit
  22. 23 May, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4: Split arguments/locals from temps. · 75c22465
      Erik Verbruggen authored
      
      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: default avatarSimon Hausmann <simon.hausmann@digia.com>
      75c22465
  23. 22 May, 2014 - 1 commit
  24. 21 May, 2014 - 1 commit
  25. 15 May, 2014 - 1 commit
    • Erik Verbruggen's avatar
      V4 IR: change BasicBlockSet::const_iterator to use std::find. · 65557f0c
      Erik Verbruggen authored
      
      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: default avatarLars Knoll <lars.knoll@digia.com>
      65557f0c
  26. 30 Apr, 2014 - 1 commit
  27. 29 Apr, 2014 - 1 commit
  28. 23 Apr, 2014 - 1 commit
    • Simon Hausmann's avatar
      Extend the QML bootstrap library by the IR builders · a885d10a
      Simon Hausmann authored
      
      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: default avatarLars Knoll <lars.knoll@digia.com>
      a885d10a
  29. 15 Apr, 2014 - 3 commits