Perform constant folding on array indices.
[mesa.git] / ir.h
1 /* -*- c++ -*- */
2 /*
3 * Copyright © 2010 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #pragma once
26 #ifndef IR_H
27 #define IR_H
28
29 #include "list.h"
30 #include "ir_visitor.h"
31
32 struct ir_program {
33 void *bong_hits;
34 };
35
36 /**
37 * Base class of all IR instructions
38 */
39 class ir_instruction : public exec_node {
40 public:
41 const struct glsl_type *type;
42
43 class ir_constant *constant_expression_value();
44 virtual void accept(ir_visitor *) = 0;
45
46 /**
47 * \name IR instruction downcast functions
48 *
49 * These functions either cast the object to a derived class or return
50 * \c NULL if the object's type does not match the specified derived class.
51 * Additional downcast functions will be added as needed.
52 */
53 /*@{*/
54 virtual class ir_variable * as_variable() { return NULL; }
55 virtual class ir_dereference * as_dereference() { return NULL; }
56 virtual class ir_rvalue * as_rvalue() { return NULL; }
57 /*@}*/
58
59 protected:
60 ir_instruction()
61 {
62 /* empty */
63 }
64 };
65
66
67 class ir_rvalue : public ir_instruction {
68 public:
69 virtual ir_rvalue * as_rvalue()
70 {
71 return this;
72 }
73
74 virtual bool is_lvalue()
75 {
76 return false;
77 }
78
79 protected:
80 ir_rvalue() : ir_instruction() { }
81 };
82
83
84 enum ir_variable_mode {
85 ir_var_auto = 0,
86 ir_var_uniform,
87 ir_var_in,
88 ir_var_out,
89 ir_var_inout
90 };
91
92 enum ir_varaible_interpolation {
93 ir_var_smooth = 0,
94 ir_var_flat,
95 ir_var_noperspective
96 };
97
98
99 class ir_variable : public ir_instruction {
100 public:
101 ir_variable(const struct glsl_type *, const char *);
102
103 virtual ir_variable *as_variable()
104 {
105 return this;
106 }
107
108 virtual void accept(ir_visitor *v)
109 {
110 v->visit(this);
111 }
112
113 /**
114 * Duplicate an IR variable
115 *
116 * \note
117 * This will probably be made \c virtual and moved to the base class
118 * eventually.
119 */
120 ir_variable *clone() const
121 {
122 ir_variable *var = new ir_variable(type, name);
123
124 var->max_array_access = this->max_array_access;
125 var->read_only = this->read_only;
126 var->centroid = this->centroid;
127 var->invariant = this->invariant;
128 var->mode = this->mode;
129 var->interpolation = this->interpolation;
130
131 return var;
132 }
133
134 const char *name;
135
136 /**
137 * Highest element accessed with a constant expression array index
138 *
139 * Not used for non-array variables.
140 */
141 unsigned max_array_access;
142
143 unsigned read_only:1;
144 unsigned centroid:1;
145 unsigned invariant:1;
146
147 unsigned mode:3;
148 unsigned interpolation:2;
149
150 /**
151 * Flag that the whole array is assignable
152 *
153 * In GLSL 1.20 and later whole arrays are assignable (and comparable for
154 * equality). This flag enables this behavior.
155 */
156 unsigned array_lvalue:1;
157
158 /**
159 * Value assigned in the initializer of a variable declared "const"
160 */
161 ir_constant *constant_value;
162 };
163
164
165 class ir_label : public ir_instruction {
166 public:
167 ir_label(const char *label);
168
169 virtual void accept(ir_visitor *v)
170 {
171 v->visit(this);
172 }
173
174 const char *label;
175 };
176
177
178 /*@{*/
179 class ir_function_signature : public ir_instruction {
180 public:
181 ir_function_signature(const glsl_type *return_type);
182
183 virtual void accept(ir_visitor *v)
184 {
185 v->visit(this);
186 }
187
188 /**
189 * Get the name of the function for which this is a signature
190 */
191 const char *function_name() const;
192
193 /**
194 * Function return type.
195 *
196 * \note This discards the optional precision qualifier.
197 */
198 const struct glsl_type *return_type;
199
200 /**
201 * List of function parameters stored as ir_variable objects.
202 */
203 struct exec_list parameters;
204
205 /**
206 * Pointer to the label that begins the function definition.
207 */
208 ir_label *definition;
209
210 private:
211 /** Function of which this signature is one overload. */
212 class ir_function *function;
213
214 friend class ir_function;
215 };
216
217
218 /**
219 * Header for tracking functions in the symbol table
220 */
221 class ir_function : public ir_instruction {
222 public:
223 ir_function(const char *name);
224
225 virtual void accept(ir_visitor *v)
226 {
227 v->visit(this);
228 }
229
230 void add_signature(ir_function_signature *sig)
231 {
232 sig->function = this;
233 signatures.push_tail(sig);
234 }
235
236 /**
237 * Get an iterator for the set of function signatures
238 */
239 exec_list_iterator iterator()
240 {
241 return signatures.iterator();
242 }
243
244 /**
245 * Find a signature that matches a set of actual parameters.
246 */
247 const ir_function_signature *matching_signature(exec_list *actual_param);
248
249 /**
250 * Name of the function.
251 */
252 const char *name;
253
254 private:
255 /**
256 * Set of overloaded functions with this name.
257 */
258 struct exec_list signatures;
259 };
260
261 inline const char *ir_function_signature::function_name() const
262 {
263 return function->name;
264 }
265 /*@}*/
266
267
268 /**
269 * IR instruction representing high-level if-statements
270 */
271 class ir_if : public ir_instruction {
272 public:
273 ir_if(ir_rvalue *condition)
274 : condition(condition)
275 {
276 /* empty */
277 }
278
279 virtual void accept(ir_visitor *v)
280 {
281 v->visit(this);
282 }
283
284 ir_rvalue *condition;
285 exec_list then_instructions;
286 exec_list else_instructions;
287 };
288
289
290 class ir_assignment : public ir_rvalue {
291 public:
292 ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
293
294 virtual void accept(ir_visitor *v)
295 {
296 v->visit(this);
297 }
298
299 /**
300 * Left-hand side of the assignment.
301 */
302 ir_rvalue *lhs;
303
304 /**
305 * Value being assigned
306 */
307 ir_rvalue *rhs;
308
309 /**
310 * Optional condition for the assignment.
311 */
312 ir_rvalue *condition;
313 };
314
315 /* Update ir_expression::num_operands() and ir_print_visitor.cpp when
316 * updating this list.
317 */
318 enum ir_expression_operation {
319 ir_unop_bit_not,
320 ir_unop_logic_not,
321 ir_unop_neg,
322 ir_unop_abs,
323 ir_unop_rcp,
324 ir_unop_rsq,
325 ir_unop_sqrt,
326 ir_unop_exp,
327 ir_unop_log,
328 ir_unop_exp2,
329 ir_unop_log2,
330 ir_unop_f2i, /**< Float-to-integer conversion. */
331 ir_unop_i2f, /**< Integer-to-float conversion. */
332 ir_unop_f2b, /**< Float-to-boolean conversion */
333 ir_unop_b2f, /**< Boolean-to-float conversion */
334 ir_unop_i2b, /**< int-to-boolean conversion */
335 ir_unop_b2i, /**< Boolean-to-int conversion */
336 ir_unop_u2f, /**< Unsigned-to-float conversion. */
337
338 /**
339 * \name Unary floating-point rounding operations.
340 */
341 /*@{*/
342 ir_unop_trunc,
343 ir_unop_ceil,
344 ir_unop_floor,
345 /*@}*/
346
347 ir_binop_add,
348 ir_binop_sub,
349 ir_binop_mul,
350 ir_binop_div,
351 ir_binop_mod,
352
353 /**
354 * \name Binary comparison operators
355 */
356 /*@{*/
357 ir_binop_less,
358 ir_binop_greater,
359 ir_binop_lequal,
360 ir_binop_gequal,
361 ir_binop_equal,
362 ir_binop_nequal,
363 /*@}*/
364
365 /**
366 * \name Bit-wise binary operations.
367 */
368 /*@{*/
369 ir_binop_lshift,
370 ir_binop_rshift,
371 ir_binop_bit_and,
372 ir_binop_bit_xor,
373 ir_binop_bit_or,
374 /*@}*/
375
376 ir_binop_logic_and,
377 ir_binop_logic_xor,
378 ir_binop_logic_or,
379
380 ir_binop_dot,
381 ir_binop_min,
382 ir_binop_max,
383
384 ir_binop_pow
385 };
386
387 class ir_expression : public ir_rvalue {
388 public:
389 ir_expression(int op, const struct glsl_type *type,
390 ir_rvalue *, ir_rvalue *);
391
392 unsigned int get_num_operands(void);
393
394 virtual void accept(ir_visitor *v)
395 {
396 v->visit(this);
397 }
398
399 ir_expression_operation operation;
400 ir_rvalue *operands[2];
401 };
402
403
404 /**
405 * IR instruction representing a function call
406 */
407 class ir_call : public ir_rvalue {
408 public:
409 ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
410 : ir_rvalue(), callee(callee)
411 {
412 assert(callee->return_type != NULL);
413 type = callee->return_type;
414 actual_parameters->move_nodes_to(& this->actual_parameters);
415 }
416
417 virtual void accept(ir_visitor *v)
418 {
419 v->visit(this);
420 }
421
422 /**
423 * Get a generic ir_call object when an error occurs
424 */
425 static ir_call *get_error_instruction();
426
427 /**
428 * Get an iterator for the set of acutal parameters
429 */
430 exec_list_iterator iterator()
431 {
432 return actual_parameters.iterator();
433 }
434
435 /**
436 * Get the name of the function being called.
437 */
438 const char *callee_name() const
439 {
440 return callee->function_name();
441 }
442
443 private:
444 ir_call()
445 : ir_rvalue(), callee(NULL)
446 {
447 /* empty */
448 }
449
450 const ir_function_signature *callee;
451 exec_list actual_parameters;
452 };
453
454
455 /**
456 * \name Jump-like IR instructions.
457 *
458 * These include \c break, \c continue, \c return, and \c discard.
459 */
460 /*@{*/
461 class ir_jump : public ir_instruction {
462 protected:
463 ir_jump()
464 : ir_instruction()
465 {
466 /* empty */
467 }
468 };
469
470 class ir_return : public ir_jump {
471 public:
472 ir_return()
473 : value(NULL)
474 {
475 /* empty */
476 }
477
478 ir_return(ir_rvalue *value)
479 : value(value)
480 {
481 /* empty */
482 }
483
484 ir_rvalue *get_value() const
485 {
486 return value;
487 }
488
489 virtual void accept(ir_visitor *v)
490 {
491 v->visit(this);
492 }
493
494 private:
495 ir_rvalue *value;
496 };
497 /*@}*/
498
499
500 struct ir_swizzle_mask {
501 unsigned x:2;
502 unsigned y:2;
503 unsigned z:2;
504 unsigned w:2;
505
506 /**
507 * Number of components in the swizzle.
508 */
509 unsigned num_components:3;
510
511 /**
512 * Does the swizzle contain duplicate components?
513 *
514 * L-value swizzles cannot contain duplicate components.
515 */
516 unsigned has_duplicates:1;
517 };
518
519
520 class ir_swizzle : public ir_rvalue {
521 public:
522 ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
523 unsigned count);
524 /**
525 * Construct an ir_swizzle from the textual representation. Can fail.
526 */
527 static ir_swizzle *create(ir_rvalue *, const char *, unsigned vector_length);
528
529 virtual void accept(ir_visitor *v)
530 {
531 v->visit(this);
532 }
533
534 bool is_lvalue()
535 {
536 return val->is_lvalue() && !mask.has_duplicates;
537 }
538
539 ir_rvalue *val;
540 ir_swizzle_mask mask;
541 };
542
543
544 class ir_dereference : public ir_rvalue {
545 public:
546 ir_dereference(struct ir_instruction *);
547
548 ir_dereference(ir_instruction *variable, ir_rvalue *array_index);
549
550 virtual ir_dereference *as_dereference()
551 {
552 return this;
553 }
554
555 virtual void accept(ir_visitor *v)
556 {
557 v->visit(this);
558 }
559
560 bool is_lvalue();
561
562 enum {
563 ir_reference_variable,
564 ir_reference_array,
565 ir_reference_record
566 } mode;
567
568 /**
569 * Object being dereferenced.
570 *
571 * Must be either an \c ir_variable or an \c ir_rvalue.
572 */
573 ir_instruction *var;
574
575 union {
576 ir_rvalue *array_index;
577 const char *field;
578 } selector;
579 };
580
581
582 class ir_constant : public ir_rvalue {
583 public:
584 ir_constant(const struct glsl_type *type, const void *data);
585 ir_constant(bool b);
586 ir_constant(unsigned int u);
587 ir_constant(int i);
588 ir_constant(float f);
589
590 virtual void accept(ir_visitor *v)
591 {
592 v->visit(this);
593 }
594
595 /**
596 * Value of the constant.
597 *
598 * The field used to back the values supplied by the constant is determined
599 * by the type associated with the \c ir_instruction. Constants may be
600 * scalars, vectors, or matrices.
601 */
602 union {
603 unsigned u[16];
604 int i[16];
605 float f[16];
606 bool b[16];
607 } value;
608 };
609
610
611 extern void
612 _mesa_glsl_initialize_variables(exec_list *instructions,
613 struct _mesa_glsl_parse_state *state);
614
615 extern void
616 _mesa_glsl_initialize_functions(exec_list *instructions,
617 struct _mesa_glsl_parse_state *state);
618
619 #endif /* IR_H */