This will be used by function inlining, the linker, and avoiding double usage of the LHS deref chains in ++, *=, and similar operations.tags/mesa-7.9-rc1
@@ -38,6 +38,7 @@ glsl_SOURCES = \ | |||
ir_print_visitor.cpp ir_variable.cpp ir_function.cpp \ | |||
ir_basic_block.cpp \ | |||
ir_basic_block.h \ | |||
ir_clone.cpp \ | |||
ir_constant_expression.cpp \ | |||
ir_constant_folding.cpp \ | |||
ir_constant_variable.cpp \ |
@@ -2171,8 +2171,7 @@ ast_jump_statement::hir(exec_list *instructions, | |||
if (loop != NULL) { | |||
ir_loop_jump *const jump = | |||
new ir_loop_jump(loop, | |||
(mode == ast_break) | |||
new ir_loop_jump((mode == ast_break) | |||
? ir_loop_jump::jump_break | |||
: ir_loop_jump::jump_continue); | |||
instructions->push_tail(jump); | |||
@@ -2251,7 +2250,7 @@ ast_iteration_statement::condition_to_hir(ir_loop *stmt, | |||
ir_if *const if_stmt = new ir_if(not_cond); | |||
ir_jump *const break_stmt = | |||
new ir_loop_jump(stmt, ir_loop_jump::jump_break); | |||
new ir_loop_jump(ir_loop_jump::jump_break); | |||
if_stmt->then_instructions.push_tail(break_stmt); | |||
stmt->body_instructions.push_tail(if_stmt); |
@@ -297,8 +297,8 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) | |||
} | |||
} | |||
ir_constant * | |||
ir_constant::clone() | |||
ir_instruction * | |||
ir_constant::clone(struct hash_table *ht) const | |||
{ | |||
switch (this->type->base_type) { | |||
case GLSL_TYPE_UINT: | |||
@@ -316,7 +316,7 @@ ir_constant::clone() | |||
; node = node->next) { | |||
ir_constant *const orig = (ir_constant *) node; | |||
c->components.push_tail(orig->clone()); | |||
c->components.push_tail(orig->clone(NULL)); | |||
} | |||
return c; |
@@ -47,10 +47,11 @@ public: | |||
class ir_constant *constant_expression_value(); | |||
/** ir_print_visitor helper for debugging. */ | |||
void print(void); | |||
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; | |||
/** | |||
* \name IR instruction downcast functions | |||
@@ -144,6 +145,8 @@ class ir_variable : public ir_instruction { | |||
public: | |||
ir_variable(const struct glsl_type *, const char *); | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual ir_variable *as_variable() | |||
{ | |||
return this; | |||
@@ -156,26 +159,6 @@ public: | |||
virtual ir_visitor_status accept(ir_hierarchical_visitor *); | |||
/** | |||
* 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; | |||
} | |||
/** | |||
* Get the string value for the interpolation qualifier | |||
@@ -266,6 +249,8 @@ class ir_function_signature : public ir_instruction { | |||
public: | |||
ir_function_signature(const glsl_type *return_type); | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual void accept(ir_visitor *v) | |||
{ | |||
v->visit(this); | |||
@@ -330,6 +315,8 @@ class ir_function : public ir_instruction { | |||
public: | |||
ir_function(const char *name); | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual ir_function *as_function() | |||
{ | |||
return this; | |||
@@ -398,6 +385,8 @@ public: | |||
/* empty */ | |||
} | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual ir_if *as_if() | |||
{ | |||
return this; | |||
@@ -428,6 +417,8 @@ public: | |||
/* empty */ | |||
} | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual void accept(ir_visitor *v) | |||
{ | |||
v->visit(this); | |||
@@ -467,6 +458,8 @@ class ir_assignment : public ir_rvalue { | |||
public: | |||
ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual void accept(ir_visitor *v) | |||
{ | |||
v->visit(this); | |||
@@ -589,8 +582,10 @@ public: | |||
ir_expression(int op, const struct glsl_type *type, | |||
ir_rvalue *, ir_rvalue *); | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
static unsigned int get_num_operands(ir_expression_operation); | |||
unsigned int get_num_operands() | |||
unsigned int get_num_operands() const | |||
{ | |||
return get_num_operands(operation); | |||
} | |||
@@ -612,8 +607,6 @@ public: | |||
virtual ir_visitor_status accept(ir_hierarchical_visitor *); | |||
ir_expression *clone(); | |||
ir_expression_operation operation; | |||
ir_rvalue *operands[2]; | |||
}; | |||
@@ -632,6 +625,8 @@ public: | |||
actual_parameters->move_nodes_to(& this->actual_parameters); | |||
} | |||
virtual ir_instruction *clone(struct hash_table *ht) const; | |||
virtual ir_call *as_call() | |||
{ | |||
return this; | |||
@@ -718,6 +713,8 @@ public: | |||
/* empty */ | |||
} | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual ir_return *as_return() | |||
{ | |||
return this; | |||
@@ -754,12 +751,14 @@ public: | |||
jump_continue | |||
}; | |||
ir_loop_jump(ir_loop *loop, jump_mode mode) | |||
: loop(loop), mode(mode) | |||
ir_loop_jump(jump_mode mode) | |||
: mode(mode) | |||
{ | |||
/* empty */ | |||
} | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual void accept(ir_visitor *v) | |||
{ | |||
v->visit(this); | |||
@@ -778,9 +777,6 @@ public: | |||
} | |||
private: | |||
/** Loop containing this break instruction. */ | |||
ir_loop *loop; | |||
/** Mode selector for the jump instruction. */ | |||
enum jump_mode mode; | |||
}; | |||
@@ -825,6 +821,8 @@ public: | |||
/* empty */ | |||
} | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual void accept(ir_visitor *v) | |||
{ | |||
v->visit(this); | |||
@@ -910,16 +908,13 @@ public: | |||
unsigned count); | |||
ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual ir_swizzle *as_swizzle() | |||
{ | |||
return this; | |||
} | |||
ir_swizzle *clone() | |||
{ | |||
return new ir_swizzle(this->val, this->mask); | |||
} | |||
/** | |||
* Construct an ir_swizzle from the textual representation. Can fail. | |||
*/ | |||
@@ -967,6 +962,8 @@ class ir_dereference_variable : public ir_dereference { | |||
public: | |||
ir_dereference_variable(ir_variable *var); | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
/** | |||
* Get the variable that is ultimately referenced by an r-value | |||
*/ | |||
@@ -1006,6 +1003,8 @@ public: | |||
ir_dereference_array(ir_variable *var, ir_rvalue *array_index); | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual ir_dereference_array *as_dereference_array() | |||
{ | |||
return this; | |||
@@ -1040,6 +1039,8 @@ public: | |||
ir_dereference_record(ir_variable *var, const char *field); | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
/** | |||
* Get the variable that is ultimately referenced by an r-value | |||
*/ | |||
@@ -1096,6 +1097,8 @@ public: | |||
*/ | |||
ir_constant(const ir_constant *c, unsigned i); | |||
virtual ir_instruction *clone(struct hash_table *) const; | |||
virtual ir_constant *as_constant() | |||
{ | |||
return this; | |||
@@ -1108,8 +1111,6 @@ public: | |||
virtual ir_visitor_status accept(ir_hierarchical_visitor *); | |||
ir_constant *clone(); | |||
/** | |||
* Get a particular component of a constant as a specific type | |||
* |
@@ -0,0 +1,240 @@ | |||
/* | |||
* Copyright © 2010 Intel Corporation | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
* and/or sell copies of the Software, and to permit persons to whom the | |||
* Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
* DEALINGS IN THE SOFTWARE. | |||
*/ | |||
#include <string.h> | |||
#include "ir.h" | |||
#include "glsl_types.h" | |||
#include "hash_table.h" | |||
/** | |||
* Duplicate an IR variable | |||
* | |||
* \note | |||
* This will probably be made \c virtual and moved to the base class | |||
* eventually. | |||
*/ | |||
ir_instruction * | |||
ir_variable::clone(struct hash_table *ht) 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; | |||
if (ht) { | |||
hash_table_insert(ht, (void *)const_cast<ir_variable *>(this), var); | |||
} | |||
return var; | |||
} | |||
ir_instruction * | |||
ir_swizzle::clone(struct hash_table *ht) const | |||
{ | |||
return new ir_swizzle((ir_rvalue *)this->val->clone(ht), this->mask); | |||
} | |||
ir_instruction * | |||
ir_return::clone(struct hash_table *ht) const | |||
{ | |||
ir_rvalue *new_value = NULL; | |||
if (this->value) | |||
new_value = (ir_rvalue *)this->value->clone(ht); | |||
return new ir_return(new_value); | |||
} | |||
ir_instruction * | |||
ir_loop_jump::clone(struct hash_table *ht) const | |||
{ | |||
(void)ht; | |||
return new ir_loop_jump(this->mode); | |||
} | |||
ir_instruction * | |||
ir_if::clone(struct hash_table *ht) const | |||
{ | |||
ir_if *new_if = new ir_if((ir_rvalue *)this->condition->clone(ht)); | |||
foreach_iter(exec_list_iterator, iter, this->then_instructions) { | |||
ir_instruction *ir = (ir_instruction *)iter.get(); | |||
new_if->then_instructions.push_tail(ir->clone(ht)); | |||
} | |||
foreach_iter(exec_list_iterator, iter, this->else_instructions) { | |||
ir_instruction *ir = (ir_instruction *)iter.get(); | |||
new_if->else_instructions.push_tail(ir->clone(ht)); | |||
} | |||
return new_if; | |||
} | |||
ir_instruction * | |||
ir_loop::clone(struct hash_table *ht) const | |||
{ | |||
ir_loop *new_loop = new ir_loop(); | |||
if (this->from) | |||
new_loop->from = (ir_rvalue *)this->from->clone(ht); | |||
if (this->to) | |||
new_loop->to = (ir_rvalue *)this->to->clone(ht); | |||
if (this->increment) | |||
new_loop->increment = (ir_rvalue *)this->increment->clone(ht); | |||
new_loop->counter = counter; | |||
foreach_iter(exec_list_iterator, iter, this->body_instructions) { | |||
ir_instruction *ir = (ir_instruction *)iter.get(); | |||
new_loop->body_instructions.push_tail(ir->clone(ht)); | |||
} | |||
return new_loop; | |||
} | |||
ir_instruction * | |||
ir_call::clone(struct hash_table *ht) const | |||
{ | |||
exec_list new_parameters; | |||
foreach_iter(exec_list_iterator, iter, this->actual_parameters) { | |||
ir_instruction *ir = (ir_instruction *)iter.get(); | |||
new_parameters.push_tail(ir->clone(ht)); | |||
} | |||
return new ir_call(this->callee, &new_parameters); | |||
} | |||
ir_instruction * | |||
ir_expression::clone(struct hash_table *ht) const | |||
{ | |||
ir_rvalue *op[2] = {NULL, NULL}; | |||
unsigned int i; | |||
for (i = 0; i < get_num_operands(); i++) { | |||
op[i] = (ir_rvalue *)this->operands[i]->clone(ht); | |||
} | |||
return new ir_expression(this->operation, this->type, op[0], op[1]); | |||
} | |||
ir_instruction * | |||
ir_dereference_variable::clone(struct hash_table *ht) const | |||
{ | |||
ir_variable *new_var; | |||
if (ht) { | |||
new_var = (ir_variable *)hash_table_find(ht, this->var); | |||
if (!new_var) | |||
new_var = this->var; | |||
} else { | |||
new_var = this->var; | |||
} | |||
return new ir_dereference_variable(new_var); | |||
} | |||
ir_instruction * | |||
ir_dereference_array::clone(struct hash_table *ht) const | |||
{ | |||
return new ir_dereference_array((ir_rvalue *)this->array->clone(ht), | |||
(ir_rvalue *)this->array_index->clone(ht)); | |||
} | |||
ir_instruction * | |||
ir_dereference_record::clone(struct hash_table *ht) const | |||
{ | |||
return new ir_dereference_record((ir_rvalue *)this->record->clone(ht), | |||
this->field); | |||
} | |||
ir_instruction * | |||
ir_texture::clone(struct hash_table *ht) const | |||
{ | |||
ir_texture *new_tex = new ir_texture(this->op); | |||
new_tex->sampler = (ir_dereference *)this->sampler->clone(ht); | |||
new_tex->coordinate = (ir_rvalue *)this->coordinate->clone(ht); | |||
if (this->projector) | |||
new_tex->projector = (ir_rvalue *)this->projector->clone(ht); | |||
if (this->shadow_comparitor) { | |||
new_tex->shadow_comparitor = | |||
(ir_rvalue *)this->shadow_comparitor->clone(ht); | |||
} | |||
for (int i = 0; i < 3; i++) | |||
new_tex->offsets[i] = this->offsets[i]; | |||
switch (this->op) { | |||
case ir_tex: | |||
break; | |||
case ir_txb: | |||
new_tex->lod_info.bias = (ir_rvalue *)this->lod_info.bias->clone(ht); | |||
break; | |||
case ir_txl: | |||
case ir_txf: | |||
new_tex->lod_info.lod = (ir_rvalue *)this->lod_info.lod->clone(ht); | |||
break; | |||
case ir_txd: | |||
new_tex->lod_info.grad.dPdx = | |||
(ir_rvalue *)this->lod_info.grad.dPdx->clone(ht); | |||
new_tex->lod_info.grad.dPdy = | |||
(ir_rvalue *)this->lod_info.grad.dPdy->clone(ht); | |||
break; | |||
} | |||
return new_tex; | |||
} | |||
ir_instruction * | |||
ir_assignment::clone(struct hash_table *ht) const | |||
{ | |||
ir_rvalue *new_condition = NULL; | |||
if (this->condition) | |||
new_condition = (ir_rvalue *)this->condition->clone(ht); | |||
return new ir_assignment((ir_rvalue *)this->lhs->clone(ht), | |||
(ir_rvalue *)this->rhs->clone(ht), | |||
new_condition); | |||
} | |||
ir_instruction * | |||
ir_function::clone(struct hash_table *ht) const | |||
{ | |||
(void)ht; | |||
/* FINISHME */ | |||
abort(); | |||
} | |||
ir_instruction * | |||
ir_function_signature::clone(struct hash_table *ht) const | |||
{ | |||
(void)ht; | |||
/* FINISHME */ | |||
abort(); | |||
} |
@@ -546,7 +546,7 @@ ir_constant_visitor::visit(ir_dereference_variable *ir) | |||
ir_variable *var = ir->variable_referenced(); | |||
if (var && var->constant_value) | |||
value = var->constant_value->clone(); | |||
value = (ir_constant *)var->constant_value->clone(NULL); | |||
} | |||
@@ -27,11 +27,13 @@ | |||
* Replaces calls to functions with the body of the function. | |||
*/ | |||
#include <inttypes.h> | |||
#include "ir.h" | |||
#include "ir_visitor.h" | |||
#include "ir_function_inlining.h" | |||
#include "ir_expression_flattening.h" | |||
#include "glsl_types.h" | |||
#include "hash_table.h" | |||
class ir_function_inlining_visitor : public ir_hierarchical_visitor { | |||
public: | |||
@@ -55,283 +57,15 @@ public: | |||
bool progress; | |||
}; | |||
class variable_remap : public exec_node { | |||
public: | |||
variable_remap(const ir_variable *old_var, ir_variable *new_var) | |||
: old_var(old_var), new_var(new_var) | |||
{ | |||
/* empty */ | |||
} | |||
const ir_variable *old_var; | |||
ir_variable *new_var; | |||
}; | |||
class ir_function_cloning_visitor : public ir_visitor { | |||
public: | |||
ir_function_cloning_visitor(ir_variable *retval) | |||
: retval(retval) | |||
{ | |||
/* empty */ | |||
} | |||
virtual ~ir_function_cloning_visitor() | |||
{ | |||
/* empty */ | |||
} | |||
void remap_variable(const ir_variable *old_var, ir_variable *new_var) { | |||
variable_remap *remap = new variable_remap(old_var, new_var); | |||
this->remap_list.push_tail(remap); | |||
} | |||
ir_variable *get_remapped_variable(ir_variable *var) { | |||
foreach_iter(exec_list_iterator, iter, this->remap_list) { | |||
variable_remap *remap = (variable_remap *)iter.get(); | |||
if (var == remap->old_var) | |||
return remap->new_var; | |||
} | |||
/* Not a reapped variable, so a global scoped reference, for example. */ | |||
return var; | |||
} | |||
/* List of variable_remap for mapping from original function body variables | |||
* to inlined function body variables. | |||
*/ | |||
exec_list remap_list; | |||
/* Return value for the inlined function. */ | |||
ir_variable *retval; | |||
/** | |||
* \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_loop *); | |||
virtual void visit(ir_loop_jump *); | |||
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_if *); | |||
/*@}*/ | |||
ir_instruction *result; | |||
}; | |||
void | |||
ir_function_cloning_visitor::visit(ir_variable *ir) | |||
{ | |||
ir_variable *new_var = ir->clone(); | |||
this->result = new_var; | |||
this->remap_variable(ir, new_var); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_loop *ir) | |||
{ | |||
/* FINISHME: Implement loop cloning. */ | |||
assert(0); | |||
(void)ir; | |||
this->result = NULL; | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_loop_jump *ir) | |||
{ | |||
/* FINISHME: Implement loop cloning. */ | |||
assert(0); | |||
(void) ir; | |||
this->result = NULL; | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_function_signature *ir) | |||
{ | |||
assert(0); | |||
(void)ir; | |||
this->result = NULL; | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_function *ir) | |||
unsigned int hash_func(const void *key) | |||
{ | |||
assert(0); | |||
(void) ir; | |||
this->result = NULL; | |||
return (unsigned int)(uintptr_t)key; | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_expression *ir) | |||
int hash_compare_func(const void *key1, const void *key2) | |||
{ | |||
unsigned int operand; | |||
ir_rvalue *op[2] = {NULL, NULL}; | |||
for (operand = 0; operand < ir->get_num_operands(); operand++) { | |||
ir->operands[operand]->accept(this); | |||
op[operand] = this->result->as_rvalue(); | |||
assert(op[operand]); | |||
} | |||
this->result = new ir_expression(ir->operation, ir->type, op[0], op[1]); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_texture *ir) | |||
{ | |||
ir_texture *tex = new ir_texture(ir->op); | |||
ir->sampler->accept(this); | |||
tex->set_sampler(this->result->as_dereference()); | |||
ir->coordinate->accept(this); | |||
tex->coordinate = this->result->as_rvalue(); | |||
if (ir->projector != NULL) { | |||
ir->projector->accept(this); | |||
tex->projector = this->result->as_rvalue(); | |||
} | |||
if (ir->shadow_comparitor != NULL) { | |||
ir->shadow_comparitor->accept(this); | |||
tex->shadow_comparitor = this->result->as_rvalue(); | |||
} | |||
for (int i = 0; i < 3; i++) | |||
tex->offsets[i] = ir->offsets[i]; | |||
tex->lod_info = ir->lod_info; | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_swizzle *ir) | |||
{ | |||
ir->val->accept(this); | |||
this->result = new ir_swizzle(this->result->as_rvalue(), ir->mask); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_dereference_variable *ir) | |||
{ | |||
ir_variable *var = this->get_remapped_variable(ir->variable_referenced()); | |||
this->result = new ir_dereference_variable(var); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_dereference_array *ir) | |||
{ | |||
ir->array->accept(this); | |||
ir_rvalue *var = this->result->as_rvalue(); | |||
ir->array_index->accept(this); | |||
ir_rvalue *index = this->result->as_rvalue(); | |||
this->result = new ir_dereference_array(var, index); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_dereference_record *ir) | |||
{ | |||
ir->record->accept(this); | |||
ir_rvalue *var = this->result->as_rvalue(); | |||
this->result = new ir_dereference_record(var, strdup(ir->field)); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_assignment *ir) | |||
{ | |||
ir_rvalue *lhs, *rhs, *condition = NULL; | |||
ir->lhs->accept(this); | |||
lhs = this->result->as_rvalue(); | |||
ir->rhs->accept(this); | |||
rhs = this->result->as_rvalue(); | |||
if (ir->condition) { | |||
ir->condition->accept(this); | |||
condition = this->result->as_rvalue(); | |||
} | |||
this->result = new ir_assignment(lhs, rhs, condition); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_constant *ir) | |||
{ | |||
this->result = ir->clone(); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_call *ir) | |||
{ | |||
exec_list parameters; | |||
foreach_iter(exec_list_iterator, iter, *ir) { | |||
ir_rvalue *param = (ir_rvalue *)iter.get(); | |||
param->accept(this); | |||
parameters.push_tail(this->result); | |||
} | |||
this->result = new ir_call(ir->get_callee(), ¶meters); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_return *ir) | |||
{ | |||
ir_rvalue *rval; | |||
assert(this->retval); | |||
rval = ir->get_value(); | |||
rval->accept(this); | |||
rval = this->result->as_rvalue(); | |||
assert(rval); | |||
result = new ir_assignment(new ir_dereference_variable(this->retval), rval, | |||
NULL); | |||
} | |||
void | |||
ir_function_cloning_visitor::visit(ir_if *ir) | |||
{ | |||
/* FINISHME: Implement if cloning. */ | |||
assert(0); | |||
(void) ir; | |||
result = NULL; | |||
return key1 == key2 ? 0 : 1; | |||
} | |||
bool | |||
@@ -364,6 +98,9 @@ ir_call::generate_inline(ir_instruction *next_ir) | |||
int num_parameters; | |||
int i; | |||
ir_variable *retval = NULL; | |||
struct hash_table *ht; | |||
ht = hash_table_ctor(0, hash_func, hash_compare_func); | |||
num_parameters = 0; | |||
foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters) | |||
@@ -377,8 +114,6 @@ ir_call::generate_inline(ir_instruction *next_ir) | |||
next_ir->insert_before(retval); | |||
} | |||
ir_function_cloning_visitor v = ir_function_cloning_visitor(retval); | |||
/* Generate the declarations for the parameters to our inlined code, | |||
* and set up the mapping of real function body variables to ours. | |||
*/ | |||
@@ -390,11 +125,9 @@ ir_call::generate_inline(ir_instruction *next_ir) | |||
ir_rvalue *param = (ir_rvalue *) param_iter.get(); | |||
/* Generate a new variable for the parameter. */ | |||
parameters[i] = sig_param->clone(); | |||
parameters[i] = (ir_variable *)sig_param->clone(ht); | |||
next_ir->insert_before(parameters[i]); | |||
v.remap_variable(sig_param, parameters[i]); | |||
/* Move the actual param into our param variable if it's an 'in' type. */ | |||
if (parameters[i]->mode == ir_var_in || | |||
parameters[i]->mode == ir_var_inout) { | |||
@@ -413,9 +146,7 @@ ir_call::generate_inline(ir_instruction *next_ir) | |||
foreach_iter(exec_list_iterator, iter, callee->body) { | |||
ir_instruction *ir = (ir_instruction *)iter.get(); | |||
ir->accept(&v); | |||
assert(v.result); | |||
next_ir->insert_before(v.result); | |||
next_ir->insert_before(ir->clone(ht)); | |||
} | |||
/* Copy back the value of any 'out' parameters from the function body | |||
@@ -442,6 +173,8 @@ ir_call::generate_inline(ir_instruction *next_ir) | |||
delete [] parameters; | |||
hash_table_dtor(ht); | |||
if (retval) | |||
return new ir_dereference_variable(retval); | |||
else |
@@ -28,10 +28,12 @@ | |||
static void print_type(const glsl_type *t); | |||
void | |||
ir_instruction::print(void) | |||
ir_instruction::print(void) const | |||
{ | |||
ir_instruction *deconsted = const_cast<ir_instruction *>(this); | |||
ir_print_visitor v; | |||
accept(&v); | |||
deconsted->accept(&v); | |||
} | |||
void |
@@ -334,9 +334,9 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, | |||
s_symbol *symbol = SX_AS_SYMBOL(expr); | |||
if (symbol != NULL) { | |||
if (strcmp(symbol->value(), "break") == 0 && loop_ctx != NULL) | |||
return new ir_loop_jump(loop_ctx, ir_loop_jump::jump_break); | |||
return new ir_loop_jump(ir_loop_jump::jump_break); | |||
if (strcmp(symbol->value(), "continue") == 0 && loop_ctx != NULL) | |||
return new ir_loop_jump(loop_ctx, ir_loop_jump::jump_continue); | |||
return new ir_loop_jump(ir_loop_jump::jump_continue); | |||
} | |||
s_list *list = SX_AS_LIST(expr); |
@@ -290,7 +290,8 @@ cross_validate_uniforms(struct glsl_program *prog) | |||
* have an initializer but a later instance does, copy the | |||
* initializer to the version stored in the symbol table. | |||
*/ | |||
existing->constant_value = var->constant_value->clone(); | |||
existing->constant_value = | |||
(ir_constant *)var->constant_value->clone(NULL); | |||
} | |||
} else | |||
uniforms.add_variable(var->name, var); |