ir_constant_expression: Convert from a visitor to a virtual function.

The constant_expression_wrapper was already the only external API, and
much of the internal code used it anyway.  Also, it wouldn't ever visit
non-rvalue ir_instructions, so using a visitor seemed a bit unnecessary.

This uses "ir_foo *ir = this;" lines to avoid code churn.  These should
be removed.
This commit is contained in:
Kenneth Graunke
2010-07-15 10:09:09 -07:00
committed by Ian Romanick
parent e340854115
commit fb2ffd2846
2 changed files with 60 additions and 169 deletions

View File

@@ -112,10 +112,10 @@ protected:
class ir_rvalue : public ir_instruction { class ir_rvalue : public ir_instruction {
public: public:
class ir_constant *constant_expression_value();
virtual ir_rvalue *clone(struct hash_table *) const = 0; virtual ir_rvalue *clone(struct hash_table *) const = 0;
virtual ir_constant *constant_expression_value() = 0;
virtual ir_rvalue * as_rvalue() virtual ir_rvalue * as_rvalue()
{ {
return this; return this;
@@ -511,6 +511,8 @@ public:
virtual ir_assignment *clone(struct hash_table *ht) const; virtual ir_assignment *clone(struct hash_table *ht) const;
virtual ir_constant *constant_expression_value();
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
v->visit(this); v->visit(this);
@@ -651,6 +653,8 @@ public:
virtual ir_expression *clone(struct hash_table *ht) const; virtual ir_expression *clone(struct hash_table *ht) const;
virtual ir_constant *constant_expression_value();
static unsigned int get_num_operands(ir_expression_operation); static unsigned int get_num_operands(ir_expression_operation);
unsigned int get_num_operands() const unsigned int get_num_operands() const
{ {
@@ -695,6 +699,8 @@ public:
virtual ir_call *clone(struct hash_table *ht) const; virtual ir_call *clone(struct hash_table *ht) const;
virtual ir_constant *constant_expression_value();
virtual ir_call *as_call() virtual ir_call *as_call()
{ {
return this; return this;
@@ -929,6 +935,8 @@ public:
virtual ir_texture *clone(struct hash_table *) const; virtual ir_texture *clone(struct hash_table *) const;
virtual ir_constant *constant_expression_value();
virtual void accept(ir_visitor *v) virtual void accept(ir_visitor *v)
{ {
v->visit(this); v->visit(this);
@@ -1019,6 +1027,8 @@ public:
virtual ir_swizzle *clone(struct hash_table *) const; virtual ir_swizzle *clone(struct hash_table *) const;
virtual ir_constant *constant_expression_value();
virtual ir_swizzle *as_swizzle() virtual ir_swizzle *as_swizzle()
{ {
return this; return this;
@@ -1083,6 +1093,8 @@ public:
virtual ir_dereference_variable *clone(struct hash_table *) const; virtual ir_dereference_variable *clone(struct hash_table *) const;
virtual ir_constant *constant_expression_value();
virtual ir_dereference_variable *as_dereference_variable() virtual ir_dereference_variable *as_dereference_variable()
{ {
return this; return this;
@@ -1129,6 +1141,8 @@ public:
virtual ir_dereference_array *clone(struct hash_table *) const; virtual ir_dereference_array *clone(struct hash_table *) const;
virtual ir_constant *constant_expression_value();
virtual ir_dereference_array *as_dereference_array() virtual ir_dereference_array *as_dereference_array()
{ {
return this; return this;
@@ -1165,6 +1179,8 @@ public:
virtual ir_dereference_record *clone(struct hash_table *) const; 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 * Get the variable that is ultimately referenced by an r-value
*/ */
@@ -1223,6 +1239,8 @@ public:
virtual ir_constant *clone(struct hash_table *) const; virtual ir_constant *clone(struct hash_table *) const;
virtual ir_constant *constant_expression_value();
virtual ir_constant *as_constant() virtual ir_constant *as_constant()
{ {
return this; return this;

View File

@@ -41,97 +41,10 @@
#define min(x,y) (x) < (y) ? (x) : (y) #define min(x,y) (x) < (y) ? (x) : (y)
#define max(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_constant *
ir_rvalue::constant_expression_value() ir_expression::constant_expression_value()
{ {
ir_constant_visitor visitor; ir_expression *ir = this;
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)
{
(void) ir;
value = NULL;
}
void
ir_constant_visitor::visit(ir_expression *ir)
{
value = NULL;
ir_constant *op[2] = { NULL, NULL }; ir_constant *op[2] = { NULL, NULL };
ir_constant_data data; ir_constant_data data;
@@ -140,7 +53,7 @@ ir_constant_visitor::visit(ir_expression *ir)
for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) { for (unsigned operand = 0; operand < ir->get_num_operands(); operand++) {
op[operand] = ir->operands[operand]->constant_expression_value(); op[operand] = ir->operands[operand]->constant_expression_value();
if (!op[operand]) if (!op[operand])
return; return NULL;
} }
if (op[1] != NULL) if (op[1] != NULL)
@@ -735,30 +648,28 @@ ir_constant_visitor::visit(ir_expression *ir)
default: default:
/* FINISHME: Should handle all expression types. */ /* FINISHME: Should handle all expression types. */
return; return NULL;
} }
void *ctx = talloc_parent(ir); 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 *
ir_constant_visitor::visit(ir_texture *ir) ir_texture::constant_expression_value()
{ {
// FINISHME: Do stuff with texture lookups /* texture lookups aren't constant expressions */
(void) ir; return NULL;
value = NULL;
} }
void ir_constant *
ir_constant_visitor::visit(ir_swizzle *ir) ir_swizzle::constant_expression_value()
{ {
ir_swizzle *ir = this;
ir_constant *v = ir->val->constant_expression_value(); ir_constant *v = ir->val->constant_expression_value();
this->value = NULL;
if (v != NULL) { if (v != NULL) {
ir_constant_data data; ir_constant_data data;
@@ -777,31 +688,30 @@ ir_constant_visitor::visit(ir_swizzle *ir)
} }
void *ctx = talloc_parent(ir); 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 *
ir_constant_visitor::visit(ir_dereference_variable *ir) ir_dereference_variable::constant_expression_value()
{ {
value = NULL; ir_variable *var = this->variable_referenced();
ir_variable *var = ir->variable_referenced();
if (var && var->constant_value) if (var && var->constant_value)
value = var->constant_value->clone(NULL); return var->constant_value->clone(NULL);
return NULL;
} }
void ir_constant *
ir_constant_visitor::visit(ir_dereference_array *ir) ir_dereference_array::constant_expression_value()
{ {
ir_dereference_array *ir = this;
void *ctx = talloc_parent(ir); void *ctx = talloc_parent(ir);
ir_constant *array = ir->array->constant_expression_value(); ir_constant *array = ir->array->constant_expression_value();
ir_constant *idx = ir->array_index->constant_expression_value(); ir_constant *idx = ir->array_index->constant_expression_value();
this->value = NULL;
if ((array != NULL) && (idx != NULL)) { if ((array != NULL) && (idx != NULL)) {
if (array->type->is_matrix()) { if (array->type->is_matrix()) {
/* Array access of a matrix results in a vector. /* Array access of a matrix results in a vector.
@@ -836,85 +746,48 @@ ir_constant_visitor::visit(ir_dereference_array *ir)
break; break;
} }
this->value = new(ctx) ir_constant(column_type, &data); return new(ctx) ir_constant(column_type, &data);
} else if (array->type->is_vector()) { } else if (array->type->is_vector()) {
const unsigned component = idx->value.u[0]; const unsigned component = idx->value.u[0];
this->value = new(ctx) ir_constant(array, component); return new(ctx) ir_constant(array, component);
} else { } else {
/* FINISHME: Handle access of constant arrays. */ /* FINISHME: Handle access of constant arrays. */
} }
} }
return NULL;
} }
void ir_constant *
ir_constant_visitor::visit(ir_dereference_record *ir) ir_dereference_record::constant_expression_value()
{ {
ir_dereference_record *ir = this;
ir_constant *v = ir->record->constant_expression_value(); ir_constant *v = ir->record->constant_expression_value();
this->value = (v != NULL) ? v->get_record_field(ir->field) : NULL; return (v != NULL) ? v->get_record_field(ir->field) : NULL;
} }
void ir_constant *
ir_constant_visitor::visit(ir_assignment *ir) ir_assignment::constant_expression_value()
{ {
(void) ir; /* FINISHME: Handle CEs involving assignment (return RHS) */
value = NULL; return NULL;
} }
void ir_constant *
ir_constant_visitor::visit(ir_constant *ir) ir_constant::constant_expression_value()
{ {
value = ir; return this;
} }
void ir_constant *
ir_constant_visitor::visit(ir_call *ir) ir_call::constant_expression_value()
{ {
(void) ir; /* FINISHME: Handle CEs involving builtin function calls. */
value = NULL; return NULL;
} }
void
ir_constant_visitor::visit(ir_return *ir)
{
(void) ir;
value = NULL;
}
void
ir_constant_visitor::visit(ir_discard *ir)
{
(void) ir;
value = NULL;
}
void
ir_constant_visitor::visit(ir_if *ir)
{
(void) ir;
value = NULL;
}
void
ir_constant_visitor::visit(ir_loop *ir)
{
(void) ir;
value = NULL;
}
void
ir_constant_visitor::visit(ir_loop_jump *ir)
{
(void) ir;
value = NULL;
}