#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif
-struct ir_program {
- void *bong_hits;
+enum ir_node_type {
+ ir_type_unset,
+ ir_type_variable,
+ ir_type_assignment,
+ ir_type_call,
+ ir_type_constant,
+ ir_type_dereference_array,
+ ir_type_dereference_record,
+ ir_type_dereference_variable,
+ ir_type_discard,
+ ir_type_expression,
+ ir_type_function,
+ ir_type_function_signature,
+ ir_type_if,
+ ir_type_loop,
+ ir_type_loop_jump,
+ ir_type_return,
+ ir_type_swizzle,
+ ir_type_texture,
+ ir_type_max /**< maximum ir_type enum number, for validation */
};
/**
*/
class ir_instruction : public exec_node {
public:
+ enum ir_node_type ir_type;
const struct glsl_type *type;
- class ir_constant *constant_expression_value();
-
/** ir_print_visitor helper for debugging. */
void print(void) const;
virtual void accept(ir_visitor *) = 0;
virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0;
- virtual ir_instruction *clone(struct hash_table *ht) const = 0;
+ virtual ir_instruction *clone(void *mem_ctx,
+ struct hash_table *ht) const = 0;
/**
* \name IR instruction downcast functions
virtual class ir_dereference * as_dereference() { return NULL; }
virtual class ir_dereference_array * as_dereference_array() { return NULL; }
virtual class ir_dereference_variable *as_dereference_variable() { return NULL; }
+ virtual class ir_expression * as_expression() { return NULL; }
virtual class ir_rvalue * as_rvalue() { return NULL; }
virtual class ir_loop * as_loop() { return NULL; }
virtual class ir_assignment * as_assignment() { return NULL; }
protected:
ir_instruction()
{
- /* empty */
+ ir_type = ir_type_unset;
+ type = NULL;
}
};
class ir_rvalue : public ir_instruction {
public:
- virtual ir_rvalue *clone(struct hash_table *) const = 0;
+ virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0;
+
+ virtual ir_constant *constant_expression_value() = 0;
virtual ir_rvalue * as_rvalue()
{
}
protected:
- ir_rvalue()
- {
- /* empty */
- }
+ ir_rvalue();
};
ir_var_uniform,
ir_var_in,
ir_var_out,
- ir_var_inout
+ ir_var_inout,
+ ir_var_temporary /**< Temporary variable generated during compilation. */
};
enum ir_variable_interpolation {
class ir_variable : public ir_instruction {
public:
- ir_variable(const struct glsl_type *, const char *);
+ ir_variable(const struct glsl_type *, const char *, ir_variable_mode);
- virtual ir_variable *clone(struct hash_table *ht) const;
+ virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_variable *as_variable()
{
/**
* Get the string value for the interpolation qualifier
*
- * \return
- * If none of \c shader_in or \c shader_out is set, an empty string will
- * be returned. Otherwise the string that would be used in a shader to
- * specify \c mode will be returned.
+ * \return The string that would be used in a shader to specify \c
+ * mode will be returned.
+ *
+ * This function should only be used on a shader input or output variable.
*/
const char *interpolation_string() const;
unsigned read_only:1;
unsigned centroid:1;
unsigned invariant:1;
- /** If the variable is initialized outside of the scope of the shader */
- unsigned shader_in:1;
- /**
- * If the variable value is later used outside of the scope of the shader.
- */
- unsigned shader_out:1;
unsigned mode:3;
unsigned interpolation:2;
*/
unsigned array_lvalue:1;
+ /* ARB_fragment_coord_conventions */
+ unsigned origin_upper_left:1;
+ unsigned pixel_center_integer:1;
+
/**
* Storage location of the base of this variable
*
public:
ir_function_signature(const glsl_type *return_type);
- virtual ir_function_signature *clone(struct hash_table *ht) const;
+ virtual ir_function_signature *clone(void *mem_ctx,
+ struct hash_table *ht) const;
virtual void accept(ir_visitor *v)
{
*/
const char *function_name() const;
+ /**
+ * Get a handle to the function for which this is a signature
+ *
+ * There is no setter function, this function returns a \c const pointer,
+ * and \c ir_function_signature::_function is private for a reason. The
+ * only way to make a connection between a function and function signature
+ * is via \c ir_function::add_signature. This helps ensure that certain
+ * invariants (i.e., a function signature is in the list of signatures for
+ * its \c _function) are met.
+ *
+ * \sa ir_function::add_signature
+ */
+ inline const class ir_function *function() const
+ {
+ return this->_function;
+ }
+
/**
* Check whether the qualifiers match between this signature's parameters
* and the supplied parameter list. If not, returns the name of the first
private:
/** Function of which this signature is one overload. */
- class ir_function *function;
+ class ir_function *_function;
friend class ir_function;
};
public:
ir_function(const char *name);
- virtual ir_function *clone(struct hash_table *ht) const;
+ virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_function *as_function()
{
void add_signature(ir_function_signature *sig)
{
- sig->function = this;
- signatures.push_tail(sig);
+ sig->_function = this;
+ this->signatures.push_tail(sig);
}
/**
* Find a signature that matches a set of actual parameters, taking implicit
* conversions into account.
*/
- const ir_function_signature *matching_signature(exec_list *actual_param);
+ ir_function_signature *matching_signature(const exec_list *actual_param);
/**
* Find a signature that exactly matches a set of actual parameters without
* any implicit type conversions.
*/
- ir_function_signature *exact_matching_signature(exec_list *actual_ps);
+ ir_function_signature *exact_matching_signature(const exec_list *actual_ps);
/**
* Name of the function.
*/
const char *name;
-private:
+ /** Whether or not this function is a built-in. */
+ unsigned is_builtin:1;
+
/**
* List of ir_function_signature for each overloaded function with this name.
*/
inline const char *ir_function_signature::function_name() const
{
- return function->name;
+ return this->_function->name;
}
/*@}*/
ir_if(ir_rvalue *condition)
: condition(condition)
{
- /* empty */
+ ir_type = ir_type_if;
}
- virtual ir_if *clone(struct hash_table *ht) const;
+ virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const;
virtual ir_if *as_if()
{
public:
ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
{
- /* empty */
+ ir_type = ir_type_loop;
}
- virtual ir_loop *clone(struct hash_table *ht) const;
+ virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const;
virtual void accept(ir_visitor *v)
{
};
-class ir_assignment : public ir_rvalue {
+class ir_assignment : public ir_instruction {
public:
ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
- virtual ir_assignment *clone(struct hash_table *ht) const;
+ /**
+ * Construct an assignment with an explicit write mask
+ *
+ * \note
+ * Since a write mask is supplied, the LHS must already be a bare
+ * \c ir_dereference. The cannot be any swizzles in the LHS.
+ */
+ ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition,
+ unsigned write_mask);
+
+ virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual ir_constant *constant_expression_value();
virtual void accept(ir_visitor *v)
{
return this;
}
+ /**
+ * Get a whole variable written by an assignment
+ *
+ * If the LHS of the assignment writes a whole variable, the variable is
+ * returned. Otherwise \c NULL is returned. Examples of whole-variable
+ * assignment are:
+ *
+ * - Assigning to a scalar
+ * - Assigning to all components of a vector
+ * - Whole array (or matrix) assignment
+ * - Whole structure assignment
+ */
+ ir_variable *whole_variable_written();
+
+ /**
+ * Set the LHS of an assignment
+ */
+ void set_lhs(ir_rvalue *lhs);
+
/**
* Left-hand side of the assignment.
+ *
+ * This should be treated as read only. If you need to set the LHS of an
+ * assignment, use \c ir_assignment::set_lhs.
*/
- ir_rvalue *lhs;
+ ir_dereference *lhs;
/**
* Value being assigned
* Optional condition for the assignment.
*/
ir_rvalue *condition;
+
+
+ /**
+ * Component mask written
+ *
+ * For non-vector types in the LHS, this field will be zero. For vector
+ * types, a bit will be set for each component that is written. Note that
+ * for \c vec2 and \c vec3 types only the lower bits will ever be set.
+ */
+ unsigned write_mask:4;
};
/* Update ir_expression::num_operands() and operator_strs when
ir_unop_rcp,
ir_unop_rsq,
ir_unop_sqrt,
- ir_unop_exp,
- ir_unop_log,
+ ir_unop_exp, /**< Log base e on gentype */
+ ir_unop_log, /**< Natural log on gentype */
ir_unop_exp2,
ir_unop_log2,
ir_unop_f2i, /**< Float-to-integer conversion. */
ir_unop_i2b, /**< int-to-boolean conversion */
ir_unop_b2i, /**< Boolean-to-int conversion */
ir_unop_u2f, /**< Unsigned-to-float conversion. */
+ ir_unop_any,
/**
* \name Unary floating-point rounding operations.
ir_binop_greater,
ir_binop_lequal,
ir_binop_gequal,
+ /**
+ * Returns single boolean for whether all components of operands[0]
+ * equal the components of operands[1].
+ */
ir_binop_equal,
+ /**
+ * Returns single boolean for whether any component of operands[0]
+ * is not equal to the corresponding component of operands[1].
+ */
ir_binop_nequal,
/*@}*/
ir_binop_logic_or,
ir_binop_dot,
+ ir_binop_cross,
ir_binop_min,
ir_binop_max,
ir_expression(int op, const struct glsl_type *type,
ir_rvalue *, ir_rvalue *);
- virtual ir_expression *clone(struct hash_table *ht) const;
+ virtual ir_expression *as_expression()
+ {
+ return this;
+ }
+
+ virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual ir_constant *constant_expression_value();
static unsigned int get_num_operands(ir_expression_operation);
unsigned int get_num_operands() const
*/
class ir_call : public ir_rvalue {
public:
- ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
+ ir_call(ir_function_signature *callee, exec_list *actual_parameters)
: callee(callee)
{
+ ir_type = ir_type_call;
assert(callee->return_type != NULL);
type = callee->return_type;
actual_parameters->move_nodes_to(& this->actual_parameters);
}
- virtual ir_call *clone(struct hash_table *ht) const;
+ virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
+
+ virtual ir_constant *constant_expression_value();
virtual ir_call *as_call()
{
return callee->function_name();
}
- const ir_function_signature *get_callee()
+ ir_function_signature *get_callee()
{
return callee;
}
+ /**
+ * Set the function call target
+ */
+ void set_callee(ir_function_signature *sig);
+
/**
* Generates an inline version of the function before @ir,
* returning the return value of the function.
*/
ir_rvalue *generate_inline(ir_instruction *ir);
+ /* List of ir_rvalue of paramaters passed in this call. */
+ exec_list actual_parameters;
+
private:
ir_call()
: callee(NULL)
{
- /* empty */
+ this->ir_type = ir_type_call;
}
- const ir_function_signature *callee;
-
- /* List of ir_rvalue of paramaters passed in this call. */
- exec_list actual_parameters;
+ ir_function_signature *callee;
};
protected:
ir_jump()
{
- /* empty */
+ ir_type = ir_type_unset;
}
};
ir_return()
: value(NULL)
{
- /* empty */
+ this->ir_type = ir_type_return;
}
ir_return(ir_rvalue *value)
: value(value)
{
- /* empty */
+ this->ir_type = ir_type_return;
}
- virtual ir_return *clone(struct hash_table *) const;
+ virtual ir_return *clone(void *mem_ctx, struct hash_table *) const;
virtual ir_return *as_return()
{
ir_loop_jump(jump_mode mode)
{
+ this->ir_type = ir_type_loop_jump;
this->mode = mode;
this->loop = loop;
}
- virtual ir_loop_jump *clone(struct hash_table *) const;
+ virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const;
virtual void accept(ir_visitor *v)
{
public:
ir_discard()
{
+ this->ir_type = ir_type_discard;
this->condition = NULL;
}
ir_discard(ir_rvalue *cond)
{
+ this->ir_type = ir_type_discard;
this->condition = cond;
}
- virtual ir_discard *clone(struct hash_table *ht) const;
+ virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const;
virtual void accept(ir_visitor *v)
{
ir_texture(enum ir_texture_opcode op)
: op(op), projector(NULL), shadow_comparitor(NULL)
{
- /* empty */
+ this->ir_type = ir_type_texture;
}
- virtual ir_texture *clone(struct hash_table *) const;
+ virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
virtual void accept(ir_visitor *v)
{
ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask);
- virtual ir_swizzle *clone(struct hash_table *) const;
+ virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
virtual ir_swizzle *as_swizzle()
{
class ir_dereference : public ir_rvalue {
public:
- virtual ir_dereference *clone(struct hash_table *) const = 0;
+ virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0;
virtual ir_dereference *as_dereference()
{
public:
ir_dereference_variable(ir_variable *var);
- virtual ir_dereference_variable *clone(struct hash_table *) const;
+ virtual ir_dereference_variable *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
virtual ir_dereference_variable *as_dereference_variable()
{
ir_dereference_array(ir_variable *var, ir_rvalue *array_index);
- virtual ir_dereference_array *clone(struct hash_table *) const;
+ virtual ir_dereference_array *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
virtual ir_dereference_array *as_dereference_array()
{
ir_dereference_record(ir_variable *var, const char *field);
- virtual ir_dereference_record *clone(struct hash_table *) const;
+ virtual ir_dereference_record *clone(void *mem_ctx,
+ struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
/**
* Get the variable that is ultimately referenced by an r-value
*/
ir_constant(const ir_constant *c, unsigned i);
- virtual ir_constant *clone(struct hash_table *) const;
+ /**
+ * Return a new ir_constant of the specified type containing all zeros.
+ */
+ static ir_constant *zero(void *mem_ctx, const glsl_type *type);
+
+ virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
+
+ virtual ir_constant *constant_expression_value();
virtual ir_constant *as_constant()
{
unsigned get_uint_component(unsigned i) const;
/*@}*/
+ ir_constant *get_array_element(unsigned i) const;
+
ir_constant *get_record_field(const char *name);
/**
*/
union ir_constant_data value;
+ /* Array elements */
+ ir_constant **array_elements;
+
+ /* Structure fields */
exec_list components;
private:
void validate_ir_tree(exec_list *instructions);
+/**
+ * Make a clone of each IR instruction in a list
+ *
+ * \param in List of IR instructions that are to be cloned
+ * \param out List to hold the cloned instructions
+ */
+void
+clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in);
+
extern void
_mesa_glsl_initialize_variables(exec_list *instructions,
struct _mesa_glsl_parse_state *state);
_mesa_glsl_initialize_functions(exec_list *instructions,
struct _mesa_glsl_parse_state *state);
+extern void
+_mesa_glsl_release_functions(void);
+
+extern void
+reparent_ir(exec_list *list, void *mem_ctx);
+
+struct glsl_symbol_table;
+
+extern void
+import_prototypes(const exec_list *source, exec_list *dest,
+ struct glsl_symbol_table *symbols, void *mem_ctx);
+
+extern bool
+ir_has_call(ir_instruction *ir);
+
+extern void
+do_set_program_inouts(exec_list *instructions, struct gl_program *prog);
+
#endif /* IR_H */