Matt Turner <matts...@gmail.com> writes:

> On Tue, May 5, 2015 at 2:17 PM, Francisco Jerez <curroje...@riseup.net> wrote:
>> Kenneth Graunke <kenn...@whitecape.org> writes:
>>> I like the idea of the builder refactor - having a mechanism for emitting
>>> code at arbitrary points makes a ton of sense.  But I'm uncomfortable
>>> with how much code is added - and duplicated from the existing visitor
>>> code - given that fs_visitor is refactored to use it.
>>>
>>> I agree with Jason that we should discuss our goal - what things should
>>> look like - but frankly, I think we should hold off on large scale
>>> refactoring until after we delete the GLSL IR backend.  There will be
>>> much less code to reorganize.
>>>
>> I agree, I wasn't planning on migrating the rest of the compiler
>> back-end to the builder framework until that happens.
>
> We talked about this on IRC yesterday -- I find it difficult to review
> some of these patches adding large amounts of new infrastructure
> that's only used in other in this series.
>
> Basically, the problem is that you're adding (1) a large amount of new
> infrastructure, and (2) a large amount of tiling calculation/format
> conversion code and neither can be independently evaluated. If the new
> infrastructure was proposed and we could see how it was useful in the
> existing compiler, we could evaluate it. If the new tiling
> calculation/format conversion code used existing compiler
> infrastructure, we could evaluate it.
>
> Combining the two in the same series though makes it difficult.

Matt, I know that a 3k LOC series might be intimidating at first glance,
but:

 - The additional infrastructure is badly needed.  If you've bothered to
   read the commit message [maybe longest in (our git tree's) history]
   or skimmed through the body of the fs_builder patch, read the
   6-screenful e-mail I sent you last October including a detailed
   explanation of the builder, or any of the working sample code
   (including a port of large parts of existing compiler code) I sent
   you back then, you surely already know that I'm not doing this on a
   whim.  The infrastructure equivalent to the builder should have
   *never* been part of the GLSL IR visitor, and the more new
   functionality we throw at the compiler relying on the old
   infrastructure the more difficult the migration will get.

 - Nothing prevents you from "evaluating" the builder framework
   independent from the tiling and format conversion code.  You have
   more than enough information to assess whether the change is
   reasonable on its own.  You have the lengthy explanation from last
   October.  You have sample code from last October showing how it's
   useful in the existing compiler -- And for the case that doesn't seem
   convincing enough I'm attaching a partial port of brw_fs_visitor.cpp
   to the builder framework based on a current tree [but note that it's
   just an example and not meant to be upstreamed].  You have enough
   knowledge of the existing infrastructure that hardly anything about
   the new infrastructure will come as a surprise for you -- It largely
   mimics the existing IR-building methods, their semantics and
   implementation, and the transition from one to the other usually
   amounts to replacing "emit(FOO(...))" with "bld.FOO(...)".  You have
   enough documentation in the code itself -- I've spent a great deal of
   time documenting the builder framework and the image load/store
   implementation [to a much greater extent than is usual in the rest of
   the back-end code, a quickly written bash script gives a
   comment-to-code ratio of 31% vs. the average of 19% in the rest of
   the FS back-end].  Lastly you have me to answer any questions that
   could come up during review -- And the fact that you haven't asked
   any specific technical questions so far other than about codestyle
   and logistics makes me think that you haven't really attempted to
   understand the code in detail yet, and the supposed difficulty you
   talk about may be based on a presumption rather than on your actual
   experience.

 - Even if I turn out to be wrong, your "evaluation" is inconclusive for
   some strange reason, and the new infrastructure is merged with some
   hidden architectural flaw, the risk is close to non-existent.  The
   worst thing that could happen is we have to flip the switch to
   disable ARB_shader_image_load_store again until the problem is fixed.
   No critical functionality is affected because the new infrastructure
   is completely self-contained.

> It seems like we'd be buying into a transition to the new builder
> without having seen what the transition looks like ("[switching to the
> new infrastructure] will be undertaken by a separate series, as it
> involves major back-end surgery").
>
That's not nearly what I meant.  Of course whether and how we carry out
the transition will still be open for discussion, that statement you
quote was intended to show that I'm willing to do the hard work and not
going to abandon the new infrastructure while the transition is half-way
done (as Ken rudely insinuated on IRC).

> That said, I think people are okay with the builder, in principle at
> least. Splitting the visitor classes certainly seems like a good idea.
> In an ideal world, we'd transition the backend over to your new
> builder, and then add the new image_load_store bits on top of that.
> Since we want to delete brw_*_visitor.cpp before we transition to your
> new builder and we're not planning to delete brw_*_visitor.cpp until
> after 10.6, then this can't happen in 10.6 unless we change something.
>
Yeah, I agree that it wouldn't make sense to do the transition until the
GLSL IR visitor is removed, but I don't see anything less "ideal" about
having ARB_shader_image_load_store be the first to use the new
infrastructure.  If anything it's an advantage that the new experimental
infrastructure (although I'm quite confident in it and calling it
experimental is an overstatement) is only exercised by a single
extension we can easily disable rather than by the whole compiler.

>>> It may also make sense to land Skylake support first - I believe we can
>>> use typed surface messages in most places, which is a lot easier.  We
>>> could land that, then add the additional complexity to support BDW/HSW.
>
> I'd like to reiterate this point. The platform we have to support this
> extension on is Gen9, and Gen9's typed messages support nearly all of
> the formats required.
>
> If we enable Gen9, we'll have more time to figure out how to do the
> rest of the infrastructure changes. Is doing Gen9 first feasible?

SKL doesn't fundamentally change the picture.  It still needs a large
portion of the infrastructure introduced in this series, including the
format conversion code (although it will only be fully exercised by a
smaller subset of the formats, thankfully).  The only major thing it
saves us from doing is the tiling calculation, which is abstracted out
in a single (ugly) less than 100 LOC function part of PATCH 19 that
doesn't use the new infrastructure in any particularly clever way.

Because of the amount of infrastructure you'd have to re-implement and
because adding SKL support to the existing series is trivial (the change
required in this whole series adds a single line of code), I think that
starting from scratch with a SKL-only implementation would be a massive
waste of time.

The changes required in my old state-setup series are a bit more
invasive, but they are still quite straightforward and I already have
the extension working at the same level as on earlier generations.  I'll
send updated versions of the affected patches shortly.

diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index 4f463f4..5e67337 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -51,6 +51,7 @@ extern "C" {
 #include "glsl/ir.h"
 #include "glsl/nir/nir.h"
 #include "program/sampler.h"
+#include "brw_fs_builder.h"
 
 struct bblock_t;
 namespace {
@@ -539,6 +540,7 @@ public:
    const unsigned dispatch_width; /**< 8 or 16 */
 
    unsigned promoted_constants;
+   brw::fs_builder bld;
 };
 
 /**
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index 2867b67..c7186de 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -270,8 +270,8 @@ fs_visitor::visit(ir_dereference_array *ir)
       fs_reg tmp = vgrf(glsl_type::uint_type);
 
       ir->array_index->accept(this);
-      emit(MUL(tmp, this->result, fs_reg(ATOMIC_COUNTER_SIZE)));
-      emit(ADD(tmp, tmp, src));
+      bld.MUL(tmp, this->result, fs_reg(ATOMIC_COUNTER_SIZE));
+      bld.ADD(tmp, tmp, src);
       this->result = tmp;
 
    } else {
@@ -298,10 +298,10 @@ fs_visitor::visit(ir_dereference_array *ir)
 
          fs_reg index_reg;
          index_reg = vgrf(glsl_type::int_type);
-         emit(BRW_OPCODE_MUL, index_reg, this->result, fs_reg(element_size));
+         bld.emit(BRW_OPCODE_MUL, index_reg, this->result, fs_reg(element_size));
 
          if (src.reladdr) {
-            emit(BRW_OPCODE_ADD, index_reg, *src.reladdr, index_reg);
+            bld.emit(BRW_OPCODE_ADD, index_reg, *src.reladdr, index_reg);
          }
 
          src.reladdr = ralloc(mem_ctx, fs_reg);
@@ -322,19 +322,19 @@ fs_visitor::emit_lrp(const fs_reg &dst, const fs_reg &x, const fs_reg &y,
       fs_reg one_minus_a         = vgrf(glsl_type::float_type);
       fs_reg x_times_one_minus_a = vgrf(glsl_type::float_type);
 
-      emit(MUL(y_times_a, y, a));
+      bld.MUL(y_times_a, y, a);
 
       fs_reg negative_a = a;
       negative_a.negate = !a.negate;
-      emit(ADD(one_minus_a, negative_a, fs_reg(1.0f)));
-      emit(MUL(x_times_one_minus_a, x, one_minus_a));
+      bld.ADD(one_minus_a, negative_a, fs_reg(1.0f));
+      bld.MUL(x_times_one_minus_a, x, one_minus_a);
 
-      return emit(ADD(dst, x_times_one_minus_a, y_times_a));
+      return bld.ADD(dst, x_times_one_minus_a, y_times_a);
    } else {
       /* The LRP instruction actually does op1 * op0 + op2 * (1 - op0), so
        * we need to reorder the operands.
        */
-      return emit(LRP(dst, a, y, x));
+      return bld.LRP(dst, a, y, x);
    }
 }
 
@@ -348,12 +348,12 @@ fs_visitor::emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg &d
    fs_inst *inst;
 
    if (devinfo->gen >= 6) {
-      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
+      inst = bld.emit(BRW_OPCODE_SEL, dst, src0, src1);
       inst->conditional_mod = conditionalmod;
    } else {
-      emit(CMP(reg_null_d, src0, src1, conditionalmod));
+      bld.CMP(reg_null_d, src0, src1, conditionalmod);
 
-      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
+      inst = bld.emit(BRW_OPCODE_SEL, dst, src0, src1);
       inst->predicate = BRW_PREDICATE_NORMAL;
    }
 }
@@ -363,9 +363,9 @@ fs_visitor::emit_uniformize(const fs_reg &dst, const fs_reg &src)
 {
    const fs_reg chan_index = vgrf(glsl_type::uint_type);
 
-   emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, component(chan_index, 0))
+   bld.emit(SHADER_OPCODE_FIND_LIVE_CHANNEL, component(chan_index, 0))
       ->force_writemask_all = true;
-   emit(SHADER_OPCODE_BROADCAST, component(dst, 0),
+   bld.emit(SHADER_OPCODE_BROADCAST, component(dst, 0),
         src, component(chan_index, 0))
       ->force_writemask_all = true;
 }
@@ -444,11 +444,11 @@ fs_visitor::try_emit_line(ir_expression *ir)
    fs_reg src1 = this->result;
 
    fs_reg src0 = vgrf(ir->type);
