1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2016 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg/**
25b8e80941Smrg * \file ir_array_refcount.h
26b8e80941Smrg *
27b8e80941Smrg * Provides a visitor which produces a list of variables referenced.
28b8e80941Smrg */
29b8e80941Smrg
30b8e80941Smrg#ifndef GLSL_IR_ARRAY_REFCOUNT_H
31b8e80941Smrg#define GLSL_IR_ARRAY_REFCOUNT_H
32b8e80941Smrg
33b8e80941Smrg#include "ir.h"
34b8e80941Smrg#include "ir_visitor.h"
35b8e80941Smrg#include "compiler/glsl_types.h"
36b8e80941Smrg#include "util/bitset.h"
37b8e80941Smrg
38b8e80941Smrg/**
39b8e80941Smrg * Describes an access of an array element or an access of the whole array
40b8e80941Smrg */
41b8e80941Smrgstruct array_deref_range {
42b8e80941Smrg   /**
43b8e80941Smrg    * Index that was accessed.
44b8e80941Smrg    *
45b8e80941Smrg    * All valid array indices are less than the size of the array.  If index
46b8e80941Smrg    * is equal to the size of the array, this means the entire array has been
47b8e80941Smrg    * accessed (e.g., due to use of a non-constant index).
48b8e80941Smrg    */
49b8e80941Smrg   unsigned index;
50b8e80941Smrg
51b8e80941Smrg   /** Size of the array.  Used for offset calculations. */
52b8e80941Smrg   unsigned size;
53b8e80941Smrg};
54b8e80941Smrg
55b8e80941Smrgclass ir_array_refcount_entry
56b8e80941Smrg{
57b8e80941Smrgpublic:
58b8e80941Smrg   ir_array_refcount_entry(ir_variable *var);
59b8e80941Smrg   ~ir_array_refcount_entry();
60b8e80941Smrg
61b8e80941Smrg   ir_variable *var; /* The key: the variable's pointer. */
62b8e80941Smrg
63b8e80941Smrg   /** Has the variable been referenced? */
64b8e80941Smrg   bool is_referenced;
65b8e80941Smrg
66b8e80941Smrg   /**
67b8e80941Smrg    * Mark a set of array elements as accessed.
68b8e80941Smrg    *
69b8e80941Smrg    * If every \c array_deref_range is for a single index, only a single
70b8e80941Smrg    * element will be marked.  If any \c array_deref_range is for an entire
71b8e80941Smrg    * array-of-, then multiple elements will be marked.
72b8e80941Smrg    *
73b8e80941Smrg    * Items in the \c array_deref_range list appear in least- to
74b8e80941Smrg    * most-significant order.  This is the \b opposite order the indices
75b8e80941Smrg    * appear in the GLSL shader text.  An array access like
76b8e80941Smrg    *
77b8e80941Smrg    *     x = y[1][i][3];
78b8e80941Smrg    *
79b8e80941Smrg    * would appear as
80b8e80941Smrg    *
81b8e80941Smrg    *     { { 3, n }, { m, m }, { 1, p } }
82b8e80941Smrg    *
83b8e80941Smrg    * where n, m, and p are the sizes of the arrays-of-arrays.
84b8e80941Smrg    *
85b8e80941Smrg    * The set of marked array elements can later be queried by
86b8e80941Smrg    * \c ::is_linearized_index_referenced.
87b8e80941Smrg    *
88b8e80941Smrg    * \param dr     List of array_deref_range elements to be processed.
89b8e80941Smrg    * \param count  Number of array_deref_range elements to be processed.
90b8e80941Smrg    */
91b8e80941Smrg   void mark_array_elements_referenced(const array_deref_range *dr,
92b8e80941Smrg                                       unsigned count);
93b8e80941Smrg
94b8e80941Smrg   /** Has a linearized array index been referenced? */
95b8e80941Smrg   bool is_linearized_index_referenced(unsigned linearized_index) const
96b8e80941Smrg   {
97b8e80941Smrg      assert(bits != 0);
98b8e80941Smrg      assert(linearized_index <= num_bits);
99b8e80941Smrg
100b8e80941Smrg      return BITSET_TEST(bits, linearized_index);
101b8e80941Smrg   }
102b8e80941Smrg
103b8e80941Smrgprivate:
104b8e80941Smrg   /** Set of bit-flags to note which array elements have been accessed. */
105b8e80941Smrg   BITSET_WORD *bits;
106b8e80941Smrg
107b8e80941Smrg   /**
108b8e80941Smrg    * Total number of bits referenced by \c bits.
109b8e80941Smrg    *
110b8e80941Smrg    * Also the total number of array(s-of-arrays) elements of \c var.
111b8e80941Smrg    */
112b8e80941Smrg   unsigned num_bits;
113b8e80941Smrg
114b8e80941Smrg   /** Count of nested arrays in the type. */
115b8e80941Smrg   unsigned array_depth;
116b8e80941Smrg
117b8e80941Smrg   /**
118b8e80941Smrg    * Recursive part of the public mark_array_elements_referenced method.
119b8e80941Smrg    *
120b8e80941Smrg    * The recursion occurs when an entire array-of- is accessed.  See the
121b8e80941Smrg    * implementation for more details.
122b8e80941Smrg    *
123b8e80941Smrg    * \param dr                List of array_deref_range elements to be
124b8e80941Smrg    *                          processed.
125b8e80941Smrg    * \param count             Number of array_deref_range elements to be
126b8e80941Smrg    *                          processed.
127b8e80941Smrg    * \param scale             Current offset scale.
128b8e80941Smrg    * \param linearized_index  Current accumulated linearized array index.
129b8e80941Smrg    */
130b8e80941Smrg   void mark_array_elements_referenced(const array_deref_range *dr,
131b8e80941Smrg                                       unsigned count,
132b8e80941Smrg                                       unsigned scale,
133b8e80941Smrg                                       unsigned linearized_index);
134b8e80941Smrg
135b8e80941Smrg   friend class array_refcount_test;
136b8e80941Smrg};
137b8e80941Smrg
138b8e80941Smrgclass ir_array_refcount_visitor : public ir_hierarchical_visitor {
139b8e80941Smrgpublic:
140b8e80941Smrg   ir_array_refcount_visitor(void);
141b8e80941Smrg   ~ir_array_refcount_visitor(void);
142b8e80941Smrg
143b8e80941Smrg   virtual ir_visitor_status visit(ir_dereference_variable *);
144b8e80941Smrg
145b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_function_signature *);
146b8e80941Smrg   virtual ir_visitor_status visit_enter(ir_dereference_array *);
147b8e80941Smrg
148b8e80941Smrg   /**
149b8e80941Smrg    * Find variable in the hash table, and insert it if not present
150b8e80941Smrg    */
151b8e80941Smrg   ir_array_refcount_entry *get_variable_entry(ir_variable *var);
152b8e80941Smrg
153b8e80941Smrg   /**
154b8e80941Smrg    * Hash table mapping ir_variable to ir_array_refcount_entry.
155b8e80941Smrg    */
156b8e80941Smrg   struct hash_table *ht;
157b8e80941Smrg
158b8e80941Smrg   void *mem_ctx;
159b8e80941Smrg
160b8e80941Smrgprivate:
161b8e80941Smrg   /** Get an array_deref_range element from private tracking. */
162b8e80941Smrg   array_deref_range *get_array_deref();
163b8e80941Smrg
164b8e80941Smrg   /**
165b8e80941Smrg    * Last ir_dereference_array that was visited
166b8e80941Smrg    *
167b8e80941Smrg    * Used to prevent some redundant calculations.
168b8e80941Smrg    *
169b8e80941Smrg    * \sa ::visit_enter(ir_dereference_array *)
170b8e80941Smrg    */
171b8e80941Smrg   ir_dereference_array *last_array_deref;
172b8e80941Smrg
173b8e80941Smrg   /**
174b8e80941Smrg    * \name array_deref_range tracking
175b8e80941Smrg    */
176b8e80941Smrg   /*@{*/
177b8e80941Smrg   /** Currently allocated block of derefs. */
178b8e80941Smrg   array_deref_range *derefs;
179b8e80941Smrg
180b8e80941Smrg   /** Number of derefs used in current processing. */
181b8e80941Smrg   unsigned num_derefs;
182b8e80941Smrg
183b8e80941Smrg   /** Size of the derefs buffer in bytes. */
184b8e80941Smrg   unsigned derefs_size;
185b8e80941Smrg   /*@}*/
186b8e80941Smrg};
187b8e80941Smrg
188b8e80941Smrg#endif /* GLSL_IR_ARRAY_REFCOUNT_H */
189