mesa: fix temp re-use bug in emit_arith()
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 16 Jul 2008 22:04:43 +0000 (16:04 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 16 Jul 2008 22:11:38 +0000 (16:11 -0600)
src/mesa/shader/slang/slang_emit.c

index f025b15de9d9d50ac3785d76543fdbb13fa3c811..c997c11a7debc6a5222da314990eab36ebfa5df4 100644 (file)
@@ -469,6 +469,12 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
    const slang_ir_info *info = _slang_ir_info(n->Opcode);
    char *srcAnnot[3], *dstAnnot;
    GLuint i;
+   slang_ir_node *temps[3];
+
+   /* we'll save pointers to nodes/storage to free in temps[] until
+    * the very end.
+    */
+   temps[0] = temps[1] = temps[2] = NULL;
 
    assert(info);
    assert(info->InstOpcode != OPCODE_NOP);
@@ -489,9 +495,9 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
       storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Children[0]->Store);
       storage_to_src_reg(&inst->SrcReg[1], n->Children[0]->Children[1]->Store);
       storage_to_src_reg(&inst->SrcReg[2], n->Children[1]->Store);
-      free_temp_storage(emitInfo->vt, n->Children[0]->Children[0]);
-      free_temp_storage(emitInfo->vt, n->Children[0]->Children[1]);
-      free_temp_storage(emitInfo->vt, n->Children[1]);
+      temps[0] = n->Children[0]->Children[0];
+      temps[1] = n->Children[0]->Children[1];
+      temps[2] = n->Children[1];
    }
    else if (info->NumParams == 2 &&
             n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
@@ -505,9 +511,9 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
       storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Children[0]->Store);
       storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Children[1]->Store);
       storage_to_src_reg(&inst->SrcReg[2], n->Children[0]->Store);
-      free_temp_storage(emitInfo->vt, n->Children[1]->Children[0]);
-      free_temp_storage(emitInfo->vt, n->Children[1]->Children[1]);
-      free_temp_storage(emitInfo->vt, n->Children[0]);
+      temps[0] = n->Children[1]->Children[0];
+      temps[1] = n->Children[1]->Children[1];
+      temps[2] = n->Children[0];
    }
    else
 #endif
@@ -532,9 +538,9 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
       for (i = 0; i < info->NumParams; i++)
          srcAnnot[i] = storage_annotation(n->Children[i], emitInfo->prog);
 
-      /* free temps */
+      /* record (potential) temps to free */
       for (i = 0; i < info->NumParams; i++)
-         free_temp_storage(emitInfo->vt, n->Children[i]);
+         temps[i] = n->Children[i];
    }
 
    /* result storage */
@@ -544,6 +550,7 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
       if (!alloc_temp_storage(emitInfo, n, size))
          return NULL;
    }
+
    storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask);
 
    dstAnnot = storage_annotation(n, emitInfo->prog);
@@ -551,6 +558,11 @@ emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
    inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot[0],
                                           srcAnnot[1], srcAnnot[2]);
 
+   /* really free temps now */
+   for (i = 0; i < 3; i++)
+      if (temps[i])
+         free_temp_storage(emitInfo->vt, temps[i]);
+
    /*_mesa_print_instruction(inst);*/
    return inst;
 }