-   emit(BRW_OPCODE_MOV, src0,
+   bld.emit(BRW_OPCODE_MOV, src0,
         fs_reg((uint8_t)mul_operand_vf, 0, 0, (uint8_t)add_operand_vf));
 
    this->result = vgrf(ir->type);
-   emit(BRW_OPCODE_LINE, this->result, src0, src1);
+   bld.emit(BRW_OPCODE_LINE, this->result, src0, src1);
    return true;
 }
 
@@ -506,7 +506,7 @@ fs_visitor::try_emit_mad(ir_expression *ir)
       src2.negate = false;
 
    this->result = vgrf(ir->type);
-   emit(BRW_OPCODE_MAD, this->result, src0, src1, src2);
+   bld.emit(BRW_OPCODE_MAD, this->result, src0, src1, src2);
 
    return true;
 }
@@ -572,7 +572,7 @@ fs_visitor::try_emit_b2f_of_comparison(ir_expression *ir)
             this->result = vgrf(ir->type);
             op[i ^ 1].type = BRW_REGISTER_TYPE_F;
 
-            fs_inst *inst = emit(SEL(this->result, op[i ^ 1], fs_reg(1.0f)));
+            fs_inst *inst = bld.SEL(this->result, op[i ^ 1], fs_reg(1.0f));
             inst->predicate = BRW_PREDICATE_NORMAL;
             inst->predicate_inverse = true;
             return true;
@@ -583,10 +583,10 @@ fs_visitor::try_emit_b2f_of_comparison(ir_expression *ir)
    emit_bool_to_cond_code(cmp);
 
    fs_reg temp = vgrf(ir->type);
-   emit(MOV(temp, fs_reg(1.0f)));
+   bld.MOV(temp, fs_reg(1.0f));
 
    this->result = vgrf(ir->type);
-   fs_inst *inst = emit(SEL(this->result, temp, fs_reg(0.0f)));
+   fs_inst *inst = bld.SEL(this->result, temp, fs_reg(0.0f));
    inst->predicate = BRW_PREDICATE_NORMAL;
 
    return true;
@@ -641,7 +641,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
 
    switch (ir->operation) {
    case ir_unop_interpolate_at_centroid:
-      inst = emit(FS_OPCODE_INTERPOLATE_AT_CENTROID, dst_xy, src, fs_reg(0u));
+      inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_CENTROID, dst_xy, src, fs_reg(0u));
       break;
 
    case ir_binop_interpolate_at_sample: {
@@ -649,7 +649,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
       assert(sample_num || !"nonconstant sample number should have been lowered.");
 
       unsigned msg_data = sample_num->value.i[0] << 4;
-      inst = emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_xy, src, fs_reg(msg_data));
+      inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_SAMPLE, dst_xy, src, fs_reg(msg_data));
       break;
    }
 
@@ -658,7 +658,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
       if (const_offset) {
          unsigned msg_data = pack_pixel_offset(const_offset->value.f[0]) |
                             (pack_pixel_offset(const_offset->value.f[1]) << 4);
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_xy, src,
+         inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_SHARED_OFFSET, dst_xy, src,
                      fs_reg(msg_data));
       } else {
          /* pack the operands: hw wants offsets as 4 bit signed ints */
@@ -667,8 +667,8 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
          fs_reg src2 = src;
          for (int i = 0; i < 2; i++) {
             fs_reg temp = vgrf(glsl_type::float_type);
-            emit(MUL(temp, this->result, fs_reg(16.0f)));
-            emit(MOV(src2, temp));  /* float to int */
+            bld.MUL(temp, this->result, fs_reg(16.0f));
+            bld.MOV(src2, temp);  /* float to int */
 
             /* Clamp the upper end of the range to +7/16. ARB_gpu_shader5 requires
              * that we support a maximum offset of +0.5, which isn't representable
@@ -683,7 +683,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
              * FRAGMENT_INTERPOLATION_OFFSET_BITS"
              */
 
-            fs_inst *inst = emit(BRW_OPCODE_SEL, src2, src2, fs_reg(7));
+            fs_inst *inst = bld.emit(BRW_OPCODE_SEL, src2, src2, fs_reg(7));
             inst->conditional_mod = BRW_CONDITIONAL_L; /* min(src2, 7) */
 
             src2 = offset(src2, 1);
@@ -691,7 +691,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
          }
 
          mlen = 2 * reg_width;
-         inst = emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_xy, src,
+         inst = bld.emit(FS_OPCODE_INTERPOLATE_AT_PER_SLOT_OFFSET, dst_xy, src,
                      fs_reg(0u));
       }
       break;
@@ -713,7 +713,7 @@ fs_visitor::emit_interpolate_expression(ir_expression *ir)
 
    for (int i = 0; i < ir->type->vector_elements; i++) {
       int ch = swiz ? ((*(int *)&swiz->mask) >> 2*i) & 3 : i;
-      emit(FS_OPCODE_LINTERP, res, dst_xy,
+      bld.emit(FS_OPCODE_LINTERP, res, dst_xy,
            fs_reg(interp_reg(var->data.location, ch)));
       res = offset(res, 1);
    }
@@ -750,7 +750,7 @@ fs_visitor::visit(ir_expression *ir)
       emit_bool_to_cond_code(ir->operands[0]);
 
       this->result = vgrf(ir->type);
-      inst = emit(SEL(this->result, op[1], op[2]));
+      inst = bld.SEL(this->result, op[1], op[2]);
       inst->predicate = BRW_PREDICATE_NORMAL;
       return;
 
@@ -796,16 +796,16 @@ fs_visitor::visit(ir_expression *ir)
 
    switch (ir->operation) {
    case ir_unop_logic_not:
-      emit(NOT(this->result, op[0]));
+      bld.NOT(this->result, op[0]);
       break;
    case ir_unop_neg:
       op[0].negate = !op[0].negate;
-      emit(MOV(this->result, op[0]));
+      bld.MOV(this->result, op[0]);
       break;
    case ir_unop_abs:
       op[0].abs = true;
       op[0].negate = false;
-      emit(MOV(this->result, op[0]));
+      bld.MOV(this->result, op[0]);
       break;
    case ir_unop_sign:
       if (ir->type->is_float()) {
@@ -814,13 +814,13 @@ fs_visitor::visit(ir_expression *ir)
           * Predicated OR ORs 1.0 (0x3f800000) with the sign bit if val is not
           * zero.
           */
-         emit(CMP(reg_null_f, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+         bld.CMP(reg_null_f, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ);
 
          op[0].type = BRW_REGISTER_TYPE_UD;
          this->result.type = BRW_REGISTER_TYPE_UD;
-         emit(AND(this->result, op[0], fs_reg(0x80000000u)));
+         bld.AND(this->result, op[0], fs_reg(0x80000000u));
 
-         inst = emit(OR(this->result, this->result, fs_reg(0x3f800000u)));
+         inst = bld.OR(this->result, this->result, fs_reg(0x3f800000u));
          inst->predicate = BRW_PREDICATE_NORMAL;
 
          this->result.type = BRW_REGISTER_TYPE_F;
@@ -829,11 +829,11 @@ fs_visitor::visit(ir_expression *ir)
           *               -> non-negative val generates 0x00000000.
           *  Predicated OR sets 1 if val is positive.
           */
-         emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_G));
+         bld.CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_G);
 
-         emit(ASR(this->result, op[0], fs_reg(31)));
+         bld.ASR(this->result, op[0], fs_reg(31));
 
-         inst = emit(OR(this->result, this->result, fs_reg(1)));
+         inst = bld.OR(this->result, this->result, fs_reg(1));
          inst->predicate = BRW_PREDICATE_NORMAL;
       }
       break;
@@ -860,37 +860,37 @@ fs_visitor::visit(ir_expression *ir)
    case ir_unop_dFdx:
       /* Select one of the two opcodes based on the glHint value. */
       if (fs_key->high_quality_derivatives)
-         emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
+         bld.emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
       else
-         emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
+         bld.emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
       break;
 
    case ir_unop_dFdx_coarse:
-      emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
+      bld.emit(FS_OPCODE_DDX_COARSE, this->result, op[0]);
       break;
 
    case ir_unop_dFdx_fine:
-      emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
+      bld.emit(FS_OPCODE_DDX_FINE, this->result, op[0]);
       break;
 
    case ir_unop_dFdy:
       /* Select one of the two opcodes based on the glHint value. */
       if (fs_key->high_quality_derivatives)
-         emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
+         bld.emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
       else
-         emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
+         bld.emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
       break;
 
    case ir_unop_dFdy_coarse:
-      emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
+      bld.emit(FS_OPCODE_DDY_COARSE, result, op[0], fs_reg(fs_key->render_to_fbo));
       break;
 
    case ir_unop_dFdy_fine:
-      emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
+      bld.emit(FS_OPCODE_DDY_FINE, result, op[0], fs_reg(fs_key->render_to_fbo));
       break;
 
    case ir_binop_add:
-      emit(ADD(this->result, op[0], op[1]));
+      bld.ADD(this->result, op[0], op[1]);
       break;
    case ir_binop_sub:
       unreachable("not reached: should be handled by ir_sub_to_add_neg");
@@ -904,14 +904,14 @@ fs_visitor::visit(ir_expression *ir)
           */
          if (ir->operands[0]->is_uint16_constant()) {
             if (devinfo->gen < 7)
-               emit(MUL(this->result, op[0], op[1]));
+               bld.MUL(this->result, op[0], op[1]);
             else
-               emit(MUL(this->result, op[1], op[0]));
+               bld.MUL(this->result, op[1], op[0]);
          } else if (ir->operands[1]->is_uint16_constant()) {
             if (devinfo->gen < 7)
-               emit(MUL(this->result, op[1], op[0]));
+               bld.MUL(this->result, op[1], op[0]);
             else
-               emit(MUL(this->result, op[0], op[1]));
+               bld.MUL(this->result, op[0], op[1]);
          } else {
             if (devinfo->gen >= 7)
                no16("SIMD16 explicit accumulator operands unsupported\n");
@@ -919,12 +919,12 @@ fs_visitor::visit(ir_expression *ir)
             struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                         this->result.type);
 
-            emit(MUL(acc, op[0], op[1]));
-            emit(MACH(reg_null_d, op[0], op[1]));
-            emit(MOV(this->result, fs_reg(acc)));
+            bld.MUL(acc, op[0], op[1]);
+            bld.MACH(reg_null_d, op[0], op[1]);
+            bld.MOV(this->result, fs_reg(acc));
          }
       } else {
-	 emit(MUL(this->result, op[0], op[1]));
+	 bld.MUL(this->result, op[0], op[1]);
       }
       break;
    case ir_binop_imul_high: {
@@ -934,8 +934,8 @@ fs_visitor::visit(ir_expression *ir)
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                   this->result.type);
 
