[Mesa-dev] [PATCH 1/3] glsl_to_tgsi: Create a new variable_store class replacing variables field in glsl_to_tgsi_visitor

2012-01-07 Thread Vincent Lejeune
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  414 +---
 1 files changed, 309 insertions(+), 105 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index cecceca..17ae525 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -230,14 +230,16 @@ public:
 class variable_storage : public exec_node {
 public:
variable_storage(ir_variable *var, gl_register_file file, int index)
-  : file(file), index(index), var(var)
+  : file(file), index(index), type(var-type), 
is_array(var-type-is_array() || var-type-is_record() || 
var-type-is_matrix()), is_reladdressed(false)
{
   /* empty */
}
 
gl_register_file file;
int index;
-   ir_variable *var; /* variable that maps to this, if any */
+   const glsl_type *type; /* variable that maps to this, if any */
+   bool is_array;
+   bool is_reladdressed;
 };
 
 class immediate_storage : public exec_node {
@@ -286,6 +288,242 @@ public:
st_src_reg return_reg;
 };
 
+static int type_size(const glsl_type *type);
+static int swizzle_for_size(int size);
+
+
+/**
+ * Single place to store all temporary values (either explicit - ir_variable* -
+ * or implicit - returned by get_temp -).
+ *
+ * Explicit temps are stored in variables hash_table.
+ * Implicit temps are stored in rvalue_regs array.
+ */
+class variable_store {
+   friend class glsl_to_tgsi_variable_allocator;
+protected:
+   void *mem_ctx;
+   hash_table* variables;
+   unsigned next_temp;
+   unsigned next_temp_array;
+   static void reindex_reladdress(const void *, void *, void *);
+   static void reindex_non_reladdress(const void *, void *, void *);
+   void reindex_rvalue();
+   void reindex_rvalue_reladdressed();
+   variable_storage* rvalue_regs;
+   unsigned rvalue_regs_count;
+
+public:
+   bool native_integers;
+   unsigned temp_amount() const;
+   unsigned temp_array_amount() const;
+   variable_store();
+   ~variable_store();
+   variable_storage *find_variable_storage(class ir_variable *var) const;
+   variable_storage *push(class ir_variable *, gl_register_file, int);
+   variable_storage *push(class ir_variable *);
+   variable_storage *retrieve_anonymous_temp(unsigned);
+   st_src_reg get_temp(const glsl_type *type);
+   void optimise_access(void);
+   unsigned *reindex_table;
+};
+
+unsigned
+variable_store::temp_amount() const
+{
+   return next_temp;
+}
+
+unsigned
+variable_store::temp_array_amount() const
+{
+   return next_temp_array;
+}
+
+variable_store::variable_store():mem_ctx(ralloc_context(NULL)),next_temp(1),next_temp_array(1),rvalue_regs(NULL),rvalue_regs_count(0)
+{
+   variables = 
hash_table_ctor(0,hash_table_pointer_hash,hash_table_pointer_compare);
+}
+
+variable_store::~variable_store()
+{
+   hash_table_dtor(variables);
+   ralloc_free(mem_ctx);
+}
+
+variable_storage *
+variable_store::find_variable_storage(ir_variable *var) const
+{
+   return (class variable_storage *) hash_table_find(variables,var);
+}
+
+variable_storage*
+variable_store::push(class ir_variable *var, gl_register_file file, int index)
+{
+   variable_storage *storage = new (mem_ctx) variable_storage(var,file,index);
+   hash_table_insert(variables,storage,var);
+   return storage;
+}
+
+variable_storage*
+variable_store::push(ir_variable *ir)
+{
+   variable_storage* retval = push(ir, PROGRAM_TEMPORARY, next_temp);
+   next_temp += type_size(ir-type);
+   if (ir-type-is_array() || ir-type-is_record() || ir-type-is_matrix()) 
{
+  retval-is_array = true;
+   }
+   return retval;
+}
+
+variable_storage*
+variable_store::retrieve_anonymous_temp(unsigned reg)
+{
+   for (unsigned i = 0; i  rvalue_regs_count; i++) {
+  unsigned range_start = rvalue_regs[i].index;
+  unsigned range_end = range_start + type_size(rvalue_regs[i].type) - 1;
+  if (reg = range_start  reg = range_end) {
+ return rvalue_regs + i;
+ }
+   }
+   printf (Failed to get storage);
+   exit(1);
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results.  (not SSA -- variable assignments will reuse
+ * storage).
+ */
+st_src_reg
+variable_store::get_temp(const glsl_type *type)
+{
+   st_src_reg src;
+   rvalue_regs_count++;
+   rvalue_regs = 
reralloc(mem_ctx,rvalue_regs,variable_storage,rvalue_regs_count);
+   variable_storage entry = rvalue_regs[rvalue_regs_count - 1];
+
+   src.type = native_integers ? type-base_type : GLSL_TYPE_FLOAT;
+   src.file = PROGRAM_TEMPORARY;
+   src.index = next_temp;
+   src.reladdr = NULL;
+   next_temp += type_size(type);
+
+   entry.file = PROGRAM_TEMPORARY;
+   entry.index = src.index;
+   entry.type = type;
+   entry.is_reladdressed = false;
+
+   if (type-is_array() || type-is_record() || type-is_matrix()) {
+  entry.is_array = true;
+   }
+
+   if (type-is_array() || type-is_record()) {
+  src.swizzle = SWIZZLE_NOOP;
+   } else {
+  src.swizzle = 

[Mesa-dev] [PATCH 1/3] glsl_to_tgsi: Create a new variable_store class replacing variables field in glsl_to_tgsi_visitor

2012-01-07 Thread Vincent Lejeune
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  414 +---
 1 files changed, 309 insertions(+), 105 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index cecceca..17ae525 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -230,14 +230,16 @@ public:
 class variable_storage : public exec_node {
 public:
variable_storage(ir_variable *var, gl_register_file file, int index)
-  : file(file), index(index), var(var)
+  : file(file), index(index), type(var-type), 
is_array(var-type-is_array() || var-type-is_record() || 
var-type-is_matrix()), is_reladdressed(false)
{
   /* empty */
}
 
gl_register_file file;
int index;
-   ir_variable *var; /* variable that maps to this, if any */
+   const glsl_type *type; /* variable that maps to this, if any */
+   bool is_array;
+   bool is_reladdressed;
 };
 
 class immediate_storage : public exec_node {
@@ -286,6 +288,242 @@ public:
st_src_reg return_reg;
 };
 
+static int type_size(const glsl_type *type);
+static int swizzle_for_size(int size);
+
+
+/**
+ * Single place to store all temporary values (either explicit - ir_variable* -
+ * or implicit - returned by get_temp -).
+ *
+ * Explicit temps are stored in variables hash_table.
+ * Implicit temps are stored in rvalue_regs array.
+ */
+class variable_store {
+   friend class glsl_to_tgsi_variable_allocator;
+protected:
+   void *mem_ctx;
+   hash_table* variables;
+   unsigned next_temp;
+   unsigned next_temp_array;
+   static void reindex_reladdress(const void *, void *, void *);
+   static void reindex_non_reladdress(const void *, void *, void *);
+   void reindex_rvalue();
+   void reindex_rvalue_reladdressed();
+   variable_storage* rvalue_regs;
+   unsigned rvalue_regs_count;
+
+public:
+   bool native_integers;
+   unsigned temp_amount() const;
+   unsigned temp_array_amount() const;
+   variable_store();
+   ~variable_store();
+   variable_storage *find_variable_storage(class ir_variable *var) const;
+   variable_storage *push(class ir_variable *, gl_register_file, int);
+   variable_storage *push(class ir_variable *);
+   variable_storage *retrieve_anonymous_temp(unsigned);
+   st_src_reg get_temp(const glsl_type *type);
+   void optimise_access(void);
+   unsigned *reindex_table;
+};
+
+unsigned
+variable_store::temp_amount() const
+{
+   return next_temp;
+}
+
+unsigned
+variable_store::temp_array_amount() const
+{
+   return next_temp_array;
+}
+
+variable_store::variable_store():mem_ctx(ralloc_context(NULL)),next_temp(1),next_temp_array(1),rvalue_regs(NULL),rvalue_regs_count(0)
+{
+   variables = 
hash_table_ctor(0,hash_table_pointer_hash,hash_table_pointer_compare);
+}
+
+variable_store::~variable_store()
+{
+   hash_table_dtor(variables);
+   ralloc_free(mem_ctx);
+}
+
+variable_storage *
+variable_store::find_variable_storage(ir_variable *var) const
+{
+   return (class variable_storage *) hash_table_find(variables,var);
+}
+
+variable_storage*
+variable_store::push(class ir_variable *var, gl_register_file file, int index)
+{
+   variable_storage *storage = new (mem_ctx) variable_storage(var,file,index);
+   hash_table_insert(variables,storage,var);
+   return storage;
+}
+
+variable_storage*
+variable_store::push(ir_variable *ir)
+{
+   variable_storage* retval = push(ir, PROGRAM_TEMPORARY, next_temp);
+   next_temp += type_size(ir-type);
+   if (ir-type-is_array() || ir-type-is_record() || ir-type-is_matrix()) 
{
+  retval-is_array = true;
+   }
+   return retval;
+}
+
+variable_storage*
+variable_store::retrieve_anonymous_temp(unsigned reg)
+{
+   for (unsigned i = 0; i  rvalue_regs_count; i++) {
+  unsigned range_start = rvalue_regs[i].index;
+  unsigned range_end = range_start + type_size(rvalue_regs[i].type) - 1;
+  if (reg = range_start  reg = range_end) {
+ return rvalue_regs + i;
+ }
+   }
+   printf (Failed to get storage);
+   exit(1);
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results.  (not SSA -- variable assignments will reuse
+ * storage).
+ */
+st_src_reg
+variable_store::get_temp(const glsl_type *type)
+{
+   st_src_reg src;
+   rvalue_regs_count++;
+   rvalue_regs = 
reralloc(mem_ctx,rvalue_regs,variable_storage,rvalue_regs_count);
+   variable_storage entry = rvalue_regs[rvalue_regs_count - 1];
+
+   src.type = native_integers ? type-base_type : GLSL_TYPE_FLOAT;
+   src.file = PROGRAM_TEMPORARY;
+   src.index = next_temp;
+   src.reladdr = NULL;
+   next_temp += type_size(type);
+
+   entry.file = PROGRAM_TEMPORARY;
+   entry.index = src.index;
+   entry.type = type;
+   entry.is_reladdressed = false;
+
+   if (type-is_array() || type-is_record() || type-is_matrix()) {
+  entry.is_array = true;
+   }
+
+   if (type-is_array() || type-is_record()) {
+  src.swizzle = SWIZZLE_NOOP;
+   } else {
+  src.swizzle = 

Re: [Mesa-dev] [PATCH 1/3] glsl_to_tgsi: Create a new variable_store class replacing variables field in glsl_to_tgsi_visitor

2012-01-07 Thread Bryan Cain
This is good work.  I just have a few suggested changes.

On 01/07/2012 12:26 PM, Vincent Lejeune wrote:
 ---
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  414 
 +---
  1 files changed, 309 insertions(+), 105 deletions(-)

 diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
 b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 index cecceca..17ae525 100644
 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
 @@ -230,14 +230,16 @@ public:
  class variable_storage : public exec_node {
  public:
 variable_storage(ir_variable *var, gl_register_file file, int index)
 -  : file(file), index(index), var(var)
 +  : file(file), index(index), type(var-type), 
 is_array(var-type-is_array() || var-type-is_record() || 
 var-type-is_matrix()), is_reladdressed(false)
 {
/* empty */
 }
  
 gl_register_file file;
 int index;
 -   ir_variable *var; /* variable that maps to this, if any */
 +   const glsl_type *type; /* variable that maps to this, if any */

The comment there doesn't make sense anymore.

 +   bool is_array;
 +   bool is_reladdressed;
  };
  
  class immediate_storage : public exec_node {
 @@ -286,6 +288,242 @@ public:
 st_src_reg return_reg;
  };
  
 +static int type_size(const glsl_type *type);
 +static int swizzle_for_size(int size);
 +
 +
 +/**
 + * Single place to store all temporary values (either explicit - 
 ir_variable* -
 + * or implicit - returned by get_temp -).

I don't think the last  - is supposed to be there.

 + *
 + * Explicit temps are stored in variables hash_table.
 + * Implicit temps are stored in rvalue_regs array.
 + */
 +class variable_store {
 +   friend class glsl_to_tgsi_variable_allocator;
 +protected:
 +   void *mem_ctx;
 +   hash_table* variables;
 +   unsigned next_temp;
 +   unsigned next_temp_array;
 +   static void reindex_reladdress(const void *, void *, void *);
 +   static void reindex_non_reladdress(const void *, void *, void *);
 +   void reindex_rvalue();
 +   void reindex_rvalue_reladdressed();
 +   variable_storage* rvalue_regs;
 +   unsigned rvalue_regs_count;
 +
 +public:
 +   bool native_integers;
 +   unsigned temp_amount() const;
 +   unsigned temp_array_amount() const;
 +   variable_store();
 +   ~variable_store();
 +   variable_storage *find_variable_storage(class ir_variable *var) const;
 +   variable_storage *push(class ir_variable *, gl_register_file, int);
 +   variable_storage *push(class ir_variable *);
 +   variable_storage *retrieve_anonymous_temp(unsigned);
 +   st_src_reg get_temp(const glsl_type *type);
 +   void optimise_access(void);
 +   unsigned *reindex_table;
 +};
 +
 +unsigned
 +variable_store::temp_amount() const
 +{
 +   return next_temp;
 +}
 +
 +unsigned
 +variable_store::temp_array_amount() const
 +{
 +   return next_temp_array;
 +}
 +
 +variable_store::variable_store():mem_ctx(ralloc_context(NULL)),next_temp(1),next_temp_array(1),rvalue_regs(NULL),rvalue_regs_count(0)
 +{
 +   variables = 
 hash_table_ctor(0,hash_table_pointer_hash,hash_table_pointer_compare);
 +}
 +
 +variable_store::~variable_store()
 +{
 +   hash_table_dtor(variables);
 +   ralloc_free(mem_ctx);
 +}
 +
 +variable_storage *
 +variable_store::find_variable_storage(ir_variable *var) const
 +{
 +   return (class variable_storage *) hash_table_find(variables,var);

The convention in the rest of glsl_to_tgsi (and Mesa) is to put a space
after the comma separating arguments.  I'd prefer it if this patch
followed the same convention.

 +}
 +
 +variable_storage*
 +variable_store::push(class ir_variable *var, gl_register_file file, int 
 index)
 +{
 +   variable_storage *storage = new (mem_ctx) 
 variable_storage(var,file,index);
 +   hash_table_insert(variables,storage,var);
 +   return storage;
 +}
 +
 +variable_storage*
 +variable_store::push(ir_variable *ir)
 +{
 +   variable_storage* retval = push(ir, PROGRAM_TEMPORARY, next_temp);
 +   next_temp += type_size(ir-type);
 +   if (ir-type-is_array() || ir-type-is_record() || 
 ir-type-is_matrix()) {
 +  retval-is_array = true;
 +   }
 +   return retval;
 +}
 +
 +variable_storage*
 +variable_store::retrieve_anonymous_temp(unsigned reg)
 +{
 +   for (unsigned i = 0; i  rvalue_regs_count; i++) {
 +  unsigned range_start = rvalue_regs[i].index;
 +  unsigned range_end = range_start + type_size(rvalue_regs[i].type) - 1;
 +  if (reg = range_start  reg = range_end) {
 + return rvalue_regs + i;
 + }
 +   }
 +   printf (Failed to get storage);
 +   exit(1);

I don't think writing to stdout and exiting cleanly like this is the
right way to handle a fatal error.  It should probably write the error
message to stderr (making clear that it's a fatal error in Mesa, not an
error in the application) and assert (so that a debugger can catch it),
then use call exit(1).

 +}
 +
 +/**
 + * In the initial pass of codegen, we assign temporary numbers to
 + * intermediate results.  (not SSA -- variable 

[Mesa-dev] [PATCH 1/3] glsl_to_tgsi: Create a new variable_store class replacing variables field in glsl_to_tgsi_visitor

2012-01-07 Thread Vincent Lejeune
v2: - Replaces next_temp* with num_temps*
- Uses assert(0  ...) to crashes in retrieve_anonymous_temp
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  420 +---
 1 files changed, 313 insertions(+), 107 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index cecceca..2825180 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -230,14 +230,16 @@ public:
 class variable_storage : public exec_node {
 public:
variable_storage(ir_variable *var, gl_register_file file, int index)
-  : file(file), index(index), var(var)
+  : file(file), index(index), type(var-type), 
is_array(var-type-is_array() || var-type-is_record() || 
var-type-is_matrix()), is_reladdressed(false)
{
   /* empty */
}
 
gl_register_file file;
int index;
-   ir_variable *var; /* variable that maps to this, if any */
+   const glsl_type *type;
+   bool is_array;
+   bool is_reladdressed;
 };
 
 class immediate_storage : public exec_node {
@@ -286,6 +288,244 @@ public:
st_src_reg return_reg;
 };
 
+static int type_size(const glsl_type *type);
+static int swizzle_for_size(int size);
+
+
+/**
+ * Single place to store all temporary values (either explicit - ir_variable* -
+ * or implicit - returned by get_temp).
+ *
+ * Explicit temps are stored in variables hash_table.
+ * Implicit temps are stored in rvalue_regs array.
+ */
+class variable_store {
+   friend class glsl_to_tgsi_variable_allocator;
+protected:
+   void *mem_ctx;
+   hash_table* variables;
+   unsigned num_temps;
+   unsigned num_temps_in_array;
+   static void reindex_reladdress(const void *, void *, void *);
+   static void reindex_non_reladdress(const void *, void *, void *);
+   void reindex_rvalue();
+   void reindex_rvalue_reladdressed();
+   variable_storage* rvalue_regs;
+   unsigned rvalue_regs_count;
+
+public:
+   bool native_integers;
+   unsigned temp_amount() const;
+   unsigned temp_array_amount() const;
+   variable_store();
+   ~variable_store();
+   variable_storage *find_variable_storage(class ir_variable *var) const;
+   variable_storage *push(class ir_variable *, gl_register_file, int);
+   variable_storage *push(class ir_variable *);
+   variable_storage *retrieve_anonymous_temp(unsigned);
+   st_src_reg get_temp(const glsl_type *type);
+   void optimise_access(void);
+   unsigned *reindex_table;
+};
+
+unsigned
+variable_store::temp_amount() const
+{
+   return num_temps;
+}
+
+unsigned
+variable_store::temp_array_amount() const
+{
+   return num_temps_in_array;
+}
+
+variable_store::variable_store()
+   : mem_ctx(ralloc_context(NULL)), num_temps(1), num_temps_in_array(1), 
rvalue_regs(NULL), rvalue_regs_count(0)
+{
+   variables = hash_table_ctor(0, hash_table_pointer_hash, 
hash_table_pointer_compare);
+}
+
+variable_store::~variable_store()
+{
+   hash_table_dtor(variables);
+   ralloc_free(mem_ctx);
+}
+
+variable_storage *
+variable_store::find_variable_storage(ir_variable *var) const
+{
+   return (class variable_storage *) hash_table_find(variables, var);
+}
+
+variable_storage*
+variable_store::push(class ir_variable *var, gl_register_file file, int index)
+{
+   variable_storage *storage = new (mem_ctx) variable_storage(var, file, 
index);
+   hash_table_insert(variables, storage, var);
+   return storage;
+}
+
+variable_storage*
+variable_store::push(ir_variable *ir)
+{
+   variable_storage* retval = push(ir, PROGRAM_TEMPORARY, num_temps);
+   num_temps += type_size(ir-type);
+   if (ir-type-is_array() || ir-type-is_record() || ir-type-is_matrix()) 
{
+  retval-is_array = true;
+   }
+   return retval;
+}
+
+variable_storage*
+variable_store::retrieve_anonymous_temp(unsigned reg)
+{
+   for (unsigned i = 0; i  rvalue_regs_count; i++) {
+  unsigned range_start = rvalue_regs[i].index;
+  unsigned range_end = range_start + type_size(rvalue_regs[i].type) - 1;
+  if (reg = range_start  reg = range_end) {
+ return rvalue_regs + i;
+ }
+   }
+
+   assert(0  Failed to retrieve storage for temp register);
+   exit(1);
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results.  (not SSA -- variable assignments will reuse
+ * storage).
+ */
+st_src_reg
+variable_store::get_temp(const glsl_type *type)
+{
+   st_src_reg src;
+   rvalue_regs_count++;
+   rvalue_regs = reralloc(mem_ctx, rvalue_regs, variable_storage, 
rvalue_regs_count);
+   variable_storage entry = rvalue_regs[rvalue_regs_count - 1];
+
+   src.type = native_integers ? type-base_type : GLSL_TYPE_FLOAT;
+   src.file = PROGRAM_TEMPORARY;
+   src.index = num_temps;
+   src.reladdr = NULL;
+   num_temps += type_size(type);
+
+   entry.file = PROGRAM_TEMPORARY;
+   entry.index = src.index;
+   entry.type = type;
+   entry.is_reladdressed = false;
+
+   if (type-is_array() || type-is_record() || type-is_matrix()) {
+  entry.is_array = true;
+   

[Mesa-dev] [PATCH 1/3] glsl_to_tgsi: Create a new variable_store class replacing variables field in glsl_to_tgsi_visitor

2012-01-06 Thread Vincent Lejeune
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp |  392 
 1 files changed, 287 insertions(+), 105 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index cecceca..b4cf76e 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -230,14 +230,16 @@ public:
 class variable_storage : public exec_node {
 public:
variable_storage(ir_variable *var, gl_register_file file, int index)
-  : file(file), index(index), var(var)
+  : file(file), index(index), type(var-type), 
is_array(var-type-is_array() || var-type-is_record() || 
var-type-is_matrix()), is_reladdressed(false)
{
   /* empty */
}
 
gl_register_file file;
int index;
-   ir_variable *var; /* variable that maps to this, if any */
+   const glsl_type *type; /* variable that maps to this, if any */
+   bool is_array;
+   bool is_reladdressed;
 };
 
 class immediate_storage : public exec_node {
@@ -286,6 +288,220 @@ public:
st_src_reg return_reg;
 };
 
+static int type_size(const glsl_type *type);
+static int swizzle_for_size(int size);
+
+class variable_store {
+   friend class glsl_to_tgsi_variable_allocator;
+protected:
+   void *mem_ctx;
+   hash_table* variables;
+   unsigned next_temp;
+   unsigned next_temp_array;
+   static void reindex_reladdress(const void *, void *, void *);
+   static void reindex_non_reladdress(const void *, void *, void *);
+   void reindex_rvalue();
+   void reindex_rvalue_reladdressed();
+   variable_storage* rvalue_regs;
+   unsigned rvalue_regs_count;
+
+public:
+   bool native_integers;
+   unsigned temp_amount() const;
+   unsigned temp_array_amount() const;
+   variable_store();
+   ~variable_store();
+   variable_storage *find_variable_storage(class ir_variable *var) const;
+   variable_storage *push(class ir_variable *, gl_register_file, int);
+   variable_storage *push(class ir_variable *);
+   variable_storage *retrieve_anonymous_temp(unsigned);
+   st_src_reg get_temp(const glsl_type *type);
+   void optimise_access(void);
+   unsigned *reindex_table;
+};
+
+unsigned
+variable_store::temp_amount() const
+{
+   return next_temp;
+}
+
+unsigned
+variable_store::temp_array_amount() const
+{
+   return next_temp_array;
+}
+
+variable_store::variable_store():mem_ctx(ralloc_context(NULL)),next_temp(1),next_temp_array(1),rvalue_regs_count(0),rvalue_regs(NULL)
+{
+   variables = 
hash_table_ctor(0,hash_table_pointer_hash,hash_table_pointer_compare);
+}
+
+variable_store::~variable_store()
+{
+   hash_table_dtor(variables);
+   ralloc_free(mem_ctx);
+}
+
+variable_storage *
+variable_store::find_variable_storage(ir_variable *var) const
+{
+   return (class variable_storage *) hash_table_find(variables,var);
+}
+
+variable_storage*
+variable_store::push(class ir_variable *var, gl_register_file file, int index)
+{
+   variable_storage *storage = new (mem_ctx) variable_storage(var,file,index);
+   hash_table_insert(variables,storage,var);
+   return storage;
+}
+
+variable_storage*
+variable_store::push(ir_variable *ir)
+{
+   variable_storage* retval = push(ir, PROGRAM_TEMPORARY, next_temp);
+   next_temp += type_size(ir-type);
+   if (ir-type-is_array() || ir-type-is_record() || ir-type-is_matrix()) 
{
+  retval-is_array = true;
+   }
+   return retval;
+}
+
+variable_storage*
+variable_store::retrieve_anonymous_temp(unsigned reg)
+{
+   for (unsigned i = 0; i  rvalue_regs_count; i++) {
+  unsigned range_start = rvalue_regs[i].index;
+  unsigned range_end = range_start + type_size(rvalue_regs[i].type) - 1;
+  if (reg = range_start  reg = range_end) {
+ return rvalue_regs + i;
+ }
+   }
+   printf (Failed to get storage);
+   exit(1);
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results.  (not SSA -- variable assignments will reuse
+ * storage).
+ */
+st_src_reg
+variable_store::get_temp(const glsl_type *type)
+{
+   st_src_reg src;
+   rvalue_regs_count++;
+   rvalue_regs = 
reralloc(mem_ctx,rvalue_regs,variable_storage,rvalue_regs_count);
+   variable_storage entry = rvalue_regs[rvalue_regs_count - 1];
+
+   src.type = native_integers ? type-base_type : GLSL_TYPE_FLOAT;
+   src.file = PROGRAM_TEMPORARY;
+   src.index = next_temp;
+   src.reladdr = NULL;
+   next_temp += type_size(type);
+
+   entry.file = PROGRAM_TEMPORARY;
+   entry.index = src.index;
+   entry.type = type;
+
+   if (type-is_array() || type-is_record() || type-is_matrix()) {
+  entry.is_array = true;
+   }
+
+   if (type-is_array() || type-is_record()) {
+  src.swizzle = SWIZZLE_NOOP;
+   } else {
+  src.swizzle = swizzle_for_size(type-vector_elements);
+   }
+   src.negate = 0;
+
+   return src;
+}
+
+void variable_store::reindex_reladdress(const void *key, void *data, void 
*closure)
+{
+   ir_variable *var = (ir_variable *) key;
+   variable_storage *storage = (variable_storage *) data;
+