Add a virtual clone() method to ir_instruction.
This will be used by function inlining, the linker, and avoiding double usage of the LHS deref chains in ++, *=, and similar operations.
This commit is contained in:

committed by
Ian Romanick

parent
02fc4b34e4
commit
4b6fd39c89
@@ -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);
|
||||
|
6
ir.cpp
6
ir.cpp
@@ -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;
|
||||
|
73
ir.h
73
ir.h
@@ -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
|
||||
*
|
||||
|
240
ir_clone.cpp
Normal file
240
ir_clone.cpp
Normal file
@@ -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)
|
||||
unsigned int hash_func(const void *key)
|
||||
{
|
||||
ir_variable *new_var = ir->clone();
|
||||
|
||||
this->result = new_var;
|
||||
|
||||
this->remap_variable(ir, new_var);
|
||||
return (unsigned int)(uintptr_t)key;
|
||||
}
|
||||
|
||||
void
|
||||
ir_function_cloning_visitor::visit(ir_loop *ir)
|
||||
int hash_compare_func(const void *key1, const void *key2)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
assert(0);
|
||||
(void) ir;
|
||||
this->result = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ir_function_cloning_visitor::visit(ir_expression *ir)
|
||||
{
|
||||
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);
|
||||
|
Reference in New Issue
Block a user