-      fs_inst *mul = emit(MUL(acc, op[0], op[1]));
-      emit(MACH(this->result, op[0], op[1]));
+      fs_inst *mul = bld.MUL(acc, op[0], op[1]);
+      bld.MACH(this->result, op[0], op[1]);
 
       /* Until Gen8, integer multiplies read 32-bits from one source, and
        * 16-bits from the other, and relying on the MACH instruction to
@@ -973,8 +973,8 @@ fs_visitor::visit(ir_expression *ir)
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                   BRW_REGISTER_TYPE_UD);
 
-      emit(ADDC(reg_null_ud, op[0], op[1]));
-      emit(MOV(this->result, fs_reg(acc)));
+      bld.ADDC(reg_null_ud, op[0], op[1]);
+      bld.MOV(this->result, fs_reg(acc));
       break;
    }
    case ir_binop_borrow: {
@@ -984,8 +984,8 @@ fs_visitor::visit(ir_expression *ir)
       struct brw_reg acc = retype(brw_acc_reg(dispatch_width),
                                   BRW_REGISTER_TYPE_UD);
 
-      emit(SUBB(reg_null_ud, op[0], op[1]));
-      emit(MOV(this->result, fs_reg(acc)));
+      bld.SUBB(reg_null_ud, op[0], op[1]);
+      bld.MOV(this->result, fs_reg(acc));
       break;
    }
    case ir_binop_mod:
@@ -1007,20 +1007,20 @@ fs_visitor::visit(ir_expression *ir)
          resolve_bool_comparison(ir->operands[1], &op[1]);
       }
 
-      emit(CMP(this->result, op[0], op[1],
-               brw_conditional_for_comparison(ir->operation)));
+      bld.CMP(this->result, op[0], op[1],
+               brw_conditional_for_comparison(ir->operation));
       break;
 
    case ir_binop_logic_xor:
-      emit(XOR(this->result, op[0], op[1]));
+      bld.XOR(this->result, op[0], op[1]);
       break;
 
    case ir_binop_logic_or:
-      emit(OR(this->result, op[0], op[1]));
+      bld.OR(this->result, op[0], op[1]);
       break;
 
    case ir_binop_logic_and:
-      emit(AND(this->result, op[0], op[1]));
+      bld.AND(this->result, op[0], op[1]);
       break;
 
    case ir_binop_dot:
@@ -1069,11 +1069,11 @@ fs_visitor::visit(ir_expression *ir)
    case ir_unop_u2f:
    case ir_unop_f2i:
    case ir_unop_f2u:
-      emit(MOV(this->result, op[0]));
+      bld.MOV(this->result, op[0]);
       break;
 
    case ir_unop_b2i:
-      emit(AND(this->result, op[0], fs_reg(1)));
+      bld.AND(this->result, op[0], fs_reg(1));
       break;
    case ir_unop_b2f:
       if (devinfo->gen <= 5) {
@@ -1081,36 +1081,36 @@ fs_visitor::visit(ir_expression *ir)
       }
       op[0].type = BRW_REGISTER_TYPE_D;
       this->result.type = BRW_REGISTER_TYPE_D;
-      emit(AND(this->result, op[0], fs_reg(0x3f800000u)));
+      bld.AND(this->result, op[0], fs_reg(0x3f800000u));
       this->result.type = BRW_REGISTER_TYPE_F;
       break;
 
    case ir_unop_f2b:
-      emit(CMP(this->result, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+      bld.CMP(this->result, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ);
       break;
    case ir_unop_i2b:
-      emit(CMP(this->result, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
+      bld.CMP(this->result, op[0], fs_reg(0), BRW_CONDITIONAL_NZ);
       break;
 
    case ir_unop_trunc:
-      emit(RNDZ(this->result, op[0]));
+      bld.RNDZ(this->result, op[0]);
       break;
    case ir_unop_ceil: {
          fs_reg tmp = vgrf(ir->type);
          op[0].negate = !op[0].negate;
-         emit(RNDD(tmp, op[0]));
+         bld.RNDD(tmp, op[0]);
          tmp.negate = true;
-         emit(MOV(this->result, tmp));
+         bld.MOV(this->result, tmp);
       }
       break;
    case ir_unop_floor:
-      emit(RNDD(this->result, op[0]));
+      bld.RNDD(this->result, op[0]);
       break;
    case ir_unop_fract:
-      emit(FRC(this->result, op[0]));
+      bld.FRC(this->result, op[0]);
       break;
    case ir_unop_round_even:
-      emit(RNDE(this->result, op[0]));
+      bld.RNDE(this->result, op[0]);
       break;
 
    case ir_binop_min:
@@ -1133,24 +1133,24 @@ fs_visitor::visit(ir_expression *ir)
    case ir_unop_pack_half_2x16:
       unreachable("not reached: should be handled by lower_packing_builtins");
    case ir_unop_unpack_half_2x16_split_x:
-      emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X, this->result, op[0]);
+      bld.emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_X, this->result, op[0]);
       break;
    case ir_unop_unpack_half_2x16_split_y:
-      emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y, this->result, op[0]);
+      bld.emit(FS_OPCODE_UNPACK_HALF_2x16_SPLIT_Y, this->result, op[0]);
       break;
    case ir_binop_pow:
       emit_math(SHADER_OPCODE_POW, this->result, op[0], op[1]);
       break;
 
    case ir_unop_bitfield_reverse:
-      emit(BFREV(this->result, op[0]));
+      bld.BFREV(this->result, op[0]);
       break;
    case ir_unop_bit_count:
-      emit(CBIT(this->result, op[0]));
+      bld.CBIT(this->result, op[0]);
       break;
    case ir_unop_find_msb:
       temp = vgrf(glsl_type::uint_type);
-      emit(FBH(temp, op[0]));
+      bld.FBH(temp, op[0]);
 
       /* FBH counts from the MSB side, while GLSL's findMSB() wants the count
        * from the LSB side. If FBH didn't return an error (0xFFFFFFFF), then
@@ -1158,61 +1158,61 @@ fs_visitor::visit(ir_expression *ir)
        */
 
       /* FBH only supports UD type for dst, so use a MOV to convert UD to D. */
-      emit(MOV(this->result, temp));
-      emit(CMP(reg_null_d, this->result, fs_reg(-1), BRW_CONDITIONAL_NZ));
+      bld.MOV(this->result, temp);
+      bld.CMP(reg_null_d, this->result, fs_reg(-1), BRW_CONDITIONAL_NZ);
 
       temp.negate = true;
-      inst = emit(ADD(this->result, temp, fs_reg(31)));
+      inst = bld.ADD(this->result, temp, fs_reg(31));
       inst->predicate = BRW_PREDICATE_NORMAL;
       break;
    case ir_unop_find_lsb:
-      emit(FBL(this->result, op[0]));
+      bld.FBL(this->result, op[0]);
       break;
    case ir_unop_saturate:
-      inst = emit(MOV(this->result, op[0]));
+      inst = bld.MOV(this->result, op[0]);
       inst->saturate = true;
       break;
    case ir_triop_bitfield_extract:
       /* Note that the instruction's argument order is reversed from GLSL
        * and the IR.
        */
-      emit(BFE(this->result, op[2], op[1], op[0]));
+      bld.BFE(this->result, op[2], op[1], op[0]);
       break;
    case ir_binop_bfm:
-      emit(BFI1(this->result, op[0], op[1]));
+      bld.emit(BFI1(this->result, op[0], op[1]));
       break;
    case ir_triop_bfi:
-      emit(BFI2(this->result, op[0], op[1], op[2]));
+      bld.emit(BFI2(this->result, op[0], op[1], op[2]));
       break;
    case ir_quadop_bitfield_insert:
       unreachable("not reached: should be handled by "
               "lower_instructions::bitfield_insert_to_bfm_bfi");
 
    case ir_unop_bit_not:
-      emit(NOT(this->result, op[0]));
+      bld.NOT(this->result, op[0]);
       break;
    case ir_binop_bit_and:
-      emit(AND(this->result, op[0], op[1]));
+      bld.AND(this->result, op[0], op[1]);
       break;
    case ir_binop_bit_xor:
-      emit(XOR(this->result, op[0], op[1]));
+      bld.XOR(this->result, op[0], op[1]);
       break;
    case ir_binop_bit_or:
-      emit(OR(this->result, op[0], op[1]));
+      bld.OR(this->result, op[0], op[1]);
       break;
 
    case ir_binop_lshift:
-      emit(SHL(this->result, op[0], op[1]));
+      bld.SHL(this->result, op[0], op[1]);
       break;
 
    case ir_binop_rshift:
       if (ir->type->base_type == GLSL_TYPE_INT)
-	 emit(ASR(this->result, op[0], op[1]));
+	 bld.ASR(this->result, op[0], op[1]);
       else
-	 emit(SHR(this->result, op[0], op[1]));
+	 bld.SHR(this->result, op[0], op[1]);
       break;
    case ir_binop_pack_half_2x16_split:
