virtual class ir_variable * as_variable() { return NULL; }
virtual class ir_dereference * as_dereference() { 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; }
+ virtual class ir_call * as_call() { return NULL; }
+ virtual class ir_return * as_return() { return NULL; }
/*@}*/
protected:
}
protected:
- ir_rvalue() : ir_instruction() { }
+ ir_rvalue()
+ {
+ /* empty */
+ }
};
v->visit(this);
}
+ /**
+ * Duplicate an IR variable
+ *
+ * \note
+ * This will probably be made \c virtual and moved to the base class
+ * eventually.
+ */
+ ir_variable *clone() const
+ {
+ ir_variable *var = new ir_variable(type, name);
+
+ var->max_array_access = this->max_array_access;
+ var->read_only = this->read_only;
+ var->centroid = this->centroid;
+ var->invariant = this->invariant;
+ var->mode = this->mode;
+ var->interpolation = this->interpolation;
+
+ return var;
+ }
+
const char *name;
+ /**
+ * Highest element accessed with a constant expression array index
+ *
+ * Not used for non-array variables.
+ */
+ unsigned max_array_access;
+
unsigned read_only:1;
unsigned centroid:1;
unsigned invariant:1;
unsigned mode:3;
unsigned interpolation:2;
+
+ /**
+ * Flag that the whole array is assignable
+ *
+ * In GLSL 1.20 and later whole arrays are assignable (and comparable for
+ * equality). This flag enables this behavior.
+ */
+ unsigned array_lvalue:1;
+
+ /**
+ * Emit a warning if this variable is accessed.
+ */
+ const char *warn_extension;
+
+ /**
+ * Value assigned in the initializer of a variable declared "const"
+ */
+ ir_constant *constant_value;
};
class ir_label : public ir_instruction {
public:
- ir_label(const char *label);
+ ir_label(const char *label, ir_function_signature *signature);
virtual void accept(ir_visitor *v)
{
}
const char *label;
+
+ ir_function_signature *signature;
};
/*@{*/
class ir_function_signature : public ir_instruction {
+ /* An ir_function_signature will be part of the list of signatures in
+ * an ir_function.
+ */
public:
ir_function_signature(const glsl_type *return_type);
v->visit(this);
}
+ /**
+ * Get the name of the function for which this is a signature
+ */
+ const char *function_name() const;
+
/**
* Function return type.
*
const struct glsl_type *return_type;
/**
- * List of function parameters stored as ir_variable objects.
+ * List of ir_variable of function parameters.
+ *
+ * This represents the storage. The paramaters passed in a particular
+ * call will be in ir_call::actual_paramaters.
*/
struct exec_list parameters;
*/
ir_label *definition;
+ /** Body of instructions in the function. */
+ struct exec_list body;
+
private:
/** Function of which this signature is one overload. */
class ir_function *function;
private:
/**
- * Set of overloaded functions with this name.
+ * List of ir_function_signature for each overloaded function with this name.
*/
struct exec_list signatures;
};
+
+inline const char *ir_function_signature::function_name() const
+{
+ return function->name;
+}
/*@}*/
}
ir_rvalue *condition;
+ /** List of ir_instruction for the body of the then branch */
exec_list then_instructions;
+ /** List of ir_instruction for the body of the else branch */
exec_list else_instructions;
};
+/**
+ * IR instruction representing a high-level loop structure.
+ */
+class ir_loop : public ir_instruction {
+public:
+ ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL)
+ {
+ /* empty */
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ virtual ir_loop *as_loop()
+ {
+ return this;
+ }
+
+ /**
+ * Get an iterator for the instructions of the loop body
+ */
+ exec_list_iterator iterator()
+ {
+ return body_instructions.iterator();
+ }
+
+ /** List of ir_instruction that make up the body of the loop. */
+ exec_list body_instructions;
+
+ /**
+ * \name Loop counter and controls
+ */
+ /*@{*/
+ ir_rvalue *from;
+ ir_rvalue *to;
+ ir_rvalue *increment;
+ ir_variable *counter;
+ /*@}*/
+};
+
+
class ir_assignment : public ir_rvalue {
public:
ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition);
v->visit(this);
}
+ virtual ir_assignment * as_assignment()
+ {
+ return this;
+ }
+
/**
* Left-hand side of the assignment.
*/
ir_rvalue *condition;
};
-/* Update ir_print_visitor.cpp when updating this list. */
+/* Update ir_expression::num_operands() and ir_print_visitor.cpp when
+ * updating this list.
+*/
enum ir_expression_operation {
ir_unop_bit_not,
ir_unop_logic_not,
ir_unop_log2,
ir_unop_f2i, /**< Float-to-integer conversion. */
ir_unop_i2f, /**< Integer-to-float conversion. */
+ ir_unop_f2b, /**< Float-to-boolean conversion */
+ ir_unop_b2f, /**< Boolean-to-float conversion */
+ ir_unop_i2b, /**< int-to-boolean conversion */
+ ir_unop_b2i, /**< Boolean-to-int conversion */
ir_unop_u2f, /**< Unsigned-to-float conversion. */
/**
ir_binop_logic_and,
ir_binop_logic_xor,
ir_binop_logic_or,
- ir_binop_logic_not,
ir_binop_dot,
ir_binop_min,
ir_expression(int op, const struct glsl_type *type,
ir_rvalue *, ir_rvalue *);
+ unsigned int get_num_operands(void);
+
virtual void accept(ir_visitor *v)
{
v->visit(this);
}
+ ir_expression *clone();
+
ir_expression_operation operation;
ir_rvalue *operands[2];
};
class ir_call : public ir_rvalue {
public:
ir_call(const ir_function_signature *callee, exec_list *actual_parameters)
- : ir_rvalue(), callee(callee)
+ : callee(callee)
{
assert(callee->return_type != NULL);
type = callee->return_type;
actual_parameters->move_nodes_to(& this->actual_parameters);
}
+ virtual ir_call *as_call()
+ {
+ return this;
+ }
+
virtual void accept(ir_visitor *v)
{
v->visit(this);
*/
const char *callee_name() const
{
- /* FINISHME: This only works for functions that have definitions. */
- return callee->definition->label;
+ return callee->function_name();
+ }
+
+ const ir_function_signature *get_callee()
+ {
+ return callee;
}
+ /**
+ * Generates an inline version of the function before @ir,
+ * returning the return value of the function.
+ */
+ ir_rvalue *generate_inline(ir_instruction *ir);
+
private:
ir_call()
- : ir_rvalue(), callee(NULL)
+ : callee(NULL)
{
/* empty */
}
const ir_function_signature *callee;
+
+ /* List of ir_rvalue of paramaters passed in this call. */
exec_list actual_parameters;
};
class ir_jump : public ir_instruction {
protected:
ir_jump()
- : ir_instruction()
{
/* empty */
}
/* empty */
}
+ virtual ir_return *as_return()
+ {
+ return this;
+ }
+
ir_rvalue *get_value() const
{
return value;
private:
ir_rvalue *value;
};
+
+
+/**
+ * Jump instructions used inside loops
+ *
+ * These include \c break and \c continue. The \c break within a loop is
+ * different from the \c break within a switch-statement.
+ *
+ * \sa ir_switch_jump
+ */
+class ir_loop_jump : public ir_jump {
+public:
+ enum jump_mode {
+ jump_break,
+ jump_continue
+ };
+
+ ir_loop_jump(ir_loop *loop, jump_mode mode)
+ : loop(loop), mode(mode)
+ {
+ /* empty */
+ }
+
+ virtual void accept(ir_visitor *v)
+ {
+ v->visit(this);
+ }
+
+ bool is_break() const
+ {
+ return mode == jump_break;
+ }
+
+ bool is_continue() const
+ {
+ return mode == jump_continue;
+ }
+
+private:
+ /** Loop containing this break instruction. */
+ ir_loop *loop;
+
+ /** Mode selector for the jump instruction. */
+ enum jump_mode mode;
+};
/*@}*/
public:
ir_swizzle(ir_rvalue *, unsigned x, unsigned y, unsigned z, unsigned w,
unsigned count);
+ ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
+ : val(val), mask(mask)
+ {
+ /* empty */
+ }
+
+ ir_swizzle *clone()
+ {
+ return new ir_swizzle(this->val, this->mask);
+ }
+
/**
* Construct an ir_swizzle from the textual representation. Can fail.
*/
v->visit(this);
}
- bool is_lvalue()
- {
- if (var == NULL)
- return false;
-
- ir_variable *const as_var = var->as_variable();
- if (as_var == NULL)
- return false;
-
- return !as_var->read_only;
- }
+ bool is_lvalue();
enum {
ir_reference_variable,
v->visit(this);
}
+ ir_constant *clone()
+ {
+ return new ir_constant(this->type, &this->value);
+ }
+
/**
* Value of the constant.
*
} value;
};
+void
+visit_exec_list(exec_list *list, ir_visitor *visitor);
extern void
_mesa_glsl_initialize_variables(exec_list *instructions,