util: Include bitscan.h directly
[mesa.git] / src / compiler / glsl / opt_constant_propagation.cpp
index 6ec4ab498d95e4b9296817e678612731833ae8e4..05dc71efb72038339b58fdec2fe4a091e7b0cd87 100644 (file)
@@ -47,6 +47,9 @@ namespace {
 class acp_entry : public exec_node
 {
 public:
+   /* override operator new from exec_node */
+   DECLARE_LINEAR_ZALLOC_CXX_OPERATORS(acp_entry)
+
    acp_entry(ir_variable *var, unsigned write_mask, ir_constant *constant)
    {
       assert(var);
@@ -77,6 +80,9 @@ public:
 class kill_entry : public exec_node
 {
 public:
+   /* override operator new from exec_node */
+   DECLARE_LINEAR_ZALLOC_CXX_OPERATORS(kill_entry)
+
    kill_entry(ir_variable *var, unsigned write_mask)
    {
       assert(var);
@@ -95,6 +101,7 @@ public:
       progress = false;
       killed_all = false;
       mem_ctx = ralloc_context(0);
+      this->lin_ctx = linear_alloc_parent(this->mem_ctx, 0);
       this->acp = new(mem_ctx) exec_list;
       this->kills = _mesa_hash_table_create(mem_ctx, _mesa_hash_pointer,
                                             _mesa_key_pointer_equal);
@@ -132,6 +139,7 @@ public:
    bool killed_all;
 
    void *mem_ctx;
+   void *lin_ctx;
 };
 
 
@@ -145,8 +153,9 @@ ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue)
       this->progress = true;
 
    ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable();
-   if (var_ref) {
-      ir_constant *constant = var_ref->constant_expression_value();
+   if (var_ref && !var_ref->type->is_array()) {
+      ir_constant *constant =
+         var_ref->constant_expression_value(ralloc_parent(var_ref));
       if (constant) {
          *rvalue = constant;
          this->progress = true;
@@ -229,6 +238,12 @@ ir_constant_propagation_visitor::constant_propagation(ir_rvalue **rvalue) {
       case GLSL_TYPE_BOOL:
         data.b[i] = found->constant->value.b[rhs_channel];
         break;
+      case GLSL_TYPE_UINT64:
+        data.u64[i] = found->constant->value.u64[rhs_channel];
+        break;
+      case GLSL_TYPE_INT64:
+        data.i64[i] = found->constant->value.i64[rhs_channel];
+        break;
       default:
         assert(!"not reached");
         break;
@@ -354,7 +369,7 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
 
    /* Populate the initial acp with a constant of the original */
    foreach_in_list(acp_entry, a, orig_acp) {
-      this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
+      this->acp->push_tail(new(this->lin_ctx) acp_entry(a));
    }
 
    visit_list_elements(this, instructions);
@@ -454,7 +469,7 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
    }
    /* Not already in the hash table.  Make new entry. */
    _mesa_hash_table_insert(this->kills, var,
-                           new(this->mem_ctx) kill_entry(var, write_mask));
+                           new(this->lin_ctx) kill_entry(var, write_mask));
 }
 
 /**
@@ -493,7 +508,7 @@ ir_constant_propagation_visitor::add_constant(ir_assignment *ir)
        deref->var->data.mode == ir_var_shader_shared)
       return;
 
-   entry = new(this->mem_ctx) acp_entry(deref->var, ir->write_mask, constant);
+   entry = new(this->lin_ctx) acp_entry(deref->var, ir->write_mask, constant);
    this->acp->push_tail(entry);
 }