-      emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, this->result, op[0], op[1]);
+      bld.emit(FS_OPCODE_PACK_HALF_2x16_SPLIT, this->result, op[0], op[1]);
       break;
    case ir_binop_ubo_load: {
       /* This IR node takes a constant uniform block and a constant or
@@ -1234,8 +1234,8 @@ fs_visitor::visit(ir_expression *ir)
           * from any live channel.
           */
          surf_index = vgrf(glsl_type::uint_type);
-         emit(ADD(surf_index, op[0],
-                  fs_reg(stage_prog_data->binding_table.ubo_start)));
+         bld.ADD(surf_index, op[0],
+                  fs_reg(stage_prog_data->binding_table.ubo_start));
          emit_uniformize(surf_index, surf_index);
 
          /* Assume this may touch any UBO. It would be nice to provide
@@ -1251,7 +1251,7 @@ fs_visitor::visit(ir_expression *ir)
          packed_consts.type = result.type;
 
          fs_reg const_offset_reg = fs_reg(const_offset->value.u[0] & ~15);
-         emit(new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, 8,
+         bld.emit(new(mem_ctx) fs_inst(FS_OPCODE_UNIFORM_PULL_CONSTANT_LOAD, 8,
                                    packed_consts, surf_index, const_offset_reg));
 
          for (int i = 0; i < ir->type->vector_elements; i++) {
@@ -1266,9 +1266,9 @@ fs_visitor::visit(ir_expression *ir)
              * values with the low bit set to 1.  Convert them using CMP.
              */
             if (ir->type->base_type == GLSL_TYPE_BOOL) {
-               emit(CMP(result, packed_consts, fs_reg(0u), BRW_CONDITIONAL_NZ));
+               bld.CMP(result, packed_consts, fs_reg(0u), BRW_CONDITIONAL_NZ);
             } else {
-               emit(MOV(result, packed_consts));
+               bld.MOV(result, packed_consts);
             }
 
             result = offset(result, 1);
@@ -1276,14 +1276,14 @@ fs_visitor::visit(ir_expression *ir)
       } else {
          /* Turn the byte offset into a dword offset. */
          fs_reg base_offset = vgrf(glsl_type::int_type);
-         emit(SHR(base_offset, op[1], fs_reg(2)));
+         bld.SHR(base_offset, op[1], fs_reg(2));
 
          for (int i = 0; i < ir->type->vector_elements; i++) {
             emit(VARYING_PULL_CONSTANT_LOAD(result, surf_index,
                                             base_offset, i));
 
             if (ir->type->base_type == GLSL_TYPE_BOOL)
-               emit(CMP(result, result, fs_reg(0), BRW_CONDITIONAL_NZ));
+               bld.CMP(result, result, fs_reg(0), BRW_CONDITIONAL_NZ);
 
             result = offset(result, 1);
          }
@@ -1297,7 +1297,7 @@ fs_visitor::visit(ir_expression *ir)
       /* Note that the instruction's argument order is reversed from GLSL
        * and the IR.
        */
-      emit(MAD(this->result, op[2], op[1], op[0]));
+      bld.MAD(this->result, op[2], op[1], op[0]);
       break;
 
    case ir_triop_lrp:
@@ -1341,7 +1341,7 @@ fs_visitor::emit_assignment_writes(fs_reg &l, fs_reg &r,
 	 r.type = brw_type_for_base_type(type);
 
 	 if (predicated || !l.equals(r)) {
-	    fs_inst *inst = emit(MOV(l, r));
+	    fs_inst *inst = bld.MOV(l, r);
 	    inst->predicate = predicated ? BRW_PREDICATE_NORMAL : BRW_PREDICATE_NONE;
 	 }
 
@@ -1445,7 +1445,7 @@ fs_visitor::visit(ir_assignment *ir)
        ir->lhs->type->is_vector()) {
       for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
 	 if (ir->write_mask & (1 << i)) {
-	    inst = emit(MOV(l, r));
+	    inst = bld.MOV(l, r);
 	    if (ir->condition)
 	       inst->predicate = BRW_PREDICATE_NORMAL;
 	    r = offset(r, 1);
@@ -1474,7 +1474,7 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
 
    if (shadow_c.file != BAD_FILE) {
       for (int i = 0; i < coord_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
 	 coordinate = offset(coordinate, 1);
       }
 
@@ -1482,7 +1482,7 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
        * the unused slots must be zeroed.
        */
       for (int i = coord_components; i < 3; i++) {
-         emit(MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f)));
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f));
       }
       mlen += 3;
 
@@ -1490,25 +1490,25 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
 	 /* There's no plain shadow compare message, so we use shadow
 	  * compare with a bias of 0.0.
 	  */
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f)));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
 	 mlen++;
       } else if (op == ir_txb || op == ir_txl) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen), lod));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen), lod);
 	 mlen++;
       } else {
          unreachable("Should not get here.");
       }
 
-      emit(MOV(fs_reg(MRF, base_mrf + mlen), shadow_c));
+      bld.MOV(fs_reg(MRF, base_mrf + mlen), shadow_c);
       mlen++;
    } else if (op == ir_tex) {
       for (int i = 0; i < coord_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
 	 coordinate = offset(coordinate, 1);
       }
       /* zero the others. */
       for (int i = coord_components; i<3; i++) {
-         emit(MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f)));
+         bld.MOV(fs_reg(MRF, base_mrf + mlen + i), fs_reg(0.0f));
       }
       /* gen4's SIMD8 sampler always has the slots for u,v,r present. */
       mlen += 3;
@@ -1516,7 +1516,7 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
       fs_reg &dPdx = lod;
 
       for (int i = 0; i < coord_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen + i), coordinate);
 	 coordinate = offset(coordinate, 1);
       }
       /* the slots for u and v are always present, but r is optional */
@@ -1537,20 +1537,20 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
        *        m5     m6     m7     m8     m9     m10
        */
       for (int i = 0; i < grad_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen), dPdx));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen), dPdx);
 	 dPdx = offset(dPdx, 1);
       }
       mlen += MAX2(grad_components, 2);
 
       for (int i = 0; i < grad_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen), dPdy));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen), dPdy);
 	 dPdy = offset(dPdy, 1);
       }
       mlen += MAX2(grad_components, 2);
    } else if (op == ir_txs) {
       /* There's no SIMD8 resinfo message on Gen4.  Use SIMD16 instead. */
       simd16 = true;
-      emit(MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod));
+      bld.MOV(fs_reg(MRF, base_mrf + mlen, BRW_REGISTER_TYPE_UD), lod);
       mlen += 2;
    } else {
       /* Oh joy.  gen4 doesn't have SIMD8 non-shadow-compare bias/lod
@@ -1560,8 +1560,8 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
       assert(op == ir_txb || op == ir_txl || op == ir_txf);
 
       for (int i = 0; i < coord_components; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
-                  coordinate));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen + i * 2, coordinate.type),
+                  coordinate);
 	 coordinate = offset(coordinate, 1);
       }
 
@@ -1569,13 +1569,13 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
        * be necessary for TXF (ld), but seems wise to do for all messages.
        */
       for (int i = coord_components; i < 3; i++) {
-	 emit(MOV(fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f)));
+	 bld.MOV(fs_reg(MRF, base_mrf + mlen + i * 2), fs_reg(0.0f));
       }
 
       /* lod/bias appears after u/v/r. */
       mlen += 6;
 
-      emit(MOV(fs_reg(MRF, base_mrf + mlen, lod.type), lod));
+      bld.MOV(fs_reg(MRF, base_mrf + mlen, lod.type), lod);
       mlen++;
 
       /* The unused upper half. */
@@ -1603,7 +1603,7 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
       unreachable("not reached");
    }
 
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
    inst->base_mrf = base_mrf;
    inst->mlen = mlen;
    inst->header_size = 1;
@@ -1611,7 +1611,7 @@ fs_visitor::emit_texture_gen4(ir_texture_opcode op, fs_reg dst,
 
    if (simd16) {
       for (int i = 0; i < 4; i++) {
-	 emit(MOV(orig_dst, dst));
+	 bld.MOV(orig_dst, dst);
 	 orig_dst = offset(orig_dst, 1);
 	 dst = offset(dst, 2);
       }
@@ -1637,7 +1637,7 @@ fs_visitor::emit_texture_gen4_simd16(ir_texture_opcode op, fs_reg dst,
 
    /* Copy the coordinates. */
    for (int i = 0; i < vector_elements; i++) {
-      emit(MOV(retype(offset(message, i), coordinate.type), coordinate));
+      bld.MOV(retype(offset(message, i), coordinate.type), coordinate);
       coordinate = offset(coordinate, 1);
    }
 
@@ -1646,20 +1646,20 @@ fs_visitor::emit_texture_gen4_simd16(ir_texture_opcode op, fs_reg dst,
    /* Messages other than sample and ld require all three components */
    if (has_lod || shadow_c.file != BAD_FILE) {
       for (int i = vector_elements; i < 3; i++) {
-         emit(MOV(offset(message, i), fs_reg(0.0f)));
+         bld.MOV(offset(message, i), fs_reg(0.0f));
       }
    }
 
    if (has_lod) {
       fs_reg msg_lod = retype(offset(message, 3), op == ir_txf ?
                               BRW_REGISTER_TYPE_UD : BRW_REGISTER_TYPE_F);
-      emit(MOV(msg_lod, lod));
+      bld.MOV(msg_lod, lod);
       msg_end = offset(msg_lod, 1);
    }
 
    if (shadow_c.file != BAD_FILE) {
       fs_reg msg_ref = offset(message, 3 + has_lod);
-      emit(MOV(msg_ref, shadow_c));
+      bld.MOV(msg_ref, shadow_c);
       msg_end = offset(msg_ref, 1);
    }
 
@@ -1674,7 +1674,7 @@ fs_visitor::emit_texture_gen4_simd16(ir_texture_opcode op, fs_reg dst,
    default: unreachable("not reached");
    }
 
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
    inst->base_mrf = message.reg - 1;
    inst->mlen = msg_end.reg - inst->base_mrf;
    inst->header_size = 1;
@@ -1714,7 +1714,7 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
    }
 
    for (int i = 0; i < vector_elements; i++) {
-      emit(MOV(retype(offset(msg_coords, i), coordinate.type), coordinate));
+      bld.MOV(retype(offset(msg_coords, i), coordinate.type), coordinate);
       coordinate = offset(coordinate, 1);
    }
    fs_reg msg_end = offset(msg_coords, vector_elements);
@@ -1722,7 +1722,7 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
 
    if (shadow_c.file != BAD_FILE) {
       fs_reg msg_shadow = msg_lod;
-      emit(MOV(msg_shadow, shadow_c));
+      bld.MOV(msg_shadow, shadow_c);
       msg_lod = offset(msg_shadow, 1);
       msg_end = msg_lod;
    }
@@ -1733,13 +1733,13 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
       opcode = SHADER_OPCODE_TEX;
       break;
    case ir_txb:
-      emit(MOV(msg_lod, lod));
+      bld.MOV(msg_lod, lod);
       msg_end = offset(msg_lod, 1);
 
       opcode = FS_OPCODE_TXB;
       break;
    case ir_txl:
-      emit(MOV(msg_lod, lod));
+      bld.MOV(msg_lod, lod);
       msg_end = offset(msg_lod, 1);
 
       opcode = SHADER_OPCODE_TXL;
@@ -1756,11 +1756,11 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
        */
       msg_end = msg_lod;
       for (int i = 0; i < grad_components; i++) {
-         emit(MOV(msg_end, lod));
+         bld.MOV(msg_end, lod);
          lod = offset(lod, 1);
          msg_end = offset(msg_end, 1);
 
-         emit(MOV(msg_end, lod2));
+         bld.MOV(msg_end, lod2);
          lod2 = offset(lod2, 1);
          msg_end = offset(msg_end, 1);
       }
@@ -1770,21 +1770,21 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
    }
    case ir_txs:
       msg_lod = retype(msg_end, BRW_REGISTER_TYPE_UD);
-      emit(MOV(msg_lod, lod));
+      bld.MOV(msg_lod, lod);
       msg_end = offset(msg_lod, 1);
 
       opcode = SHADER_OPCODE_TXS;
       break;
    case ir_query_levels:
       msg_lod = msg_end;
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u));
       msg_end = offset(msg_lod, 1);
 
       opcode = SHADER_OPCODE_TXS;
       break;
    case ir_txf:
       msg_lod = offset(msg_coords, 3);
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), lod));
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), lod);
       msg_end = offset(msg_lod, 1);
 
       opcode = SHADER_OPCODE_TXF;
@@ -1792,9 +1792,9 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
    case ir_txf_ms:
       msg_lod = offset(msg_coords, 3);
       /* lod */
