class ir_rvalue : public ir_instruction {
public:
- class ir_constant *constant_expression_value();
-
virtual ir_rvalue *clone(struct hash_table *) const = 0;
+ virtual ir_constant *constant_expression_value() = 0;
+
virtual ir_rvalue * as_rvalue()
{
return this;
virtual ir_assignment *clone(struct hash_table *ht) const;
+ virtual ir_constant *constant_expression_value();
+
virtual void accept(ir_visitor *v)
{
v->visit(this);
virtual ir_expression *clone(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
{
virtual ir_call *clone(struct hash_table *ht) const;
+ virtual ir_constant *constant_expression_value();
+
virtual ir_call *as_call()
{
return this;
virtual ir_texture *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
virtual void accept(ir_visitor *v)
{
v->visit(this);
virtual ir_swizzle *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
virtual ir_swizzle *as_swizzle()
{
return this;
virtual ir_dereference_variable *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
virtual ir_dereference_variable *as_dereference_variable()
{
return this;
virtual ir_dereference_array *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
virtual ir_dereference_array *as_dereference_array()
{
return this;
virtual ir_dereference_record *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
/**
* Get the variable that is ultimately referenced by an r-value
*/
virtual ir_constant *clone(struct hash_table *) const;
+ virtual ir_constant *constant_expression_value();
+
virtual ir_constant *as_constant()
{
return this;
#define min(x,y) (x) < (y) ? (x) : (y)
#define max(x,y) (x) > (y) ? (x) : (y)
-/**
- * Visitor class for evaluating constant expressions
- */
-class ir_constant_visitor : public ir_visitor {
-public:
- ir_constant_visitor()
- : value(NULL)
- {
- /* empty */
- }
-
- virtual ~ir_constant_visitor()
- {
- /* empty */
- }
-
- /**
- * \name Visit methods
- *
- * As typical for the visitor pattern, there must be one \c visit method for
- * each concrete subclass of \c ir_instruction. Virtual base classes within
- * the hierarchy should not have \c visit methods.
- */
- /*@{*/
- virtual void visit(ir_variable *);
- virtual void visit(ir_function_signature *);
- virtual void visit(ir_function *);
- virtual void visit(ir_expression *);
- virtual void visit(ir_texture *);
- virtual void visit(ir_swizzle *);
- virtual void visit(ir_dereference_variable *);
- virtual void visit(ir_dereference_array *);
- virtual void visit(ir_dereference_record *);
- virtual void visit(ir_assignment *);
- virtual void visit(ir_constant *);
- virtual void visit(ir_call *);
- virtual void visit(ir_return *);
- virtual void visit(ir_discard *);
- virtual void visit(ir_if *);
- virtual void visit(ir_loop *);
- virtual void visit(ir_loop_jump *);
- /*@}*/
-
- /**
- * Value of the constant expression.
- *
- * \note
- * This field will be \c NULL if the expression is not constant valued.
- */
- /* FINIHSME: This cannot hold values for constant arrays or structures. */
- ir_constant *value;
-};
-
-
ir_constant *
-ir_rvalue::constant_expression_value()
-{
- ir_constant_visitor visitor;
-
- this->accept(& visitor);
- return visitor.value;
-}
-
-
-void
-ir_constant_visitor::visit(ir_variable *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_function_signature *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_function *ir)
+ir_expression::constant_expression_value()
{
- (void) ir;
- value = NULL;
-}
-
-void
-ir_constant_visitor::visit(ir_expression *ir)
-{
- value = NULL;
+ ir_expression *ir = this;
ir_constant *op[2] = { NULL, NULL };
ir_constant_data data;
for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
op[operand] = ir->operands[operand]->constant_expression_value();
if (!op[operand])
- return;
+ return NULL;
}
if (op[1] != NULL)
default:
/* FINISHME: Should handle all expression types. */
- return;
+ return NULL;
}
void *ctx = talloc_parent(ir);
- this->value = new(ctx) ir_constant(ir->type, &data);
+ return new(ctx) ir_constant(ir->type, &data);
}
-void
-ir_constant_visitor::visit(ir_texture *ir)
+ir_constant *
+ir_texture::constant_expression_value()
{
- // FINISHME: Do stuff with texture lookups
- (void) ir;
- value = NULL;
+ /* texture lookups aren't constant expressions */
+ return NULL;
}
-void
-ir_constant_visitor::visit(ir_swizzle *ir)
+ir_constant *
+ir_swizzle::constant_expression_value()
{
+ ir_swizzle *ir = this;
ir_constant *v = ir->val->constant_expression_value();
- this->value = NULL;
-
if (v != NULL) {
ir_constant_data data;
}
void *ctx = talloc_parent(ir);
- this->value = new(ctx) ir_constant(ir->type, &data);
+ return new(ctx) ir_constant(ir->type, &data);
}
+ return NULL;
}
-void
-ir_constant_visitor::visit(ir_dereference_variable *ir)
+ir_constant *
+ir_dereference_variable::constant_expression_value()
{
- value = NULL;
-
- ir_variable *var = ir->variable_referenced();
+ ir_variable *var = this->variable_referenced();
if (var && var->constant_value)
- value = var->constant_value->clone(NULL);
+ return var->constant_value->clone(NULL);
+ return NULL;
}
-void
-ir_constant_visitor::visit(ir_dereference_array *ir)
+ir_constant *
+ir_dereference_array::constant_expression_value()
{
+ ir_dereference_array *ir = this;
void *ctx = talloc_parent(ir);
ir_constant *array = ir->array->constant_expression_value();
ir_constant *idx = ir->array_index->constant_expression_value();
- this->value = NULL;
-
if ((array != NULL) && (idx != NULL)) {
if (array->type->is_matrix()) {
/* Array access of a matrix results in a vector.
break;
}
- this->value = new(ctx) ir_constant(column_type, &data);
+ return new(ctx) ir_constant(column_type, &data);
} else if (array->type->is_vector()) {
const unsigned component = idx->value.u[0];
- this->value = new(ctx) ir_constant(array, component);
+ return new(ctx) ir_constant(array, component);
} else {
/* FINISHME: Handle access of constant arrays. */
}
}
+ return NULL;
}
-void
-ir_constant_visitor::visit(ir_dereference_record *ir)
+ir_constant *
+ir_dereference_record::constant_expression_value()
{
+ ir_dereference_record *ir = this;
ir_constant *v = ir->record->constant_expression_value();
- this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_assignment *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_constant *ir)
-{
- value = ir;
-}
-
-
-void
-ir_constant_visitor::visit(ir_call *ir)
-{
- (void) ir;
- value = NULL;
-}
-
-
-void
-ir_constant_visitor::visit(ir_return *ir)
-{
- (void) ir;
- value = NULL;
+ return (v != NULL) ? v->get_record_field(ir->field) : NULL;
}
-void
-ir_constant_visitor::visit(ir_discard *ir)
+ir_constant *
+ir_assignment::constant_expression_value()
{
- (void) ir;
- value = NULL;
+ /* FINISHME: Handle CEs involving assignment (return RHS) */
+ return NULL;
}
-void
-ir_constant_visitor::visit(ir_if *ir)
+ir_constant *
+ir_constant::constant_expression_value()
{
- (void) ir;
- value = NULL;
+ return this;
}
-void
-ir_constant_visitor::visit(ir_loop *ir)
+ir_constant *
+ir_call::constant_expression_value()
{
- (void) ir;
- value = NULL;
+ /* FINISHME: Handle CEs involving builtin function calls. */
+ return NULL;
}
-
-void
-ir_constant_visitor::visit(ir_loop_jump *ir)
-{
- (void) ir;
- value = NULL;
-}