Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2014 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Jason Ekstrand (jason@jlekstrand.net)
  25.  */
  26.  
  27. #include "nir.h"
  28. #include "nir_worklist.h"
  29. #include "nir_vla.h"
  30.  
  31. /*
  32.  * Basic liveness analysis.  This works only in SSA form.
  33.  *
  34.  * This liveness pass treats phi nodes as being melded to the space between
  35.  * blocks so that the destinations of a phi are in the livein of the block
  36.  * in which it resides and the sources are in the liveout of the
  37.  * corresponding block.  By formulating the liveness information in this
  38.  * way, we ensure that the definition of any variable dominates its entire
  39.  * live range.  This is true because the only way that the definition of an
  40.  * SSA value may not dominate a use is if the use is in a phi node and the
  41.  * uses in phi no are in the live-out of the corresponding predecessor
  42.  * block but not in the live-in of the block containing the phi node.
  43.  */
  44.  
  45. struct live_variables_state {
  46.    unsigned num_ssa_defs;
  47.    unsigned bitset_words;
  48.  
  49.    nir_block_worklist worklist;
  50. };
  51.  
  52. static bool
  53. index_ssa_def(nir_ssa_def *def, void *void_state)
  54. {
  55.    struct live_variables_state *state = void_state;
  56.  
  57.    if (def->parent_instr->type == nir_instr_type_ssa_undef)
  58.       def->live_index = 0;
  59.    else
  60.       def->live_index = state->num_ssa_defs++;
  61.  
  62.    return true;
  63. }
  64.  
  65. static bool
  66. index_ssa_definitions_block(nir_block *block, void *state)
  67. {
  68.    nir_foreach_instr(block, instr)
  69.       nir_foreach_ssa_def(instr, index_ssa_def, state);
  70.  
  71.    return true;
  72. }
  73.  
  74. /* Initialize the liveness data to zero and add the given block to the
  75.  * worklist.
  76.  */
  77. static bool
  78. init_liveness_block(nir_block *block, void *void_state)
  79. {
  80.    struct live_variables_state *state = void_state;
  81.  
  82.    block->live_in = reralloc(block, block->live_in, BITSET_WORD,
  83.                              state->bitset_words);
  84.    memset(block->live_in, 0, state->bitset_words * sizeof(BITSET_WORD));
  85.  
  86.    block->live_out = reralloc(block, block->live_out, BITSET_WORD,
  87.                               state->bitset_words);
  88.    memset(block->live_out, 0, state->bitset_words * sizeof(BITSET_WORD));
  89.  
  90.    nir_block_worklist_push_head(&state->worklist, block);
  91.  
  92.    return true;
  93. }
  94.  
  95. static bool
  96. set_src_live(nir_src *src, void *void_live)
  97. {
  98.    BITSET_WORD *live = void_live;
  99.  
  100.    if (!src->is_ssa)
  101.       return true;
  102.  
  103.    if (src->ssa->live_index == 0)
  104.       return true;   /* undefined variables are never live */
  105.  
  106.    BITSET_SET(live, src->ssa->live_index);
  107.  
  108.    return true;
  109. }
  110.  
  111. static bool
  112. set_ssa_def_dead(nir_ssa_def *def, void *void_live)
  113. {
  114.    BITSET_WORD *live = void_live;
  115.  
  116.    BITSET_CLEAR(live, def->live_index);
  117.  
  118.    return true;
  119. }
  120.  
  121. /** Propagates the live in of succ across the edge to the live out of pred
  122.  *
  123.  * Phi nodes exist "between" blocks and all the phi nodes at the start of a
  124.  * block act "in parallel".  When we propagate from the live_in of one
  125.  * block to the live out of the other, we have to kill any writes from phis
  126.  * and make live any sources.
  127.  *
  128.  * Returns true if updating live out of pred added anything
  129.  */
  130. static bool
  131. propagate_across_edge(nir_block *pred, nir_block *succ,
  132.                       struct live_variables_state *state)
  133. {
  134.    NIR_VLA(BITSET_WORD, live, state->bitset_words);
  135.    memcpy(live, succ->live_in, state->bitset_words * sizeof *live);
  136.  
  137.    nir_foreach_instr(succ, instr) {
  138.       if (instr->type != nir_instr_type_phi)
  139.          break;
  140.       nir_phi_instr *phi = nir_instr_as_phi(instr);
  141.  
  142.       assert(phi->dest.is_ssa);
  143.       set_ssa_def_dead(&phi->dest.ssa, live);
  144.    }
  145.  
  146.    nir_foreach_instr(succ, instr) {
  147.       if (instr->type != nir_instr_type_phi)
  148.          break;
  149.       nir_phi_instr *phi = nir_instr_as_phi(instr);
  150.  
  151.       nir_foreach_phi_src(phi, src) {
  152.          if (src->pred == pred) {
  153.             set_src_live(&src->src, live);
  154.             break;
  155.          }
  156.       }
  157.    }
  158.  
  159.    BITSET_WORD progress = 0;
  160.    for (unsigned i = 0; i < state->bitset_words; ++i) {
  161.       progress |= live[i] & ~pred->live_out[i];
  162.       pred->live_out[i] |= live[i];
  163.    }
  164.    return progress != 0;
  165. }
  166.  
  167. void
  168. nir_live_variables_impl(nir_function_impl *impl)
  169. {
  170.    struct live_variables_state state;
  171.  
  172.    /* We start at 1 because we reserve the index value of 0 for ssa_undef
  173.     * instructions.  Those are never live, so their liveness information
  174.     * can be compacted into a single bit.
  175.     */
  176.    state.num_ssa_defs = 1;
  177.    nir_foreach_block(impl, index_ssa_definitions_block, &state);
  178.  
  179.    nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL);
  180.  
  181.    /* We now know how many unique ssa definitions we have and we can go
  182.     * ahead and allocate live_in and live_out sets and add all of the
  183.     * blocks to the worklist.
  184.     */
  185.    state.bitset_words = BITSET_WORDS(state.num_ssa_defs);
  186.    nir_foreach_block(impl, init_liveness_block, &state);
  187.  
  188.    /* We're now ready to work through the worklist and update the liveness
  189.     * sets of each of the blocks.  By the time we get to this point, every
  190.     * block in the function implementation has been pushed onto the
  191.     * worklist in reverse order.  As long as we keep the worklist
  192.     * up-to-date as we go, everything will get covered.
  193.     */
  194.    while (!nir_block_worklist_is_empty(&state.worklist)) {
  195.       /* We pop them off in the reverse order we pushed them on.  This way
  196.        * the first walk of the instructions is backwards so we only walk
  197.        * once in the case of no control flow.
  198.        */
  199.       nir_block *block = nir_block_worklist_pop_head(&state.worklist);
  200.  
  201.       memcpy(block->live_in, block->live_out,
  202.              state.bitset_words * sizeof(BITSET_WORD));
  203.  
  204.       nir_if *following_if = nir_block_get_following_if(block);
  205.       if (following_if)
  206.          set_src_live(&following_if->condition, block->live_in);
  207.  
  208.       nir_foreach_instr_reverse(block, instr) {
  209.          /* Phi nodes are handled seperately so we want to skip them.  Since
  210.           * we are going backwards and they are at the beginning, we can just
  211.           * break as soon as we see one.
  212.           */
  213.          if (instr->type == nir_instr_type_phi)
  214.             break;
  215.  
  216.          nir_foreach_ssa_def(instr, set_ssa_def_dead, block->live_in);
  217.          nir_foreach_src(instr, set_src_live, block->live_in);
  218.       }
  219.  
  220.       /* Walk over all of the predecessors of the current block updating
  221.        * their live in with the live out of this one.  If anything has
  222.        * changed, add the predecessor to the work list so that we ensure
  223.        * that the new information is used.
  224.        */
  225.       struct set_entry *entry;
  226.       set_foreach(block->predecessors, entry) {
  227.          nir_block *pred = (nir_block *)entry->key;
  228.          if (propagate_across_edge(pred, block, &state))
  229.             nir_block_worklist_push_tail(&state.worklist, pred);
  230.       }
  231.    }
  232.  
  233.    nir_block_worklist_fini(&state.worklist);
  234. }
  235.  
  236. static bool
  237. src_does_not_use_def(nir_src *src, void *def)
  238. {
  239.    return !src->is_ssa || src->ssa != (nir_ssa_def *)def;
  240. }
  241.  
  242. static bool
  243. search_for_use_after_instr(nir_instr *start, nir_ssa_def *def)
  244. {
  245.    /* Only look for a use strictly after the given instruction */
  246.    struct exec_node *node = start->node.next;
  247.    while (!exec_node_is_tail_sentinel(node)) {
  248.       nir_instr *instr = exec_node_data(nir_instr, node, node);
  249.       if (!nir_foreach_src(instr, src_does_not_use_def, def))
  250.          return true;
  251.       node = node->next;
  252.    }
  253.    return false;
  254. }
  255.  
  256. /* Returns true if def is live at instr assuming that def comes before
  257.  * instr in a pre DFS search of the dominance tree.
  258.  */
  259. static bool
  260. nir_ssa_def_is_live_at(nir_ssa_def *def, nir_instr *instr)
  261. {
  262.    if (BITSET_TEST(instr->block->live_out, def->live_index)) {
  263.       /* Since def dominates instr, if def is in the liveout of the block,
  264.        * it's live at instr
  265.        */
  266.       return true;
  267.    } else {
  268.       if (BITSET_TEST(instr->block->live_in, def->live_index) ||
  269.           def->parent_instr->block == instr->block) {
  270.          /* In this case it is either live coming into instr's block or it
  271.           * is defined in the same block.  In this case, we simply need to
  272.           * see if it is used after instr.
  273.           */
  274.          return search_for_use_after_instr(instr, def);
  275.       } else {
  276.          return false;
  277.       }
  278.    }
  279. }
  280.  
  281. bool
  282. nir_ssa_defs_interfere(nir_ssa_def *a, nir_ssa_def *b)
  283. {
  284.    if (a->parent_instr == b->parent_instr) {
  285.       /* Two variables defined at the same time interfere assuming at
  286.        * least one isn't dead.
  287.        */
  288.       return true;
  289.    } else if (a->live_index == 0 || b->live_index == 0) {
  290.       /* If either variable is an ssa_undef, then there's no interference */
  291.       return false;
  292.    } else if (a->live_index < b->live_index) {
  293.       return nir_ssa_def_is_live_at(a, b->parent_instr);
  294.    } else {
  295.       return nir_ssa_def_is_live_at(b, a->parent_instr);
  296.    }
  297. }
  298.