-      emit(MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u)));
+      bld.MOV(retype(msg_lod, BRW_REGISTER_TYPE_UD), fs_reg(0u));
       /* sample index */
-      emit(MOV(retype(offset(msg_lod, 1), BRW_REGISTER_TYPE_UD), sample_index));
+      bld.MOV(retype(offset(msg_lod, 1), BRW_REGISTER_TYPE_UD), sample_index);
       msg_end = offset(msg_lod, 2);
 
       opcode = SHADER_OPCODE_TXF_CMS;
@@ -1809,7 +1809,7 @@ fs_visitor::emit_texture_gen5(ir_texture_opcode op, fs_reg dst,
       unreachable("not reached");
    }
 
-   fs_inst *inst = emit(opcode, dst, reg_undef, fs_reg(sampler));
+   fs_inst *inst = bld.emit(opcode, dst, reg_undef, fs_reg(sampler));
    inst->base_mrf = message.reg;
    inst->mlen = msg_end.reg - message.reg;
    inst->header_size = header_size;
@@ -1867,7 +1867,7 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
    }
 
    if (shadow_c.file != BAD_FILE) {
-      emit(MOV(sources[length], shadow_c));
+      bld.MOV(sources[length], shadow_c);
       length++;
    }
 
@@ -1890,11 +1890,11 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
    case ir_lod:
       break;
    case ir_txb:
-      emit(MOV(sources[length], lod));
+      bld.MOV(sources[length], lod);
       length++;
       break;
    case ir_txl:
-      emit(MOV(sources[length], lod));
+      bld.MOV(sources[length], lod);
       length++;
       break;
    case ir_txd: {
@@ -1904,7 +1904,7 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
        * [hdr], [ref], x, dPdx.x, dPdy.x, y, dPdx.y, dPdy.y, z, dPdx.z, dPdy.z
        */
       for (int i = 0; i < coord_components; i++) {
-	 emit(MOV(sources[length], coordinate));
+	 bld.MOV(sources[length], coordinate);
 	 coordinate = offset(coordinate, 1);
 	 length++;
 
@@ -1912,11 +1912,11 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
           * only derivatives for (u, v, r).
           */
          if (i < grad_components) {
-            emit(MOV(sources[length], lod));
+            bld.MOV(sources[length], lod);
             lod = offset(lod, 1);
             length++;
 
-            emit(MOV(sources[length], lod2));
+            bld.MOV(sources[length], lod2);
             lod2 = offset(lod2, 1);
             length++;
          }
@@ -1926,11 +1926,11 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
       break;
    }
    case ir_txs:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), lod));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), lod);
       length++;
       break;
    case ir_query_levels:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), fs_reg(0u)));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), fs_reg(0u));
       length++;
       break;
    case ir_txf:
@@ -1938,23 +1938,23 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
        * On Gen9 they are u, v, lod, r
        */
 
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
       coordinate = offset(coordinate, 1);
       length++;
 
       if (devinfo->gen >= 9) {
          if (coord_components >= 2) {
-            emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
+            bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
             coordinate = offset(coordinate, 1);
          }
          length++;
       }
 
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), lod));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), lod);
       length++;
 
       for (int i = devinfo->gen >= 9 ? 2 : 1; i < coord_components; i++) {
-	 emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
+	 bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
 	 coordinate = offset(coordinate, 1);
 	 length++;
       }
@@ -1962,18 +1962,18 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
       coordinate_done = true;
       break;
    case ir_txf_ms:
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), sample_index));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), sample_index);
       length++;
 
       /* data from the multisample control surface */
-      emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), mcs));
+      bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_UD), mcs);
       length++;
 
       /* there is no offsetting for this message; just copy in the integer
        * texture coordinates
        */
       for (int i = 0; i < coord_components; i++) {
-         emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate));
+         bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), coordinate);
          coordinate = offset(coordinate, 1);
          length++;
       }
@@ -1987,19 +1987,19 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
 
          /* More crazy intermixing */
          for (int i = 0; i < 2; i++) { /* u, v */
-            emit(MOV(sources[length], coordinate));
+            bld.MOV(sources[length], coordinate);
             coordinate = offset(coordinate, 1);
             length++;
          }
 
          for (int i = 0; i < 2; i++) { /* offu, offv */
-            emit(MOV(retype(sources[length], BRW_REGISTER_TYPE_D), offset_value));
+            bld.MOV(retype(sources[length], BRW_REGISTER_TYPE_D), offset_value);
             offset_value = offset(offset_value, 1);
             length++;
          }
 
          if (coord_components == 3) { /* r if present */
-            emit(MOV(sources[length], coordinate));
+            bld.MOV(sources[length], coordinate);
             coordinate = offset(coordinate, 1);
             length++;
          }
@@ -2012,7 +2012,7 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
    /* Set up the coordinate (except for cases where it was done above) */
    if (!coordinate_done) {
       for (int i = 0; i < coord_components; i++) {
-         emit(MOV(sources[length], coordinate));
+         bld.MOV(sources[length], coordinate);
          coordinate = offset(coordinate, 1);
          length++;
       }
@@ -2026,7 +2026,7 @@ fs_visitor::emit_texture_gen7(ir_texture_opcode op, fs_reg dst,
 
    fs_reg src_payload = fs_reg(GRF, alloc.allocate(mlen),
                                BRW_REGISTER_TYPE_F, dispatch_width);
-   emit(LOAD_PAYLOAD(src_payload, sources, length, header_size));
+   bld.LOAD_PAYLOAD(src_payload, sources, length, header_size);
 
    /* Generate the SEND */
    enum opcode opcode;
@@ -2126,10 +2126,10 @@ fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
       fs_reg src = coordinate;
       coordinate = dst;
 
-      emit(MUL(dst, src, scale_x));
+      bld.MUL(dst, src, scale_x);
       dst = offset(dst, 1);
       src = offset(src, 1);
-      emit(MUL(dst, src, scale_y));
+      bld.MUL(dst, src, scale_y);
    } else if (is_rect) {
       /* On gen6+, the sampler handles the rectangle coordinates
        * natively, without needing rescaling.  But that means we have
@@ -2143,7 +2143,7 @@ fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
 	    fs_reg chan = coordinate;
 	    chan = offset(chan, i);
 
-	    inst = emit(BRW_OPCODE_SEL, chan, chan, fs_reg(0.0f));
+	    inst = bld.emit(BRW_OPCODE_SEL, chan, chan, fs_reg(0.0f));
 	    inst->conditional_mod = BRW_CONDITIONAL_GE;
 
 	    /* Our parameter comes in as 1.0/width or 1.0/height,
@@ -2153,10 +2153,10 @@ fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
 	     * parameter type, so just invert back.
 	     */
 	    fs_reg limit = vgrf(glsl_type::float_type);
-	    emit(MOV(limit, i == 0 ? scale_x : scale_y));
-	    emit(SHADER_OPCODE_RCP, limit, limit);
+	    bld.MOV(limit, i == 0 ? scale_x : scale_y);
+	    bld.emit(SHADER_OPCODE_RCP, limit, limit);
 
-	    inst = emit(BRW_OPCODE_SEL, chan, chan, limit);
+	    inst = bld.emit(BRW_OPCODE_SEL, chan, chan, limit);
 	    inst->conditional_mod = BRW_CONDITIONAL_L;
 	 }
       }
@@ -2168,7 +2168,7 @@ fs_visitor::rescale_texcoord(fs_reg coordinate, int coord_components,
 	    fs_reg chan = coordinate;
 	    chan = offset(chan, i);
 
-	    fs_inst *inst = emit(MOV(chan, chan));
+	    fs_inst *inst = bld.MOV(chan, chan);
 	    inst->saturate = true;
 	 }
       }
@@ -2189,11 +2189,11 @@ fs_visitor::emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler)
    /* parameters are: u, v, r; missing parameters are treated as zero */
    for (int i = 0; i < components; i++) {
       sources[i] = vgrf(glsl_type::float_type);
-      emit(MOV(retype(sources[i], BRW_REGISTER_TYPE_D), coordinate));
+      bld.MOV(retype(sources[i], BRW_REGISTER_TYPE_D), coordinate);
       coordinate = offset(coordinate, 1);
    }
 
-   emit(LOAD_PAYLOAD(payload, sources, components, 0));
+   bld.LOAD_PAYLOAD(payload, sources, components, 0);
 
    fs_inst *inst = emit(SHADER_OPCODE_TXF_MCS, dest, payload, sampler);
    inst->base_mrf = -1;
@@ -2235,7 +2235,7 @@ fs_visitor::emit_texture(ir_texture_opcode op,
          this->result = res;
 
          for (int i=0; i<4; i++) {
-            emit(MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f)));
+            bld.MOV(res, fs_reg(swiz == SWIZZLE_ZERO ? 0.0f : 1.0f));
             res = offset(res, 1);
          }
          return;
@@ -2303,7 +2303,7 @@ fs_visitor::emit_texture(ir_texture_opcode op,
             fixed_payload[i] = offset(dst, i);
          }
       }
-      emit(LOAD_PAYLOAD(dst, fixed_payload, components, 0));
+      bld.LOAD_PAYLOAD(dst, fixed_payload, components, 0);
    }
 
    swizzle_result(op, dest_type->vector_elements, dst, sampler);
@@ -2340,7 +2340,7 @@ fs_visitor::visit(ir_texture *ir)
       /* Emit code to evaluate the actual indexing expression */
       nonconst_sampler_index->accept(this);
       fs_reg temp = vgrf(glsl_type::uint_type);
-      emit(ADD(temp, this->result, fs_reg(sampler)));
+      bld.ADD(temp, this->result, fs_reg(sampler));
       emit_uniformize(temp, temp);
 
       sampler_reg = temp;
@@ -2473,16 +2473,16 @@ fs_visitor::emit_gen6_gather_wa(uint8_t wa, fs_reg dst)
    for (int i = 0; i < 4; i++) {
       fs_reg dst_f = retype(dst, BRW_REGISTER_TYPE_F);
       /* Convert from UNORM to UINT */
-      emit(MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1))));
-      emit(MOV(dst, dst_f));
+      bld.MUL(dst_f, dst_f, fs_reg((float)((1 << width) - 1)));
+      bld.MOV(dst, dst_f);
 
       if (wa & WA_SIGN) {
          /* Reinterpret the UINT value as a signed INT value by
           * shifting the sign bit into place, then shifting back
           * preserving sign.
           */
-         emit(SHL(dst, dst, fs_reg(32 - width)));
-         emit(ASR(dst, dst, fs_reg(32 - width)));
+         bld.SHL(dst, dst, fs_reg(32 - width));
+         bld.ASR(dst, dst, fs_reg(32 - width));
       }
 
       dst = offset(dst, 1);
