1 /*
2  * Copyright © 2012 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  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27 
28 #include "util/bitset.h"
29 #include "brw_vec4.h"
30 
31 namespace brw {
32 
33 struct block_data {
34    /**
35     * Which variables are defined before being used in the block.
36     *
37     * Note that for our purposes, "defined" means unconditionally, completely
38     * defined.
39     */
40    BITSET_WORD *def;
41 
42    /**
43     * Which variables are used before being defined in the block.
44     */
45    BITSET_WORD *use;
46 
47    /** Which defs reach the entry point of the block. */
48    BITSET_WORD *livein;
49 
50    /** Which defs reach the exit point of the block. */
51    BITSET_WORD *liveout;
52 
53    BITSET_WORD flag_def[1];
54    BITSET_WORD flag_use[1];
55    BITSET_WORD flag_livein[1];
56    BITSET_WORD flag_liveout[1];
57 };
58 
59 class vec4_live_variables {
60 public:
61    DECLARE_RALLOC_CXX_OPERATORS(vec4_live_variables)
62 
63    vec4_live_variables(const simple_allocator &alloc, cfg_t *cfg);
64    ~vec4_live_variables();
65 
66    int num_vars;
67    int bitset_words;
68 
69    /** Per-basic-block information on live variables */
70    struct block_data *block_data;
71 
72 protected:
73    void setup_def_use();
74    void compute_live_variables();
75 
76    const simple_allocator &alloc;
77    cfg_t *cfg;
78    void *mem_ctx;
79 };
80 
81 /* Returns the variable index for the k-th dword of the c-th component of
82  * register reg.
83  */
84 inline unsigned
85 var_from_reg(const simple_allocator &alloc, const src_reg &reg,
86              unsigned c = 0, unsigned k = 0)
87 {
88    assert(reg.file == VGRF && reg.nr < alloc.count && c < 4);
89    const unsigned csize = DIV_ROUND_UP(type_sz(reg.type), 4);
90    unsigned result =
91       8 * (alloc.offsets[reg.nr] + reg.offset / REG_SIZE) +
92       (BRW_GET_SWZ(reg.swizzle, c) + k / csize * 4) * csize + k % csize;
93    /* Do not exceed the limit for this register */
94    assert(result < 8 * (alloc.offsets[reg.nr] + alloc.sizes[reg.nr]));
95    return result;
96 }
97 
98 inline unsigned
99 var_from_reg(const simple_allocator &alloc, const dst_reg &reg,
100              unsigned c = 0, unsigned k = 0)
101 {
102    assert(reg.file == VGRF && reg.nr < alloc.count && c < 4);
103    const unsigned csize = DIV_ROUND_UP(type_sz(reg.type), 4);
104    unsigned result =
105       8 * (alloc.offsets[reg.nr] + reg.offset / REG_SIZE) +
106       (c + k / csize * 4) * csize + k % csize;
107    /* Do not exceed the limit for this register */
108    assert(result < 8 * (alloc.offsets[reg.nr] + alloc.sizes[reg.nr]));
109    return result;
110 }
111 
112 } /* namespace brw */
113