@@ -2546,12 +2546,12 @@ fs_visitor::swizzle_result(ir_texture_opcode op, int dest_components,
 	 l = offset(l, i);
 
 	 if (swiz == SWIZZLE_ZERO) {
-	    emit(MOV(l, fs_reg(0.0f)));
+	    bld.MOV(l, fs_reg(0.0f));
 	 } else if (swiz == SWIZZLE_ONE) {
-	    emit(MOV(l, fs_reg(1.0f)));
+	    bld.MOV(l, fs_reg(1.0f));
 	 } else {
-            emit(MOV(l, offset(orig_val,
-                               GET_SWZ(key_tex->swizzles[sampler], i))));
+            bld.MOV(l, offset(orig_val,
+                               GET_SWZ(key_tex->swizzles[sampler], i)));
 	 }
       }
       this->result = swizzled_result;
@@ -2591,7 +2591,7 @@ fs_visitor::visit(ir_swizzle *ir)
 	 break;
       }
 
-      emit(MOV(result, offset(channel, swiz)));
+      bld.MOV(result, offset(channel, swiz));
       result = offset(result, 1);
    }
 }
@@ -2612,7 +2612,7 @@ fs_visitor::visit(ir_discard *ir)
    } else {
       fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
                                       BRW_REGISTER_TYPE_UW));
-      cmp = emit(CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ));
+      cmp = bld.CMP(reg_null_f, some_reg, some_reg, BRW_CONDITIONAL_NZ);
    }
    cmp->predicate = BRW_PREDICATE_NORMAL;
    cmp->flag_subreg = 1;
@@ -2644,7 +2644,7 @@ fs_visitor::visit(ir_constant *ir)
 
 	 dst_reg.type = src_reg.type;
 	 for (unsigned j = 0; j < size; j++) {
-	    emit(MOV(dst_reg, src_reg));
+	    bld.MOV(dst_reg, src_reg);
 	    src_reg = offset(src_reg, 1);
 	    dst_reg = offset(dst_reg, 1);
 	 }
@@ -2658,7 +2658,7 @@ fs_visitor::visit(ir_constant *ir)
 
 	 dst_reg.type = src_reg.type;
 	 for (unsigned j = 0; j < size; j++) {
-	    emit(MOV(dst_reg, src_reg));
+	    bld.MOV(dst_reg, src_reg);
 	    src_reg = offset(src_reg, 1);
 	    dst_reg = offset(dst_reg, 1);
 	 }
@@ -2669,16 +2669,16 @@ fs_visitor::visit(ir_constant *ir)
       for (unsigned i = 0; i < size; i++) {
 	 switch (ir->type->base_type) {
 	 case GLSL_TYPE_FLOAT:
-	    emit(MOV(dst_reg, fs_reg(ir->value.f[i])));
+	    bld.MOV(dst_reg, fs_reg(ir->value.f[i]));
 	    break;
 	 case GLSL_TYPE_UINT:
-	    emit(MOV(dst_reg, fs_reg(ir->value.u[i])));
+	    bld.MOV(dst_reg, fs_reg(ir->value.u[i]));
 	    break;
 	 case GLSL_TYPE_INT:
-	    emit(MOV(dst_reg, fs_reg(ir->value.i[i])));
+	    bld.MOV(dst_reg, fs_reg(ir->value.i[i]));
 	    break;
 	 case GLSL_TYPE_BOOL:
-            emit(MOV(dst_reg, fs_reg(ir->value.b[i] != 0 ? ~0 : 0)));
+            bld.MOV(dst_reg, fs_reg(ir->value.b[i] != 0 ? ~0 : 0));
 	    break;
 	 default:
 	    unreachable("Non-float/uint/int/bool constant");
@@ -2698,7 +2698,7 @@ fs_visitor::emit_bool_to_cond_code(ir_rvalue *ir)
    if (!expr || expr->operation == ir_binop_ubo_load) {
       ir->accept(this);
 
-      fs_inst *inst = emit(AND(reg_null_d, this->result, fs_reg(1)));
+      fs_inst *inst = bld.AND(reg_null_d, this->result, fs_reg(1));
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       return;
    }
@@ -2725,17 +2725,17 @@ fs_visitor::emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3])
 
    switch (expr->operation) {
    case ir_unop_logic_not:
-      inst = emit(AND(reg_null_d, op[0], fs_reg(1)));
+      inst = bld.AND(reg_null_d, op[0], fs_reg(1));
       inst->conditional_mod = BRW_CONDITIONAL_Z;
       break;
 
    case ir_binop_logic_xor:
       if (devinfo->gen <= 5) {
          fs_reg temp = vgrf(expr->type);
-         emit(XOR(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
+         bld.XOR(temp, op[0], op[1]);
+         inst = bld.AND(reg_null_d, temp, fs_reg(1));
       } else {
-         inst = emit(XOR(reg_null_d, op[0], op[1]));
+         inst = bld.XOR(reg_null_d, op[0], op[1]);
       }
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       break;
@@ -2743,10 +2743,10 @@ fs_visitor::emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3])
    case ir_binop_logic_or:
       if (devinfo->gen <= 5) {
          fs_reg temp = vgrf(expr->type);
-         emit(OR(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
+         bld.OR(temp, op[0], op[1]);
+         inst = bld.AND(reg_null_d, temp, fs_reg(1));
       } else {
-         inst = emit(OR(reg_null_d, op[0], op[1]));
+         inst = bld.OR(reg_null_d, op[0], op[1]);
       }
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       break;
@@ -2754,28 +2754,28 @@ fs_visitor::emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3])
    case ir_binop_logic_and:
       if (devinfo->gen <= 5) {
          fs_reg temp = vgrf(expr->type);
-         emit(AND(temp, op[0], op[1]));
-         inst = emit(AND(reg_null_d, temp, fs_reg(1)));
+         bld.AND(temp, op[0], op[1]);
+         inst = bld.AND(reg_null_d, temp, fs_reg(1));
       } else {
-         inst = emit(AND(reg_null_d, op[0], op[1]));
+         inst = bld.AND(reg_null_d, op[0], op[1]);
       }
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       break;
 
    case ir_unop_f2b:
       if (devinfo->gen >= 6) {
-         emit(CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ));
+         bld.CMP(reg_null_d, op[0], fs_reg(0.0f), BRW_CONDITIONAL_NZ);
       } else {
-         inst = emit(MOV(reg_null_f, op[0]));
+         inst = bld.MOV(reg_null_f, op[0]);
          inst->conditional_mod = BRW_CONDITIONAL_NZ;
       }
       break;
 
    case ir_unop_i2b:
       if (devinfo->gen >= 6) {
-         emit(CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
+         bld.CMP(reg_null_d, op[0], fs_reg(0), BRW_CONDITIONAL_NZ);
       } else {
-         inst = emit(MOV(reg_null_d, op[0]));
+         inst = bld.MOV(reg_null_d, op[0]);
          inst->conditional_mod = BRW_CONDITIONAL_NZ;
       }
       break;
@@ -2793,22 +2793,22 @@ fs_visitor::emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3])
          resolve_bool_comparison(expr->operands[1], &op[1]);
       }
 
-      emit(CMP(reg_null_d, op[0], op[1],
-               brw_conditional_for_comparison(expr->operation)));
+      bld.CMP(reg_null_d, op[0], op[1],
+               brw_conditional_for_comparison(expr->operation));
       break;
 
    case ir_triop_csel: {
       /* Expand the boolean condition into the flag register. */
-      inst = emit(MOV(reg_null_d, op[0]));
+      inst = bld.MOV(reg_null_d, op[0]);
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
 
       /* Select which boolean to return. */
       fs_reg temp = vgrf(expr->operands[1]->type);
-      inst = emit(SEL(temp, op[1], op[2]));
+      inst = bld.SEL(temp, op[1], op[2]);
       inst->predicate = BRW_PREDICATE_NORMAL;
 
       /* Expand the result to a condition code. */
-      inst = emit(MOV(reg_null_d, temp));
+      inst = bld.MOV(reg_null_d, temp);
       inst->conditional_mod = BRW_CONDITIONAL_NZ;
       break;
    }
@@ -2842,32 +2842,32 @@ fs_visitor::emit_if_gen6(ir_if *ir)
 
       switch (expr->operation) {
       case ir_unop_logic_not:
-         emit(IF(op[0], fs_reg(0), BRW_CONDITIONAL_Z));
+         bld.IF(op[0], fs_reg(0), BRW_CONDITIONAL_Z);
          return;
 
       case ir_binop_logic_xor:
-         emit(IF(op[0], op[1], BRW_CONDITIONAL_NZ));
+         bld.IF(op[0], op[1], BRW_CONDITIONAL_NZ);
          return;
 
       case ir_binop_logic_or:
          temp = vgrf(glsl_type::bool_type);
-         emit(OR(temp, op[0], op[1]));
-         emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
+         bld.OR(temp, op[0], op[1]);
+         bld.IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ);
          return;
 
       case ir_binop_logic_and:
          temp = vgrf(glsl_type::bool_type);
-         emit(AND(temp, op[0], op[1]));
-         emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
+         bld.AND(temp, op[0], op[1]);
+         bld.IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ);
          return;
 
       case ir_unop_f2b:
-	 inst = emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
+	 inst = bld.emit(BRW_OPCODE_IF, reg_null_f, op[0], fs_reg(0));
 	 inst->conditional_mod = BRW_CONDITIONAL_NZ;
 	 return;
 
       case ir_unop_i2b:
-	 emit(IF(op[0], fs_reg(0), BRW_CONDITIONAL_NZ));
+	 bld.IF(op[0], fs_reg(0), BRW_CONDITIONAL_NZ);
 	 return;
 
       case ir_binop_greater:
@@ -2883,21 +2883,21 @@ fs_visitor::emit_if_gen6(ir_if *ir)
             resolve_bool_comparison(expr->operands[1], &op[1]);
          }
 
-	 emit(IF(op[0], op[1],
-                 brw_conditional_for_comparison(expr->operation)));
+	 bld.IF(op[0], op[1],
+                 brw_conditional_for_comparison(expr->operation));
 	 return;
 
       case ir_triop_csel: {
          /* Expand the boolean condition into the flag register. */
-         fs_inst *inst = emit(MOV(reg_null_d, op[0]));
+         fs_inst *inst = bld.MOV(reg_null_d, op[0]);
          inst->conditional_mod = BRW_CONDITIONAL_NZ;
 
          /* Select which boolean to use as the result. */
          fs_reg temp = vgrf(expr->operands[1]->type);
-         inst = emit(SEL(temp, op[1], op[2]));
+         inst = bld.SEL(temp, op[1], op[2]);
          inst->predicate = BRW_PREDICATE_NORMAL;
 
-	 emit(IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ));
+	 bld.IF(temp, fs_reg(0), BRW_CONDITIONAL_NZ);
 	 return;
       }
 
@@ -2907,7 +2907,7 @@ fs_visitor::emit_if_gen6(ir_if *ir)
    }
 
    ir->condition->accept(this);
-   emit(IF(this->result, fs_reg(0), BRW_CONDITIONAL_NZ));
+   bld.IF(this->result, fs_reg(0), BRW_CONDITIONAL_NZ);
 }
 
 bool
@@ -2969,7 +2969,7 @@ fs_visitor::try_opt_frontfacing_ternary(ir_if *ir)
          tmp.subreg_offset = 2;
          tmp.stride = 2;
 
-         fs_inst *or_inst = emit(OR(tmp, g0, fs_reg(0x3f80)));
+         fs_inst *or_inst = bld.OR(tmp, g0, fs_reg(0x3f80));
          or_inst->src[1].type = BRW_REGISTER_TYPE_UW;
 
          tmp.type = BRW_REGISTER_TYPE_D;
@@ -2992,9 +2992,9 @@ fs_visitor::try_opt_frontfacing_ternary(ir_if *ir)
             g1_6.negate = true;
          }
 
-         emit(OR(tmp, g1_6, fs_reg(0x3f800000)));
+         bld.OR(tmp, g1_6, fs_reg(0x3f800000));
       }
-      emit(AND(dst, tmp, fs_reg(0xbf800000)));
+      bld.AND(dst, tmp, fs_reg(0xbf800000));
       return true;
    }
 
@@ -3067,19 +3067,19 @@ fs_visitor::try_replace_with_sel()
       if (src0.file == IMM) {
          src0 = vgrf(glsl_type::float_type);
          src0.type = then_mov->src[0].type;
-         emit(MOV(src0, then_mov->src[0]));
+         bld.MOV(src0, then_mov->src[0]);
       }
 
       fs_inst *sel;
       if (if_inst->conditional_mod) {
          /* Sandybridge-specific IF with embedded comparison */
-         emit(CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
-                  if_inst->conditional_mod));
-         sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
+         bld.CMP(reg_null_d, if_inst->src[0], if_inst->src[1],
+                  if_inst->conditional_mod);
+         sel = bld.emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
          sel->predicate = BRW_PREDICATE_NORMAL;
       } else {
          /* Separate CMP and IF instructions */
-         sel = emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
+         sel = bld.emit(BRW_OPCODE_SEL, then_mov->dst, src0, else_mov->src[0]);
          sel->predicate = if_inst->predicate;
          sel->predicate_inverse = if_inst->predicate_inverse;
       }
@@ -3106,7 +3106,7 @@ fs_visitor::visit(ir_if *ir)
    } else {
       emit_bool_to_cond_code(ir->condition);
 
-      emit(IF(BRW_PREDICATE_NORMAL));
+      bld.IF(BRW_PREDICATE_NORMAL);
    }
 
    foreach_in_list(ir_instruction, ir_, &ir->then_instructions) {
@@ -3115,7 +3115,7 @@ fs_visitor::visit(ir_if *ir)
    }
 
    if (!ir->else_instructions.is_empty()) {
-      emit(BRW_OPCODE_ELSE);
+      bld.emit(BRW_OPCODE_ELSE);
 
       foreach_in_list(ir_instruction, ir_, &ir->else_instructions) {
 	 this->base_ir = ir_;
@@ -3123,7 +3123,7 @@ fs_visitor::visit(ir_if *ir)
       }
    }
 
-   emit(BRW_OPCODE_ENDIF);
+   bld.emit(BRW_OPCODE_ENDIF);
 
    if (!try_replace_with_sel() && devinfo->gen < 6) {
       no16("Can't support (non-uniform) control flow on SIMD16\n");
@@ -3138,7 +3138,7 @@ fs_visitor::visit(ir_loop *ir)
    }
 
    this->base_ir = NULL;
-   emit(BRW_OPCODE_DO);
+   bld.emit(BRW_OPCODE_DO);
 
    foreach_in_list(ir_instruction, ir_, &ir->body_instructions) {
       this->base_ir = ir_;
@@ -3146,7 +3146,7 @@ fs_visitor::visit(ir_loop *ir)
    }
 
    this->base_ir = NULL;
-   emit(BRW_OPCODE_WHILE);
+   bld.emit(BRW_OPCODE_WHILE);
 }
 
 void
@@ -3154,10 +3154,10 @@ fs_visitor::visit(ir_loop_jump *ir)
 {
    switch (ir->mode) {
    case ir_loop_jump::jump_break:
-      emit(BRW_OPCODE_BREAK);
+      bld.emit(BRW_OPCODE_BREAK);
       break;
    case ir_loop_jump::jump_continue:
-      emit(BRW_OPCODE_CONTINUE);
+      bld.emit(BRW_OPCODE_CONTINUE);
       break;
    }
 }
@@ -3200,10 +3200,6 @@ void
 fs_visitor::visit(ir_call *ir)
 {
    const char *callee = ir->callee->function_name();
-   const bool uses_kill = (stage == MESA_SHADER_FRAGMENT &&
-                           ((brw_wm_prog_data *)prog_data)->uses_kill);
-   fs_builder bld(devinfo, mem_ctx, alloc, instructions, dispatch_width,
-                  stage, uses_kill);
 
    bld.set_annotation(current_annotation);
    bld.set_base_ir(base_ir);
@@ -3281,7 +3277,7 @@ fs_visitor::emit(exec_list list)
 {
    foreach_in_list_safe(fs_inst, inst, &list) {
       inst->exec_node::remove();
-      emit(inst);
+      bld.emit(inst);
    }
 }
 
@@ -3294,12 +3290,12 @@ fs_visitor::emit_dummy_fs()
    /* Everyone's favorite color. */
    const float color[4] = { 1.0, 0.0, 1.0, 0.0 };
    for (int i = 0; i < 4; i++) {
-      emit(MOV(fs_reg(MRF, 2 + i * reg_width, BRW_REGISTER_TYPE_F,
-                      dispatch_width), fs_reg(color[i])));
+      bld.MOV(fs_reg(MRF, 2 + i * reg_width, BRW_REGISTER_TYPE_F,
+                      dispatch_width), fs_reg(color[i]));
    }
 
    fs_inst *write;
-   write = emit(FS_OPCODE_FB_WRITE);
+   write = bld.emit(FS_OPCODE_FB_WRITE);
    write->eot = true;
    if (devinfo->gen >= 6) {
       write->base_mrf = 2;
@@ -3357,12 +3353,12 @@ fs_visitor::emit_interpolation_setup_gen4()
    this->pixel_y = vgrf(glsl_type::uint_type);
    this->pixel_x.type = BRW_REGISTER_TYPE_UW;
    this->pixel_y.type = BRW_REGISTER_TYPE_UW;
-   emit(ADD(this->pixel_x,
+   bld.ADD(this->pixel_x,
             fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
-            fs_reg(brw_imm_v(0x10101010))));
-   emit(ADD(this->pixel_y,
+            fs_reg(brw_imm_v(0x10101010)));
+   bld.ADD(this->pixel_y,
             fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
-            fs_reg(brw_imm_v(0x11001100))));
+            fs_reg(brw_imm_v(0x11001100)));
 
    this->current_annotation = "compute pixel deltas from v0";
 
@@ -3373,15 +3369,15 @@ fs_visitor::emit_interpolation_setup_gen4()
    const fs_reg ystart(negate(brw_vec1_grf(1, 1)));
 
    if (devinfo->has_pln && dispatch_width == 16) {
-      emit(ADD(half(offset(delta_xy, 0), 0), half(this->pixel_x, 0), xstart));
-      emit(ADD(half(offset(delta_xy, 0), 1), half(this->pixel_y, 0), ystart));
-      emit(ADD(half(offset(delta_xy, 1), 0), half(this->pixel_x, 1), xstart))
+      bld.ADD(half(offset(delta_xy, 0), 0), half(this->pixel_x, 0), xstart);
+      bld.ADD(half(offset(delta_xy, 0), 1), half(this->pixel_y, 0), ystart);
+      bld.ADD(half(offset(delta_xy, 1), 0), half(this->pixel_x, 1), xstart)
          ->force_sechalf = true;
-      emit(ADD(half(offset(delta_xy, 1), 1), half(this->pixel_y, 1), ystart))
+      bld.ADD(half(offset(delta_xy, 1), 1), half(this->pixel_y, 1), ystart)
          ->force_sechalf = true;
    } else {
-      emit(ADD(offset(delta_xy, 0), this->pixel_x, xstart));
-      emit(ADD(offset(delta_xy, 1), this->pixel_y, ystart));
+      bld.ADD(offset(delta_xy, 0), this->pixel_x, xstart);
+      bld.ADD(offset(delta_xy, 1), this->pixel_y, ystart);
    }
 
    this->current_annotation = "compute pos.w and 1/pos.w";
@@ -3389,7 +3385,7 @@ fs_visitor::emit_interpolation_setup_gen4()
     * interpolate the other attributes.
     */
    this->wpos_w = vgrf(glsl_type::float_type);
-   emit(FS_OPCODE_LINTERP, wpos_w, delta_xy, interp_reg(VARYING_SLOT_POS, 3));
+   bld.emit(FS_OPCODE_LINTERP, wpos_w, delta_xy, interp_reg(VARYING_SLOT_POS, 3));
    /* Compute the pixel 1/W value from wpos.w. */
    this->pixel_w = vgrf(glsl_type::float_type);
    emit_math(SHADER_OPCODE_RCP, this->pixel_w, wpos_w);
@@ -3423,8 +3419,8 @@ fs_visitor::emit_interpolation_setup_gen6()
 
       this->pixel_x = vgrf(glsl_type::float_type);
       this->pixel_y = vgrf(glsl_type::float_type);
-      emit(FS_OPCODE_PIXEL_X, this->pixel_x, int_pixel_xy);
-      emit(FS_OPCODE_PIXEL_Y, this->pixel_y, int_pixel_xy);
+      bld.emit(FS_OPCODE_PIXEL_X, this->pixel_x, int_pixel_xy);
+      bld.emit(FS_OPCODE_PIXEL_Y, this->pixel_y, int_pixel_xy);
    } else {
       /* The "Register Region Restrictions" page says for SNB, IVB, HSW:
        *
@@ -3438,12 +3434,12 @@ fs_visitor::emit_interpolation_setup_gen6()
       fs_reg int_pixel_y = vgrf(glsl_type::uint_type);
       int_pixel_x.type = BRW_REGISTER_TYPE_UW;
       int_pixel_y.type = BRW_REGISTER_TYPE_UW;
-      emit(ADD(int_pixel_x,
+      bld.ADD(int_pixel_x,
                fs_reg(stride(suboffset(g1_uw, 4), 2, 4, 0)),
-               fs_reg(brw_imm_v(0x10101010))));
-      emit(ADD(int_pixel_y,
+               fs_reg(brw_imm_v(0x10101010)));
+      bld.ADD(int_pixel_y,
                fs_reg(stride(suboffset(g1_uw, 5), 2, 4, 0)),
-               fs_reg(brw_imm_v(0x11001100))));
+               fs_reg(brw_imm_v(0x11001100)));
 
       /* As of gen6, we can no longer mix float and int sources.  We have
        * to turn the integer pixel centers into floats for their actual
@@ -3451,8 +3447,8 @@ fs_visitor::emit_interpolation_setup_gen6()
        */
       this->pixel_x = vgrf(glsl_type::float_type);
       this->pixel_y = vgrf(glsl_type::float_type);
-      emit(MOV(this->pixel_x, int_pixel_x));
-      emit(MOV(this->pixel_y, int_pixel_y));
+      bld.MOV(this->pixel_x, int_pixel_x);
+      bld.MOV(this->pixel_y, int_pixel_y);
    }
 
    this->current_annotation = "compute pos.w";
@@ -3479,7 +3475,7 @@ fs_visitor::setup_color_payload(fs_reg *dst, fs_reg color, unsigned components,
       fs_reg tmp = vgrf(glsl_type::vec4_type);
       assert(color.type == BRW_REGISTER_TYPE_F);
       for (unsigned i = 0; i < components; i++) {
-         inst = emit(MOV(offset(tmp, i), offset(color, i)));
+         inst = bld.MOV(offset(tmp, i), offset(color, i));
          inst->saturate = true;
       }
       color = tmp;
@@ -3535,15 +3531,15 @@ fs_visitor::emit_alpha_test()
       /* f0.1 = 0 */
       fs_reg some_reg = fs_reg(retype(brw_vec8_grf(0, 0),
                                       BRW_REGISTER_TYPE_UW));
-      cmp = emit(CMP(reg_null_f, some_reg, some_reg,
-                     BRW_CONDITIONAL_NEQ));
+      cmp = bld.CMP(reg_null_f, some_reg, some_reg,
+                     BRW_CONDITIONAL_NEQ);
    } else {
       /* RT0 alpha */
       fs_reg color = offset(outputs[0], 3);
 
       /* f0.1 &= func(color, ref) */
-      cmp = emit(CMP(reg_null_f, color, fs_reg(key->alpha_test_ref),
-                     cond_for_alpha_func(key->alpha_test_func)));
+      cmp = bld.CMP(reg_null_f, color, fs_reg(key->alpha_test_ref),
+                     cond_for_alpha_func(key->alpha_test_func));
    }
    cmp->predicate = BRW_PREDICATE_NORMAL;
    cmp->flag_subreg = 1;
@@ -3589,8 +3585,8 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
 
    if (payload.aa_dest_stencil_reg) {
       sources[length] = fs_reg(GRF, alloc.allocate(1));
-      emit(MOV(sources[length],
-               fs_reg(brw_vec8_grf(payload.aa_dest_stencil_reg, 0))));
+      bld.MOV(sources[length],
+               fs_reg(brw_vec8_grf(payload.aa_dest_stencil_reg, 0)));
       length++;
    }
 
@@ -3604,7 +3600,7 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
        */
       sources[length] = fs_reg(GRF, alloc.allocate(1),
                                BRW_REGISTER_TYPE_UW, 16);
-      emit(FS_OPCODE_SET_OMASK, sources[length], this->sample_mask);
+      bld.emit(FS_OPCODE_SET_OMASK, sources[length], this->sample_mask);
       length++;
    }
 
@@ -3666,15 +3662,15 @@ fs_visitor::emit_single_fb_write(fs_reg color0, fs_reg color1,
    if (devinfo->gen >= 7) {
       /* Send from the GRF */
       fs_reg payload = fs_reg(GRF, -1, BRW_REGISTER_TYPE_F, exec_size);
-      load = emit(LOAD_PAYLOAD(payload, sources, length, payload_header_size));
+      load = bld.LOAD_PAYLOAD(payload, sources, length, payload_header_size);
       payload.reg = alloc.allocate(load->regs_written);
       load->dst = payload;
       write = emit(FS_OPCODE_FB_WRITE, reg_undef, payload);
       write->base_mrf = -1;
    } else {
       /* Send from the MRF */
-      load = emit(LOAD_PAYLOAD(fs_reg(MRF, 1, BRW_REGISTER_TYPE_F, exec_size),
-                               sources, length, payload_header_size));
+      load = bld.LOAD_PAYLOAD(fs_reg(MRF, 1, BRW_REGISTER_TYPE_F, exec_size),
+                               sources, length, payload_header_size);
 
       /* On pre-SNB, we have to interlace the color values.  LOAD_PAYLOAD
        * will do this for us if we just give it a COMPR4 destination.
@@ -3828,10 +3824,10 @@ void fs_visitor::compute_clip_distance()
       fs_reg output = outputs[VARYING_SLOT_CLIP_DIST0 + i / 4];
       output.reg_offset = i & 3;
 
-      emit(MUL(output, outputs[clip_vertex], u));
+      bld.MUL(output, outputs[clip_vertex], u);
       for (int j = 1; j < 4; j++) {
          u.reg = userplane[i].reg + j;
-         emit(MAD(output, output, offset(outputs[clip_vertex], j), u));
+         bld.MAD(output, output, offset(outputs[clip_vertex], j), u);
       }
    }
 }
@@ -3859,11 +3855,11 @@ fs_visitor::emit_urb_writes()
    if (vue_map->slots_valid == 0) {
 
       fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-      fs_inst *inst = emit(MOV(payload, fs_reg(retype(brw_vec8_grf(1, 0),
-                                                      BRW_REGISTER_TYPE_UD))));
+      fs_inst *inst = bld.MOV(payload, fs_reg(retype(brw_vec8_grf(1, 0),
+                                                      BRW_REGISTER_TYPE_UD)));
       inst->force_writemask_all = true;
 
-      inst = emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
+      inst = bld.emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
       inst->eot = true;
       inst->mlen = 1;
       inst->offset = 1;
@@ -3892,7 +3888,7 @@ fs_visitor::emit_urb_writes()
          }
 
          zero = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-         emit(MOV(zero, fs_reg(0u)));
+         bld.MOV(zero, fs_reg(0u));
 
          sources[length++] = zero;
          if (vue_map->slots_valid & VARYING_BIT_LAYER)
@@ -3947,7 +3943,7 @@ fs_visitor::emit_urb_writes()
             for (int i = 0; i < 4; i++) {
                reg = fs_reg(GRF, alloc.allocate(1), outputs[varying].type);
                src = offset(this->outputs[varying], i);
-               fs_inst *inst = emit(MOV(reg, src));
+               fs_inst *inst = bld.MOV(reg, src);
                inst->saturate = true;
                sources[length++] = reg;
             }
@@ -3978,13 +3974,13 @@ fs_visitor::emit_urb_writes()
           */
          fs_reg dummy = fs_reg(GRF, alloc.allocate(1),
                                BRW_REGISTER_TYPE_UD);
-         fs_inst *inst = emit(MOV(dummy, fs_reg(retype(brw_vec8_grf(1, 0),
-                                                       BRW_REGISTER_TYPE_UD))));
+         fs_inst *inst = bld.MOV(dummy, fs_reg(retype(brw_vec8_grf(1, 0),
+                                                       BRW_REGISTER_TYPE_UD)));
          inst->force_writemask_all = true;
          payload_sources[0] = dummy;
 
          memcpy(&payload_sources[1], sources, length * sizeof sources[0]);
-         emit(LOAD_PAYLOAD(payload, payload_sources, length + 1, 1));
+         bld.LOAD_PAYLOAD(payload, payload_sources, length + 1, 1);
 
          inst = emit(SHADER_OPCODE_URB_WRITE_SIMD8, reg_undef, payload);
          inst->eot = last;
@@ -4005,7 +4001,7 @@ fs_visitor::resolve_ud_negate(fs_reg *reg)
       return;
 
    fs_reg temp = vgrf(glsl_type::uint_type);
-   emit(MOV(temp, *reg));
+   bld.MOV(temp, *reg);
    *reg = temp;
 }
 
@@ -4023,11 +4019,11 @@ fs_visitor::emit_cs_terminate()
     */
    struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD);
    fs_reg payload = fs_reg(GRF, alloc.allocate(1), BRW_REGISTER_TYPE_UD);
-   fs_inst *inst = emit(MOV(payload, g0));
+   fs_inst *inst = bld.MOV(payload, g0);
    inst->force_writemask_all = true;
 
    /* Send a message to the thread spawner to terminate the thread. */
-   inst = emit(CS_OPCODE_CS_TERMINATE, reg_undef, payload);
+   inst = bld.emit(CS_OPCODE_CS_TERMINATE, reg_undef, payload);
    inst->eot = true;
 }
 
@@ -4047,8 +4043,8 @@ fs_visitor::resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg)
 
    fs_reg and_result = vgrf(glsl_type::bool_type);
    fs_reg neg_result = vgrf(glsl_type::bool_type);
-   emit(AND(and_result, *reg, fs_reg(1)));
-   emit(MOV(neg_result, negate(and_result)));
+   bld.AND(and_result, *reg, fs_reg(1));
+   bld.MOV(neg_result, negate(and_result));
    *reg = neg_result;
 }
 
@@ -4065,7 +4061,10 @@ fs_visitor::fs_visitor(struct brw_context *brw,
      reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
      reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
      key(key), prog_data(&prog_data->base),
-     dispatch_width(dispatch_width), promoted_constants(0)
+     dispatch_width(dispatch_width), promoted_constants(0),
+     bld(devinfo, mem_ctx, alloc, instructions, dispatch_width, stage,
+         prog_data->uses_kill)
+
 {
    this->mem_ctx = mem_ctx;
    init();
@@ -4084,7 +4083,9 @@ fs_visitor::fs_visitor(struct brw_context *brw,
      reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
      reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
      key(key), prog_data(&prog_data->base.base),
-     dispatch_width(dispatch_width), promoted_constants(0)
+     dispatch_width(dispatch_width), promoted_constants(0),
+     bld(devinfo, mem_ctx, alloc, instructions, dispatch_width, stage, false)
+
 {
    this->mem_ctx = mem_ctx;
    init();
@@ -4103,7 +4104,8 @@ fs_visitor::fs_visitor(struct brw_context *brw,
      reg_null_d(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_D)),
      reg_null_ud(retype(brw_null_vec(dispatch_width), BRW_REGISTER_TYPE_UD)),
      key(key), prog_data(&prog_data->base),
-     dispatch_width(dispatch_width), promoted_constants(0)
+     dispatch_width(dispatch_width), promoted_constants(0),
+     bld(devinfo, mem_ctx, alloc, instructions, dispatch_width, stage, false)
 {
    this->mem_ctx = mem_ctx;
    init();

Attachment: signature.asc
Description: PGP signature

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to