radeonsi: replace si_shader_context::soa by bld_base
[mesa.git] / src / gallium / drivers / radeonsi / si_shader.c
index ff51c8bd799521272c783e27680ab2bf5841828e..d45c0e8649c87c90f387adbf97801c5da626a010 100644 (file)
 #include "gallivm/lp_bld_arit.h"
 #include "gallivm/lp_bld_flow.h"
 #include "gallivm/lp_bld_misc.h"
-#include "radeon/radeon_llvm.h"
 #include "radeon/radeon_elf_util.h"
-#include "radeon/radeon_llvm_emit.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
 #include "tgsi/tgsi_build.h"
 #include "tgsi/tgsi_util.h"
 #include "tgsi/tgsi_dump.h"
 
+#include "ac_llvm_util.h"
+#include "si_shader_internal.h"
 #include "si_pipe.h"
 #include "sid.h"
 
@@ -55,81 +55,11 @@ static const char *scratch_rsrc_dword1_symbol =
 struct si_shader_output_values
 {
        LLVMValueRef values[4];
-       unsigned name;
-       unsigned sid;
+       unsigned semantic_name;
+       unsigned semantic_index;
+       ubyte vertex_stream[4];
 };
 
-struct si_shader_context
-{
-       struct radeon_llvm_context radeon_bld;
-       struct si_shader *shader;
-       struct si_screen *screen;
-
-       unsigned type; /* PIPE_SHADER_* specifies the type of shader. */
-       bool is_gs_copy_shader;
-
-       /* Whether to generate the optimized shader variant compiled as a whole
-        * (without a prolog and epilog)
-        */
-       bool is_monolithic;
-
-       int param_streamout_config;
-       int param_streamout_write_index;
-       int param_streamout_offset[4];
-       int param_vertex_id;
-       int param_rel_auto_id;
-       int param_vs_prim_id;
-       int param_instance_id;
-       int param_vertex_index0;
-       int param_tes_u;
-       int param_tes_v;
-       int param_tes_rel_patch_id;
-       int param_tes_patch_id;
-       int param_es2gs_offset;
-       int param_oc_lds;
-
-       /* Sets a bit if the dynamic HS control word was 0x80000000. The bit is
-        * 0x800000 for VS, 0x1 for ES.
-        */
-       int param_tess_offchip;
-
-       LLVMTargetMachineRef tm;
-
-       unsigned invariant_load_md_kind;
-       unsigned range_md_kind;
-       unsigned uniform_md_kind;
-       LLVMValueRef empty_md;
-
-       /* Preloaded descriptors. */
-       LLVMValueRef esgs_ring;
-       LLVMValueRef gsvs_ring[4];
-
-       LLVMValueRef lds;
-       LLVMValueRef gs_next_vertex[4];
-       LLVMValueRef return_value;
-
-       LLVMTypeRef voidt;
-       LLVMTypeRef i1;
-       LLVMTypeRef i8;
-       LLVMTypeRef i32;
-       LLVMTypeRef i64;
-       LLVMTypeRef i128;
-       LLVMTypeRef f32;
-       LLVMTypeRef v16i8;
-       LLVMTypeRef v2i32;
-       LLVMTypeRef v4i32;
-       LLVMTypeRef v4f32;
-       LLVMTypeRef v8i32;
-
-       LLVMValueRef shared_memory;
-};
-
-static struct si_shader_context *si_shader_context(
-       struct lp_build_tgsi_context *bld_base)
-{
-       return (struct si_shader_context *)bld_base;
-}
-
 static void si_init_shader_ctx(struct si_shader_context *ctx,
                               struct si_screen *sscreen,
                               struct si_shader *shader,
@@ -139,9 +69,20 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
                                 struct lp_build_tgsi_context *bld_base,
                                 struct lp_build_emit_data *emit_data);
 
-static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
+static void si_dump_shader_key(unsigned shader, struct si_shader_key *key,
                               FILE *f);
 
+static void si_build_vs_prolog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key);
+static void si_build_vs_epilog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key);
+static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
+                                        union si_shader_part_key *key);
+static void si_build_ps_prolog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key);
+static void si_build_ps_epilog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key);
+
 /* Ideally pass the sample mask input to the PS epilog as v13, which
  * is its usual location, so that the shader doesn't have to add v_mov.
  */
@@ -183,11 +124,9 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
        case TGSI_SEMANTIC_GENERIC:
                if (index <= 63-4)
                        return 4 + index;
-               else
-                       /* same explanation as in the default statement,
-                        * the only user hitting this is st/nine.
-                        */
-                       return 0;
+
+               assert(!"invalid generic index");
+               return 0;
 
        /* patch indices are completely separate and thus start from 0 */
        case TGSI_SEMANTIC_TESSOUTER:
@@ -198,11 +137,29 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
                return 2 + index;
 
        default:
-               /* Don't fail here. The result of this function is only used
-                * for LS, TCS, TES, and GS, where legacy GL semantics can't
-                * occur, but this function is called for all vertex shaders
-                * before it's known whether LS will be compiled or not.
-                */
+               assert(!"invalid semantic name");
+               return 0;
+       }
+}
+
+unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index)
+{
+       switch (name) {
+       case TGSI_SEMANTIC_FOG:
+               return 0;
+       case TGSI_SEMANTIC_LAYER:
+               return 1;
+       case TGSI_SEMANTIC_VIEWPORT_INDEX:
+               return 2;
+       case TGSI_SEMANTIC_PRIMID:
+               return 3;
+       case TGSI_SEMANTIC_COLOR: /* these alias */
+       case TGSI_SEMANTIC_BCOLOR:
+               return 4 + index;
+       case TGSI_SEMANTIC_TEXCOORD:
+               return 6 + index;
+       default:
+               assert(!"invalid semantic name");
                return 0;
        }
 }
@@ -214,12 +171,12 @@ static LLVMValueRef unpack_param(struct si_shader_context *ctx,
                                 unsigned param, unsigned rshift,
                                 unsigned bitwidth)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
-       LLVMValueRef value = LLVMGetParam(ctx->radeon_bld.main_fn,
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       LLVMValueRef value = LLVMGetParam(ctx->main_fn,
                                          param);
 
        if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMFloatTypeKind)
-               value = bitcast(&ctx->radeon_bld.soa.bld_base,
+               value = bitcast(&ctx->bld_base,
                                TGSI_TYPE_UNSIGNED, value);
 
        if (rshift)
@@ -242,7 +199,7 @@ static LLVMValueRef get_rel_patch_id(struct si_shader_context *ctx)
                return unpack_param(ctx, SI_PARAM_REL_IDS, 0, 8);
 
        case PIPE_SHADER_TESS_EVAL:
-               return LLVMGetParam(ctx->radeon_bld.main_fn,
+               return LLVMGetParam(ctx->main_fn,
                                    ctx->param_tes_rel_patch_id);
 
        default:
@@ -294,7 +251,7 @@ get_tcs_out_patch_stride(struct si_shader_context *ctx)
 static LLVMValueRef
 get_tcs_out_patch0_offset(struct si_shader_context *ctx)
 {
-       return lp_build_mul_imm(&ctx->radeon_bld.soa.bld_base.uint_bld,
+       return lp_build_mul_imm(&ctx->bld_base.uint_bld,
                                unpack_param(ctx,
                                             SI_PARAM_TCS_OUT_OFFSETS,
                                             0, 16),
@@ -304,7 +261,7 @@ get_tcs_out_patch0_offset(struct si_shader_context *ctx)
 static LLVMValueRef
 get_tcs_out_patch0_patch_data_offset(struct si_shader_context *ctx)
 {
-       return lp_build_mul_imm(&ctx->radeon_bld.soa.bld_base.uint_bld,
+       return lp_build_mul_imm(&ctx->bld_base.uint_bld,
                                unpack_param(ctx,
                                             SI_PARAM_TCS_OUT_OFFSETS,
                                             16, 16),
@@ -314,7 +271,7 @@ get_tcs_out_patch0_patch_data_offset(struct si_shader_context *ctx)
 static LLVMValueRef
 get_tcs_in_current_patch_offset(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMValueRef patch_stride = get_tcs_in_patch_stride(ctx);
        LLVMValueRef rel_patch_id = get_rel_patch_id(ctx);
 
@@ -324,7 +281,7 @@ get_tcs_in_current_patch_offset(struct si_shader_context *ctx)
 static LLVMValueRef
 get_tcs_out_current_patch_offset(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMValueRef patch0_offset = get_tcs_out_patch0_offset(ctx);
        LLVMValueRef patch_stride = get_tcs_out_patch_stride(ctx);
        LLVMValueRef rel_patch_id = get_rel_patch_id(ctx);
@@ -338,7 +295,7 @@ get_tcs_out_current_patch_offset(struct si_shader_context *ctx)
 static LLVMValueRef
 get_tcs_out_current_patch_data_offset(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMValueRef patch0_patch_data_offset =
                get_tcs_out_patch0_patch_data_offset(ctx);
        LLVMValueRef patch_stride = get_tcs_out_patch_stride(ctx);
@@ -357,7 +314,7 @@ static LLVMValueRef build_gep0(struct si_shader_context *ctx,
                LLVMConstInt(ctx->i32, 0, 0),
                index,
        };
-       return LLVMBuildGEP(ctx->radeon_bld.gallivm.builder, base_ptr,
+       return LLVMBuildGEP(ctx->gallivm.builder, base_ptr,
                            indices, 2, "");
 }
 
@@ -365,7 +322,7 @@ static void build_indexed_store(struct si_shader_context *ctx,
                                LLVMValueRef base_ptr, LLVMValueRef index,
                                LLVMValueRef value)
 {
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
 
        LLVMBuildStore(gallivm->builder, value,
@@ -385,7 +342,7 @@ static LLVMValueRef build_indexed_load(struct si_shader_context *ctx,
                                       LLVMValueRef base_ptr, LLVMValueRef index,
                                       bool uniform)
 {
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMValueRef pointer;
 
@@ -409,12 +366,12 @@ static LLVMValueRef build_indexed_load_const(
 }
 
 static LLVMValueRef get_instance_index_for_fetch(
-       struct radeon_llvm_context *radeon_bld,
+       struct si_shader_context *radeon_bld,
        unsigned param_start_instance, unsigned divisor)
 {
        struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
-       struct gallivm_state *gallivm = radeon_bld->soa.bld_base.base.gallivm;
+               si_shader_context(&radeon_bld->bld_base);
+       struct gallivm_state *gallivm = radeon_bld->bld_base.base.gallivm;
 
        LLVMValueRef result = LLVMGetParam(radeon_bld->main_fn,
                                           ctx->param_instance_id);
@@ -429,19 +386,16 @@ static LLVMValueRef get_instance_index_for_fetch(
 }
 
 static void declare_input_vs(
-       struct radeon_llvm_context *radeon_bld,
+       struct si_shader_context *ctx,
        unsigned input_index,
        const struct tgsi_full_declaration *decl,
        LLVMValueRef out[4])
 {
-       struct lp_build_context *base = &radeon_bld->soa.bld_base.base;
+       struct lp_build_context *base = &ctx->bld_base.base;
        struct gallivm_state *gallivm = base->gallivm;
-       struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
-       unsigned divisor =
-               ctx->shader->key.vs.prolog.instance_divisors[input_index];
 
        unsigned chan;
+       unsigned fix_fetch;
 
        LLVMValueRef t_list_ptr;
        LLVMValueRef t_offset;
@@ -452,7 +406,7 @@ static void declare_input_vs(
        LLVMValueRef input;
 
        /* Load the T list */
-       t_list_ptr = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_VERTEX_BUFFERS);
+       t_list_ptr = LLVMGetParam(ctx->main_fn, SI_PARAM_VERTEX_BUFFERS);
 
        t_offset = lp_build_const_int32(gallivm, input_index);
 
@@ -461,31 +415,16 @@ static void declare_input_vs(
        /* Build the attribute offset */
        attribute_offset = lp_build_const_int32(gallivm, 0);
 
-       if (!ctx->is_monolithic) {
-               buffer_index = LLVMGetParam(radeon_bld->main_fn,
-                                           ctx->param_vertex_index0 +
-                                           input_index);
-       } else if (divisor) {
-               /* Build index from instance ID, start instance and divisor */
-               ctx->shader->info.uses_instanceid = true;
-               buffer_index = get_instance_index_for_fetch(&ctx->radeon_bld,
-                                                           SI_PARAM_START_INSTANCE,
-                                                           divisor);
-       } else {
-               /* Load the buffer index for vertices. */
-               LLVMValueRef vertex_id = LLVMGetParam(ctx->radeon_bld.main_fn,
-                                                     ctx->param_vertex_id);
-               LLVMValueRef base_vertex = LLVMGetParam(radeon_bld->main_fn,
-                                                       SI_PARAM_BASE_VERTEX);
-               buffer_index = LLVMBuildAdd(gallivm->builder, base_vertex, vertex_id, "");
-       }
+       buffer_index = LLVMGetParam(ctx->main_fn,
+                                   ctx->param_vertex_index0 +
+                                   input_index);
 
        args[0] = t_list;
        args[1] = attribute_offset;
        args[2] = buffer_index;
        input = lp_build_intrinsic(gallivm->builder,
                "llvm.SI.vs.load.input", ctx->v4f32, args, 3,
-               LLVMReadNoneAttribute);
+               LP_FUNC_ATTR_READNONE);
 
        /* Break up the vec4 into individual components */
        for (chan = 0; chan < 4; chan++) {
@@ -493,6 +432,45 @@ static void declare_input_vs(
                out[chan] = LLVMBuildExtractElement(gallivm->builder,
                                                    input, llvm_chan, "");
        }
+
+       fix_fetch = (ctx->shader->key.mono.vs.fix_fetch >> (2 * input_index)) & 3;
+       if (fix_fetch) {
+               /* The hardware returns an unsigned value; convert it to a
+                * signed one.
+                */
+               LLVMValueRef tmp = out[3];
+               LLVMValueRef c30 = LLVMConstInt(ctx->i32, 30, 0);
+
+               /* First, recover the sign-extended signed integer value. */
+               if (fix_fetch == SI_FIX_FETCH_A2_SSCALED)
+                       tmp = LLVMBuildFPToUI(gallivm->builder, tmp, ctx->i32, "");
+               else
+                       tmp = LLVMBuildBitCast(gallivm->builder, tmp, ctx->i32, "");
+
+               /* For the integer-like cases, do a natural sign extension.
+                *
+                * For the SNORM case, the values are 0.0, 0.333, 0.666, 1.0
+                * and happen to contain 0, 1, 2, 3 as the two LSBs of the
+                * exponent.
+                */
+               tmp = LLVMBuildShl(gallivm->builder, tmp,
+                                  fix_fetch == SI_FIX_FETCH_A2_SNORM ?
+                                  LLVMConstInt(ctx->i32, 7, 0) : c30, "");
+               tmp = LLVMBuildAShr(gallivm->builder, tmp, c30, "");
+
+               /* Convert back to the right type. */
+               if (fix_fetch == SI_FIX_FETCH_A2_SNORM) {
+                       LLVMValueRef clamp;
+                       LLVMValueRef neg_one = LLVMConstReal(ctx->f32, -1.0);
+                       tmp = LLVMBuildSIToFP(gallivm->builder, tmp, ctx->f32, "");
+                       clamp = LLVMBuildFCmp(gallivm->builder, LLVMRealULT, tmp, neg_one, "");
+                       tmp = LLVMBuildSelect(gallivm->builder, clamp, neg_one, tmp, "");
+               } else if (fix_fetch == SI_FIX_FETCH_A2_SSCALED) {
+                       tmp = LLVMBuildSIToFP(gallivm->builder, tmp, ctx->f32, "");
+               }
+
+               out[3] = tmp;
+       }
 }
 
 static LLVMValueRef get_primitive_id(struct lp_build_tgsi_context *bld_base,
@@ -505,16 +483,16 @@ static LLVMValueRef get_primitive_id(struct lp_build_tgsi_context *bld_base,
 
        switch (ctx->type) {
        case PIPE_SHADER_VERTEX:
-               return LLVMGetParam(ctx->radeon_bld.main_fn,
+               return LLVMGetParam(ctx->main_fn,
                                    ctx->param_vs_prim_id);
        case PIPE_SHADER_TESS_CTRL:
-               return LLVMGetParam(ctx->radeon_bld.main_fn,
+               return LLVMGetParam(ctx->main_fn,
                                    SI_PARAM_PATCH_ID);
        case PIPE_SHADER_TESS_EVAL:
-               return LLVMGetParam(ctx->radeon_bld.main_fn,
+               return LLVMGetParam(ctx->main_fn,
                                    ctx->param_tes_patch_id);
        case PIPE_SHADER_GEOMETRY:
-               return LLVMGetParam(ctx->radeon_bld.main_fn,
+               return LLVMGetParam(ctx->main_fn,
                                    SI_PARAM_PRIMITIVE_ID);
        default:
                assert(0);
@@ -530,10 +508,10 @@ static LLVMValueRef get_indirect_index(struct si_shader_context *ctx,
                                       const struct tgsi_ind_register *ind,
                                       int rel_index)
 {
-       struct gallivm_state *gallivm = ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
        LLVMValueRef result;
 
-       result = ctx->radeon_bld.soa.addr[ind->Index][ind->Swizzle];
+       result = ctx->addrs[ind->Index][ind->Swizzle];
        result = LLVMBuildLoad(gallivm->builder, result, "");
        result = LLVMBuildAdd(gallivm->builder, result,
                              lp_build_const_int32(gallivm, rel_index), "");
@@ -557,7 +535,7 @@ static LLVMValueRef get_bounded_indirect_index(struct si_shader_context *ctx,
        if (HAVE_LLVM <= 0x0308)
                return LLVMGetUndef(ctx->i32);
 
-       return radeon_llvm_bound_index(&ctx->radeon_bld, result, num);
+       return si_llvm_bound_index(ctx, result, num);
 }
 
 
@@ -570,7 +548,7 @@ static LLVMValueRef get_dw_address(struct si_shader_context *ctx,
                                   LLVMValueRef vertex_dw_stride,
                                   LLVMValueRef base_addr)
 {
-       struct gallivm_state *gallivm = ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
        ubyte *name, *index, *array_first;
        int first, param;
@@ -668,7 +646,7 @@ static LLVMValueRef get_tcs_tes_buffer_address(struct si_shader_context *ctx,
                                                LLVMValueRef vertex_index,
                                                LLVMValueRef param_index)
 {
-       struct gallivm_state *gallivm = ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
        LLVMValueRef base_addr, vertices_per_patch, num_patches, total_vertices;
        LLVMValueRef param_stride, constant16;
 
@@ -712,7 +690,7 @@ static LLVMValueRef get_tcs_tes_buffer_address_from_reg(
                                        const struct tgsi_full_dst_register *dst,
                                        const struct tgsi_full_src_register *src)
 {
-       struct gallivm_state *gallivm = ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
        struct tgsi_shader_info *info = &ctx->shader->selector->info;
        ubyte *name, *index, *array_first;
        struct tgsi_full_src_register reg;
@@ -788,7 +766,7 @@ static void build_tbuffer_store(struct si_shader_context *ctx,
                                unsigned slc,
                                unsigned tfe)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMValueRef args[] = {
                rsrc,
                vdata,
@@ -849,7 +827,7 @@ static LLVMValueRef build_buffer_load(struct si_shader_context *ctx,
                                       unsigned glc,
                                       unsigned slc)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        unsigned func = CLAMP(num_channels, 1, 3) - 1;
 
        if (HAVE_LLVM >= 0x309) {
@@ -880,7 +858,7 @@ static LLVMValueRef build_buffer_load(struct si_shader_context *ctx,
                         type_names[func]);
 
                return lp_build_intrinsic(gallivm->builder, name, types[func], args,
-                                         ARRAY_SIZE(args), LLVMReadOnlyAttribute);
+                                         ARRAY_SIZE(args), LP_FUNC_ATTR_READONLY);
        } else {
                LLVMValueRef args[] = {
                        LLVMBuildBitCast(gallivm->builder, rsrc, ctx->v16i8, ""),
@@ -911,7 +889,7 @@ static LLVMValueRef build_buffer_load(struct si_shader_context *ctx,
                         type_names[func], arg_type);
 
                return lp_build_intrinsic(gallivm->builder, name, types[func], args,
-                                         ARRAY_SIZE(args), LLVMReadOnlyAttribute);
+                                         ARRAY_SIZE(args), LP_FUNC_ATTR_READONLY);
        }
 }
 
@@ -948,7 +926,7 @@ static LLVMValueRef buffer_load(struct lp_build_tgsi_context *bld_base,
        value2 = build_buffer_load(ctx, buffer, 1, NULL, base, offset,
                                   swizzle * 4 + 4, 1, 0);
 
-       return radeon_llvm_emit_fetch_64bit(bld_base, type, value, value2);
+       return si_llvm_emit_fetch_64bit(bld_base, type, value, value2);
 }
 
 /**
@@ -983,9 +961,9 @@ static LLVMValueRef lds_load(struct lp_build_tgsi_context *bld_base,
        if (tgsi_type_is_64bit(type)) {
                LLVMValueRef value2;
                dw_addr = lp_build_add(&bld_base->uint_bld, dw_addr,
-                                      lp_build_const_int32(gallivm, swizzle + 1));
+                                      lp_build_const_int32(gallivm, 1));
                value2 = build_indexed_load(ctx, ctx->lds, dw_addr, false);
-               return radeon_llvm_emit_fetch_64bit(bld_base, type, value, value2);
+               return si_llvm_emit_fetch_64bit(bld_base, type, value, value2);
        }
 
        return LLVMBuildBitCast(gallivm->builder, value,
@@ -1058,12 +1036,12 @@ static LLVMValueRef fetch_input_tes(
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMValueRef rw_buffers, buffer, base, addr;
 
-       rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn,
+       rw_buffers = LLVMGetParam(ctx->main_fn,
                                  SI_PARAM_RW_BUFFERS);
        buffer = build_indexed_load_const(ctx, rw_buffers,
                        lp_build_const_int32(gallivm, SI_HS_RING_TESS_OFFCHIP));
 
-       base = LLVMGetParam(ctx->radeon_bld.main_fn, ctx->param_oc_lds);
+       base = LLVMGetParam(ctx->main_fn, ctx->param_oc_lds);
        addr = get_tcs_tes_buffer_address_from_reg(ctx, NULL, reg);
 
        return buffer_load(bld_base, type, swizzle, buffer, base, addr);
@@ -1087,7 +1065,7 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
         */
        if (reg->Register.File != TGSI_FILE_OUTPUT ||
            (dst[0] && LLVMGetTypeKind(LLVMTypeOf(dst[0])) == LLVMVectorTypeKind)) {
-               radeon_llvm_emit_store(bld_base, inst, info, dst);
+               si_llvm_emit_store(bld_base, inst, info, dst);
                return;
        }
 
@@ -1100,12 +1078,12 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
                dw_addr = get_dw_address(ctx, reg, NULL, NULL, dw_addr);
        }
 
-       rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn,
+       rw_buffers = LLVMGetParam(ctx->main_fn,
                                  SI_PARAM_RW_BUFFERS);
        buffer = build_indexed_load_const(ctx, rw_buffers,
                        lp_build_const_int32(gallivm, SI_HS_RING_TESS_OFFCHIP));
 
-       base = LLVMGetParam(ctx->radeon_bld.main_fn, ctx->param_oc_lds);
+       base = LLVMGetParam(ctx->main_fn, ctx->param_oc_lds);
        buf_addr = get_tcs_tes_buffer_address_from_reg(ctx, reg, NULL);
 
 
@@ -1113,7 +1091,7 @@ static void store_output_tcs(struct lp_build_tgsi_context *bld_base,
                LLVMValueRef value = dst[chan_index];
 
                if (inst->Instruction.Saturate)
-                       value = radeon_llvm_saturate(bld_base, value);
+                       value = si_llvm_saturate(bld_base, value);
 
                lds_store(bld_base, chan_index, dw_addr, value);
 
@@ -1144,7 +1122,7 @@ static LLVMValueRef fetch_input_gs(
        struct lp_build_context *base = &bld_base->base;
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
-       struct lp_build_context *uint = &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        struct gallivm_state *gallivm = base->gallivm;
        LLVMValueRef vtx_offset;
        LLVMValueRef args[9];
@@ -1180,7 +1158,7 @@ static LLVMValueRef fetch_input_gs(
                vtx_offset_param += SI_PARAM_VTX2_OFFSET - 2;
        }
        vtx_offset = lp_build_mul_imm(uint,
-                                     LLVMGetParam(ctx->radeon_bld.main_fn,
+                                     LLVMGetParam(ctx->main_fn,
                                                   vtx_offset_param),
                                      4);
 
@@ -1198,16 +1176,16 @@ static LLVMValueRef fetch_input_gs(
        value = lp_build_intrinsic(gallivm->builder,
                                   "llvm.SI.buffer.load.dword.i32.i32",
                                   ctx->i32, args, 9,
-                                  LLVMReadOnlyAttribute);
+                                  LP_FUNC_ATTR_READONLY);
        if (tgsi_type_is_64bit(type)) {
                LLVMValueRef value2;
                args[2] = lp_build_const_int32(gallivm, (param * 4 + swizzle + 1) * 256);
                value2 = lp_build_intrinsic(gallivm->builder,
                                            "llvm.SI.buffer.load.dword.i32.i32",
                                            ctx->i32, args, 9,
-                                           LLVMReadOnlyAttribute);
-               return radeon_llvm_emit_fetch_64bit(bld_base, type,
-                                                   value, value2);
+                                           LP_FUNC_ATTR_READONLY);
+               return si_llvm_emit_fetch_64bit(bld_base, type,
+                                               value, value2);
        }
        return LLVMBuildBitCast(gallivm->builder,
                                value,
@@ -1243,43 +1221,78 @@ static int lookup_interp_param_index(unsigned interpolate, unsigned location)
        }
 }
 
-/* This shouldn't be used by explicit INTERP opcodes. */
-static unsigned select_interp_param(struct si_shader_context *ctx,
-                                   unsigned param)
-{
-       if (!ctx->is_monolithic)
-               return param;
+static LLVMValueRef build_fs_interp(
+       struct lp_build_tgsi_context *bld_base,
+       LLVMValueRef llvm_chan,
+       LLVMValueRef attr_number,
+       LLVMValueRef params,
+       LLVMValueRef i,
+       LLVMValueRef j) {
 
-       if (ctx->shader->key.ps.prolog.force_persp_sample_interp) {
-               switch (param) {
-               case SI_PARAM_PERSP_CENTROID:
-               case SI_PARAM_PERSP_CENTER:
-                       return SI_PARAM_PERSP_SAMPLE;
-               }
-       }
-       if (ctx->shader->key.ps.prolog.force_linear_sample_interp) {
-               switch (param) {
-               case SI_PARAM_LINEAR_CENTROID:
-               case SI_PARAM_LINEAR_CENTER:
-                       return SI_PARAM_LINEAR_SAMPLE;
-               }
-       }
-       if (ctx->shader->key.ps.prolog.force_persp_center_interp) {
-               switch (param) {
-               case SI_PARAM_PERSP_CENTROID:
-               case SI_PARAM_PERSP_SAMPLE:
-                       return SI_PARAM_PERSP_CENTER;
-               }
+       struct si_shader_context *ctx = si_shader_context(bld_base);
+       struct gallivm_state *gallivm = bld_base->base.gallivm;
+       LLVMValueRef args[5];
+       LLVMValueRef p1;
+       if (HAVE_LLVM < 0x0400) {
+               LLVMValueRef ij[2];
+               ij[0] = LLVMBuildBitCast(gallivm->builder, i, ctx->i32, "");
+               ij[1] = LLVMBuildBitCast(gallivm->builder, j, ctx->i32, "");
+
+               args[0] = llvm_chan;
+               args[1] = attr_number;
+               args[2] = params;
+               args[3] = lp_build_gather_values(gallivm, ij, 2);
+               return lp_build_intrinsic(gallivm->builder, "llvm.SI.fs.interp",
+                                         ctx->f32, args, 4,
+                                         LP_FUNC_ATTR_READNONE);
        }
-       if (ctx->shader->key.ps.prolog.force_linear_center_interp) {
-               switch (param) {
-               case SI_PARAM_LINEAR_CENTROID:
-               case SI_PARAM_LINEAR_SAMPLE:
-                       return SI_PARAM_LINEAR_CENTER;
-               }
+
+       args[0] = i;
+       args[1] = llvm_chan;
+       args[2] = attr_number;
+       args[3] = params;
+
+       p1 = lp_build_intrinsic(gallivm->builder, "llvm.amdgcn.interp.p1",
+                               ctx->f32, args, 4, LP_FUNC_ATTR_READNONE);
+
+       args[0] = p1;
+       args[1] = j;
+       args[2] = llvm_chan;
+       args[3] = attr_number;
+       args[4] = params;
+
+       return lp_build_intrinsic(gallivm->builder, "llvm.amdgcn.interp.p2",
+                                 ctx->f32, args, 5, LP_FUNC_ATTR_READNONE);
+}
+
+static LLVMValueRef build_fs_interp_mov(
+       struct lp_build_tgsi_context *bld_base,
+       LLVMValueRef parameter,
+       LLVMValueRef llvm_chan,
+       LLVMValueRef attr_number,
+       LLVMValueRef params) {
+
+       struct si_shader_context *ctx = si_shader_context(bld_base);
+       struct gallivm_state *gallivm = bld_base->base.gallivm;
+       LLVMValueRef args[4];
+       if (HAVE_LLVM < 0x0400) {
+               args[0] = llvm_chan;
+               args[1] = attr_number;
+               args[2] = params;
+
+               return lp_build_intrinsic(gallivm->builder,
+                                         "llvm.SI.fs.constant",
+                                         ctx->f32, args, 3,
+                                         LP_FUNC_ATTR_READNONE);
        }
 
-       return param;
+       args[0] = parameter;
+       args[1] = llvm_chan;
+       args[2] = attr_number;
+       args[3] = params;
+
+       return lp_build_intrinsic(gallivm->builder, "llvm.amdgcn.interp.mov",
+                                 ctx->f32, args, 4, LP_FUNC_ATTR_READNONE);
 }
 
 /**
@@ -1307,16 +1320,15 @@ static void interp_fs_input(struct si_shader_context *ctx,
                            LLVMValueRef face,
                            LLVMValueRef result[4])
 {
-       struct lp_build_context *base = &ctx->radeon_bld.soa.bld_base.base;
-       struct lp_build_context *uint = &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
+       struct lp_build_context *base = &bld_base->base;
+       struct lp_build_context *uint = &bld_base->uint_bld;
        struct gallivm_state *gallivm = base->gallivm;
-       const char *intr_name;
        LLVMValueRef attr_number;
+       LLVMValueRef i, j;
 
        unsigned chan;
 
-       attr_number = lp_build_const_int32(gallivm, input_index);
-
        /* fs.constant returns the param from the middle vertex, so it's not
         * really useful for flat shading. It's meant to be used for custom
         * interpolation (but the intrinsic can't fetch from the other two
@@ -1326,12 +1338,26 @@ static void interp_fs_input(struct si_shader_context *ctx,
         * to do the right thing. The only reason we use fs.constant is that
         * fs.interp cannot be used on integers, because they can be equal
         * to NaN.
+        *
+        * When interp is false we will use fs.constant or for newer llvm,
+         * amdgcn.interp.mov.
         */
-       intr_name = interp_param ? "llvm.SI.fs.interp" : "llvm.SI.fs.constant";
+       bool interp = interp_param != NULL;
+
+       attr_number = lp_build_const_int32(gallivm, input_index);
+
+       if (interp) {
+               interp_param = LLVMBuildBitCast(gallivm->builder, interp_param,
+                                               LLVMVectorType(ctx->f32, 2), "");
+
+               i = LLVMBuildExtractElement(gallivm->builder, interp_param,
+                                               uint->zero, "");
+               j = LLVMBuildExtractElement(gallivm->builder, interp_param,
+                                               uint->one, "");
+       }
 
        if (semantic_name == TGSI_SEMANTIC_COLOR &&
-           ctx->shader->key.ps.prolog.color_two_side) {
-               LLVMValueRef args[4];
+           ctx->shader->key.part.ps.prolog.color_two_side) {
                LLVMValueRef is_face_positive;
                LLVMValueRef back_attr_number;
 
@@ -1347,22 +1373,25 @@ static void interp_fs_input(struct si_shader_context *ctx,
                is_face_positive = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
                                                 face, uint->zero, "");
 
-               args[2] = prim_mask;
-               args[3] = interp_param;
                for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
                        LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
                        LLVMValueRef front, back;
 
-                       args[0] = llvm_chan;
-                       args[1] = attr_number;
-                       front = lp_build_intrinsic(gallivm->builder, intr_name,
-                                               ctx->f32, args, args[3] ? 4 : 3,
-                                               LLVMReadNoneAttribute);
-
-                       args[1] = back_attr_number;
-                       back = lp_build_intrinsic(gallivm->builder, intr_name,
-                                              ctx->f32, args, args[3] ? 4 : 3,
-                                              LLVMReadNoneAttribute);
+                       if (interp) {
+                               front = build_fs_interp(bld_base, llvm_chan,
+                                                       attr_number, prim_mask,
+                                                       i, j);
+                               back = build_fs_interp(bld_base, llvm_chan,
+                                                       back_attr_number, prim_mask,
+                                                       i, j);
+                       } else {
+                               front = build_fs_interp_mov(bld_base,
+                                       lp_build_const_int32(gallivm, 2), /* P0 */
+                                       llvm_chan, attr_number, prim_mask);
+                               back = build_fs_interp_mov(bld_base,
+                                       lp_build_const_int32(gallivm, 2), /* P0 */
+                                       llvm_chan, back_attr_number, prim_mask);
+                       }
 
                        result[chan] = LLVMBuildSelect(gallivm->builder,
                                                is_face_positive,
@@ -1371,101 +1400,49 @@ static void interp_fs_input(struct si_shader_context *ctx,
                                                "");
                }
        } else if (semantic_name == TGSI_SEMANTIC_FOG) {
-               LLVMValueRef args[4];
-
-               args[0] = uint->zero;
-               args[1] = attr_number;
-               args[2] = prim_mask;
-               args[3] = interp_param;
-               result[0] = lp_build_intrinsic(gallivm->builder, intr_name,
-                                       ctx->f32, args, args[3] ? 4 : 3,
-                                       LLVMReadNoneAttribute);
+               if (interp) {
+                       result[0] = build_fs_interp(bld_base, uint->zero,
+                                               attr_number, prim_mask, i, j);
+               } else {
+                       result[0] = build_fs_interp_mov(bld_base, uint->zero,
+                               lp_build_const_int32(gallivm, 2), /* P0 */
+                               attr_number, prim_mask);
+               }
                result[1] =
                result[2] = lp_build_const_float(gallivm, 0.0f);
                result[3] = lp_build_const_float(gallivm, 1.0f);
        } else {
                for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
-                       LLVMValueRef args[4];
                        LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
 
-                       args[0] = llvm_chan;
-                       args[1] = attr_number;
-                       args[2] = prim_mask;
-                       args[3] = interp_param;
-                       result[chan] = lp_build_intrinsic(gallivm->builder, intr_name,
-                                               ctx->f32, args, args[3] ? 4 : 3,
-                                               LLVMReadNoneAttribute);
-               }
-       }
-}
-
-/* LLVMGetParam with bc_optimize resolved. */
-static LLVMValueRef get_interp_param(struct si_shader_context *ctx,
-                                    int interp_param_idx)
-{
-       LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
-       LLVMValueRef main_fn = ctx->radeon_bld.main_fn;
-       LLVMValueRef param = NULL;
-
-       /* Handle PRIM_MASK[31] (bc_optimize). */
-       if (ctx->is_monolithic &&
-           ((ctx->shader->key.ps.prolog.bc_optimize_for_persp &&
-             interp_param_idx == SI_PARAM_PERSP_CENTROID) ||
-            (ctx->shader->key.ps.prolog.bc_optimize_for_linear &&
-             interp_param_idx == SI_PARAM_LINEAR_CENTROID))) {
-               /* The shader should do: if (PRIM_MASK[31]) CENTROID = CENTER;
-                * The hw doesn't compute CENTROID if the whole wave only
-                * contains fully-covered quads.
-                */
-               LLVMValueRef bc_optimize =
-                       LLVMGetParam(main_fn, SI_PARAM_PRIM_MASK);
-               bc_optimize = LLVMBuildLShr(builder,
-                                           bc_optimize,
-                                           LLVMConstInt(ctx->i32, 31, 0), "");
-               bc_optimize = LLVMBuildTrunc(builder, bc_optimize, ctx->i1, "");
-
-               if (ctx->shader->key.ps.prolog.bc_optimize_for_persp &&
-                   interp_param_idx == SI_PARAM_PERSP_CENTROID) {
-                       param = LLVMBuildSelect(builder, bc_optimize,
-                                               LLVMGetParam(main_fn,
-                                                            SI_PARAM_PERSP_CENTER),
-                                               LLVMGetParam(main_fn,
-                                                            SI_PARAM_PERSP_CENTROID),
-                                               "");
-               }
-               if (ctx->shader->key.ps.prolog.bc_optimize_for_linear &&
-                   interp_param_idx == SI_PARAM_LINEAR_CENTROID) {
-                       param = LLVMBuildSelect(builder, bc_optimize,
-                                               LLVMGetParam(main_fn,
-                                                            SI_PARAM_LINEAR_CENTER),
-                                               LLVMGetParam(main_fn,
-                                                            SI_PARAM_LINEAR_CENTROID),
-                                               "");
+                       if (interp) {
+                               result[chan] = build_fs_interp(bld_base,
+                                       llvm_chan, attr_number, prim_mask, i, j);
+                       } else {
+                               result[chan] = build_fs_interp_mov(bld_base,
+                                       lp_build_const_int32(gallivm, 2), /* P0 */
+                                       llvm_chan, attr_number, prim_mask);
+                       }
                }
        }
-
-       if (!param)
-               param = LLVMGetParam(main_fn, interp_param_idx);
-       return param;
 }
 
 static void declare_input_fs(
-       struct radeon_llvm_context *radeon_bld,
+       struct si_shader_context *radeon_bld,
        unsigned input_index,
        const struct tgsi_full_declaration *decl,
        LLVMValueRef out[4])
 {
-       struct lp_build_context *base = &radeon_bld->soa.bld_base.base;
+       struct lp_build_context *base = &radeon_bld->bld_base.base;
        struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
+               si_shader_context(&radeon_bld->bld_base);
        struct si_shader *shader = ctx->shader;
        LLVMValueRef main_fn = radeon_bld->main_fn;
        LLVMValueRef interp_param = NULL;
        int interp_param_idx;
 
        /* Get colors from input VGPRs (set by the prolog). */
-       if (!ctx->is_monolithic &&
-           decl->Semantic.Name == TGSI_SEMANTIC_COLOR) {
+       if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR) {
                unsigned i = decl->Semantic.Index;
                unsigned colors_read = shader->selector->info.colors_read;
                unsigned mask = colors_read >> (i * 4);
@@ -1484,14 +1461,12 @@ static void declare_input_fs(
        if (interp_param_idx == -1)
                return;
        else if (interp_param_idx) {
-               interp_param_idx = select_interp_param(ctx,
-                                                      interp_param_idx);
-               interp_param = get_interp_param(ctx, interp_param_idx);
+               interp_param = LLVMGetParam(ctx->main_fn, interp_param_idx);
        }
 
        if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
            decl->Interp.Interpolate == TGSI_INTERPOLATE_COLOR &&
-           ctx->shader->key.ps.prolog.flatshade_colors)
+           ctx->shader->key.part.ps.prolog.flatshade_colors)
                interp_param = NULL; /* load the constant color */
 
        interp_fs_input(ctx, input_index, decl->Semantic.Name,
@@ -1502,9 +1477,9 @@ static void declare_input_fs(
                        &out[0]);
 }
 
-static LLVMValueRef get_sample_id(struct radeon_llvm_context *radeon_bld)
+static LLVMValueRef get_sample_id(struct si_shader_context *radeon_bld)
 {
-       return unpack_param(si_shader_context(&radeon_bld->soa.bld_base),
+       return unpack_param(si_shader_context(&radeon_bld->bld_base),
                            SI_PARAM_ANCILLARY, 8, 4);
 }
 
@@ -1530,23 +1505,23 @@ static void set_range_metadata(struct si_shader_context *ctx,
 
 static LLVMValueRef get_thread_id(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMValueRef tid;
 
        if (HAVE_LLVM < 0x0308) {
                tid = lp_build_intrinsic(gallivm->builder, "llvm.SI.tid",
-                               ctx->i32,   NULL, 0, LLVMReadNoneAttribute);
+                               ctx->i32,   NULL, 0, LP_FUNC_ATTR_READNONE);
        } else {
                LLVMValueRef tid_args[2];
                tid_args[0] = lp_build_const_int32(gallivm, 0xffffffff);
                tid_args[1] = lp_build_const_int32(gallivm, 0);
                tid_args[1] = lp_build_intrinsic(gallivm->builder,
                                        "llvm.amdgcn.mbcnt.lo", ctx->i32,
-                                       tid_args, 2, LLVMReadNoneAttribute);
+                                       tid_args, 2, LP_FUNC_ATTR_READNONE);
 
                tid = lp_build_intrinsic(gallivm->builder,
                                        "llvm.amdgcn.mbcnt.hi", ctx->i32,
-                                       tid_args, 2, LLVMReadNoneAttribute);
+                                       tid_args, 2, LP_FUNC_ATTR_READNONE);
        }
        set_range_metadata(ctx, tid, 0, 64);
        return tid;
@@ -1559,21 +1534,21 @@ static LLVMValueRef buffer_load_const(struct si_shader_context *ctx,
                                      LLVMValueRef resource,
                                      LLVMValueRef offset)
 {
-       LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
+       LLVMBuilderRef builder = ctx->gallivm.builder;
        LLVMValueRef args[2] = {resource, offset};
 
        return lp_build_intrinsic(builder, "llvm.SI.load.const", ctx->f32, args, 2,
-                              LLVMReadNoneAttribute);
+                              LP_FUNC_ATTR_READNONE);
 }
 
-static LLVMValueRef load_sample_position(struct radeon_llvm_context *radeon_bld, LLVMValueRef sample_id)
+static LLVMValueRef load_sample_position(struct si_shader_context *radeon_bld, LLVMValueRef sample_id)
 {
        struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
-       struct lp_build_context *uint_bld = &radeon_bld->soa.bld_base.uint_bld;
+               si_shader_context(&radeon_bld->bld_base);
+       struct lp_build_context *uint_bld = &radeon_bld->bld_base.uint_bld;
        struct gallivm_state *gallivm = &radeon_bld->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
-       LLVMValueRef desc = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_RW_BUFFERS);
+       LLVMValueRef desc = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS);
        LLVMValueRef buf_index = lp_build_const_int32(gallivm, SI_PS_CONST_SAMPLE_POSITIONS);
        LLVMValueRef resource = build_indexed_load_const(ctx, desc, buf_index);
 
@@ -1592,13 +1567,13 @@ static LLVMValueRef load_sample_position(struct radeon_llvm_context *radeon_bld,
 }
 
 static void declare_system_value(
-       struct radeon_llvm_context *radeon_bld,
+       struct si_shader_context *radeon_bld,
        unsigned index,
        const struct tgsi_full_declaration *decl)
 {
        struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
-       struct lp_build_context *bld = &radeon_bld->soa.bld_base.base;
+               si_shader_context(&radeon_bld->bld_base);
+       struct lp_build_context *bld = &radeon_bld->bld_base.base;
        struct gallivm_state *gallivm = &radeon_bld->gallivm;
        LLVMValueRef value = 0;
 
@@ -1652,7 +1627,7 @@ static void declare_system_value(
                        LLVMGetParam(radeon_bld->main_fn, SI_PARAM_POS_X_FLOAT),
                        LLVMGetParam(radeon_bld->main_fn, SI_PARAM_POS_Y_FLOAT),
                        LLVMGetParam(radeon_bld->main_fn, SI_PARAM_POS_Z_FLOAT),
-                       lp_build_emit_llvm_unary(&radeon_bld->soa.bld_base, TGSI_OPCODE_RCP,
+                       lp_build_emit_llvm_unary(&radeon_bld->bld_base, TGSI_OPCODE_RCP,
                                                 LLVMGetParam(radeon_bld->main_fn,
                                                              SI_PARAM_POS_W_FLOAT)),
                };
@@ -1675,9 +1650,9 @@ static void declare_system_value(
                        lp_build_const_float(gallivm, 0),
                        lp_build_const_float(gallivm, 0)
                };
-               pos[0] = lp_build_emit_llvm_unary(&radeon_bld->soa.bld_base,
+               pos[0] = lp_build_emit_llvm_unary(&radeon_bld->bld_base,
                                                  TGSI_OPCODE_FRC, pos[0]);
-               pos[1] = lp_build_emit_llvm_unary(&radeon_bld->soa.bld_base,
+               pos[1] = lp_build_emit_llvm_unary(&radeon_bld->bld_base,
                                                  TGSI_OPCODE_FRC, pos[1]);
                value = lp_build_gather_values(gallivm, pos, 4);
                break;
@@ -1724,16 +1699,16 @@ static void declare_system_value(
                LLVMValueRef rw_buffers, buffer, base, addr;
                int param = si_shader_io_get_unique_index(decl->Semantic.Name, 0);
 
-               rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn,
+               rw_buffers = LLVMGetParam(ctx->main_fn,
                                        SI_PARAM_RW_BUFFERS);
                buffer = build_indexed_load_const(ctx, rw_buffers,
                        lp_build_const_int32(gallivm, SI_HS_RING_TESS_OFFCHIP));
 
-               base = LLVMGetParam(ctx->radeon_bld.main_fn, ctx->param_oc_lds);
+               base = LLVMGetParam(ctx->main_fn, ctx->param_oc_lds);
                addr = get_tcs_tes_buffer_address(ctx, NULL,
                                          lp_build_const_int32(gallivm, param));
 
-               value = buffer_load(&radeon_bld->soa.bld_base, TGSI_TYPE_FLOAT,
+               value = buffer_load(&radeon_bld->bld_base, TGSI_TYPE_FLOAT,
                                    ~0, buffer, base, addr);
 
                break;
@@ -1746,7 +1721,7 @@ static void declare_system_value(
                int i, offset;
 
                slot = lp_build_const_int32(gallivm, SI_HS_CONST_DEFAULT_TESS_LEVELS);
-               buf = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_RW_BUFFERS);
+               buf = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS);
                buf = build_indexed_load_const(ctx, buf, slot);
                offset = decl->Semantic.Name == TGSI_SEMANTIC_DEFAULT_TESSINNER_SI ? 4 : 0;
 
@@ -1758,7 +1733,7 @@ static void declare_system_value(
        }
 
        case TGSI_SEMANTIC_PRIMID:
-               value = get_primitive_id(&radeon_bld->soa.bld_base, 0);
+               value = get_primitive_id(&radeon_bld->bld_base, 0);
                break;
 
        case TGSI_SEMANTIC_GRID_SIZE:
@@ -1770,16 +1745,21 @@ static void declare_system_value(
                LLVMValueRef values[3];
                unsigned i;
                unsigned *properties = ctx->shader->selector->info.properties;
-               unsigned sizes[3] = {
-                       properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH],
-                       properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT],
-                       properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH]
-               };
 
-               for (i = 0; i < 3; ++i)
-                       values[i] = lp_build_const_int32(gallivm, sizes[i]);
+               if (properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] != 0) {
+                       unsigned sizes[3] = {
+                               properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH],
+                               properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT],
+                               properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH]
+                       };
+
+                       for (i = 0; i < 3; ++i)
+                               values[i] = lp_build_const_int32(gallivm, sizes[i]);
 
-               value = lp_build_gather_values(gallivm, values, 3);
+                       value = lp_build_gather_values(gallivm, values, 3);
+               } else {
+                       value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_BLOCK_SIZE);
+               }
                break;
        }
 
@@ -1791,16 +1771,19 @@ static void declare_system_value(
                value = LLVMGetParam(radeon_bld->main_fn, SI_PARAM_THREAD_ID);
                break;
 
-#if HAVE_LLVM >= 0x0309
        case TGSI_SEMANTIC_HELPER_INVOCATION:
-               value = lp_build_intrinsic(gallivm->builder,
-                                          "llvm.amdgcn.ps.live",
-                                          ctx->i1, NULL, 0,
-                                          LLVMReadNoneAttribute);
-               value = LLVMBuildNot(gallivm->builder, value, "");
-               value = LLVMBuildSExt(gallivm->builder, value, ctx->i32, "");
+               if (HAVE_LLVM >= 0x0309) {
+                       value = lp_build_intrinsic(gallivm->builder,
+                                                  "llvm.amdgcn.ps.live",
+                                                  ctx->i1, NULL, 0,
+                                                  LP_FUNC_ATTR_READNONE);
+                       value = LLVMBuildNot(gallivm->builder, value, "");
+                       value = LLVMBuildSExt(gallivm->builder, value, ctx->i32, "");
+               } else {
+                       assert(!"TGSI_SEMANTIC_HELPER_INVOCATION unsupported");
+                       return;
+               }
                break;
-#endif
 
        default:
                assert(!"unknown system value");
@@ -1810,11 +1793,11 @@ static void declare_system_value(
        radeon_bld->system_values[index] = value;
 }
 
-static void declare_compute_memory(struct radeon_llvm_context *radeon_bld,
+static void declare_compute_memory(struct si_shader_context *radeon_bld,
                                    const struct tgsi_full_declaration *decl)
 {
        struct si_shader_context *ctx =
-               si_shader_context(&radeon_bld->soa.bld_base);
+               si_shader_context(&radeon_bld->bld_base);
        struct si_shader_selector *sel = ctx->shader->selector;
        struct gallivm_state *gallivm = &radeon_bld->gallivm;
 
@@ -1836,7 +1819,7 @@ static void declare_compute_memory(struct radeon_llvm_context *radeon_bld,
 
 static LLVMValueRef load_const_buffer_desc(struct si_shader_context *ctx, int i)
 {
-       LLVMValueRef list_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef list_ptr = LLVMGetParam(ctx->main_fn,
                                             SI_PARAM_CONST_BUFFERS);
 
        return build_indexed_load_const(ctx, list_ptr,
@@ -1869,26 +1852,8 @@ static LLVMValueRef fetch_constant(
        buf = reg->Register.Dimension ? reg->Dimension.Index : 0;
        idx = reg->Register.Index * 4 + swizzle;
 
-       if (!reg->Register.Indirect && !reg->Dimension.Indirect) {
-               LLVMValueRef c0, c1, desc;
-
-               desc = load_const_buffer_desc(ctx, buf);
-               c0 = buffer_load_const(ctx, desc,
-                                      LLVMConstInt(ctx->i32, idx * 4, 0));
-
-               if (!tgsi_type_is_64bit(type))
-                       return bitcast(bld_base, type, c0);
-               else {
-                       c1 = buffer_load_const(ctx, desc,
-                                              LLVMConstInt(ctx->i32,
-                                                           (idx + 1) * 4, 0));
-                       return radeon_llvm_emit_fetch_64bit(bld_base, type,
-                                                           c0, c1);
-               }
-       }
-
        if (reg->Register.Dimension && reg->Dimension.Indirect) {
-               LLVMValueRef ptr = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_CONST_BUFFERS);
+               LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, SI_PARAM_CONST_BUFFERS);
                LLVMValueRef index;
                index = get_bounded_indirect_index(ctx, &reg->DimIndirect,
                                                   reg->Dimension.Index,
@@ -1897,11 +1862,15 @@ static LLVMValueRef fetch_constant(
        } else
                bufp = load_const_buffer_desc(ctx, buf);
 
-       addr = ctx->radeon_bld.soa.addr[ireg->Index][ireg->Swizzle];
-       addr = LLVMBuildLoad(base->gallivm->builder, addr, "load addr reg");
-       addr = lp_build_mul_imm(&bld_base->uint_bld, addr, 16);
-       addr = lp_build_add(&bld_base->uint_bld, addr,
-                           lp_build_const_int32(base->gallivm, idx * 4));
+       if (reg->Register.Indirect) {
+               addr = ctx->addrs[ireg->Index][ireg->Swizzle];
+               addr = LLVMBuildLoad(base->gallivm->builder, addr, "load addr reg");
+               addr = lp_build_mul_imm(&bld_base->uint_bld, addr, 16);
+               addr = lp_build_add(&bld_base->uint_bld, addr,
+                                   lp_build_const_int32(base->gallivm, idx * 4));
+       } else {
+               addr = LLVMConstInt(ctx->i32, idx * 4, 0);
+       }
 
        result = buffer_load_const(ctx, bufp, addr);
 
@@ -1909,16 +1878,13 @@ static LLVMValueRef fetch_constant(
                result = bitcast(bld_base, type, result);
        else {
                LLVMValueRef addr2, result2;
-               addr2 = ctx->radeon_bld.soa.addr[ireg->Index][ireg->Swizzle + 1];
-               addr2 = LLVMBuildLoad(base->gallivm->builder, addr2, "load addr reg2");
-               addr2 = lp_build_mul_imm(&bld_base->uint_bld, addr2, 16);
-               addr2 = lp_build_add(&bld_base->uint_bld, addr2,
-                                    lp_build_const_int32(base->gallivm, idx * 4));
 
+               addr2 = lp_build_add(&bld_base->uint_bld, addr,
+                                    LLVMConstInt(ctx->i32, 4, 0));
                result2 = buffer_load_const(ctx, bufp, addr2);
 
-               result = radeon_llvm_emit_fetch_64bit(bld_base, type,
-                                                     result, result2);
+               result = si_llvm_emit_fetch_64bit(bld_base, type,
+                                                 result, result2);
        }
        return result;
 }
@@ -1952,8 +1918,7 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
                                     LLVMValueRef *args)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       struct lp_build_context *uint =
-                               &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        struct lp_build_context *base = &bld_base->base;
        struct gallivm_state *gallivm = base->gallivm;
        LLVMBuilderRef builder = base->gallivm->builder;
@@ -1975,13 +1940,13 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
        args[3] = lp_build_const_int32(base->gallivm, target);
 
        if (ctx->type == PIPE_SHADER_FRAGMENT) {
-               const union si_shader_key *key = &ctx->shader->key;
-               unsigned col_formats = key->ps.epilog.spi_shader_col_format;
+               const struct si_shader_key *key = &ctx->shader->key;
+               unsigned col_formats = key->part.ps.epilog.spi_shader_col_format;
                int cbuf = target - V_008DFC_SQ_EXP_MRT;
 
                assert(cbuf >= 0 && cbuf < 8);
                spi_shader_col_format = (col_formats >> (cbuf * 4)) & 0xf;
-               is_int8 = (key->ps.epilog.color_is_int8 >> cbuf) & 0x1;
+               is_int8 = (key->part.ps.epilog.color_is_int8 >> cbuf) & 0x1;
        }
 
        args[4] = uint->zero; /* COMPR flag */
@@ -2026,7 +1991,7 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
                        packed = lp_build_intrinsic(base->gallivm->builder,
                                                    "llvm.SI.packf16",
                                                    ctx->i32, pack_args, 2,
-                                                   LLVMReadNoneAttribute);
+                                                   LP_FUNC_ATTR_READNONE);
                        args[chan + 5] =
                                LLVMBuildBitCast(base->gallivm->builder,
                                                 packed, ctx->f32, "");
@@ -2035,7 +2000,7 @@ static void si_llvm_init_export_args(struct lp_build_tgsi_context *bld_base,
 
        case V_028714_SPI_SHADER_UNORM16_ABGR:
                for (chan = 0; chan < 4; chan++) {
-                       val[chan] = radeon_llvm_saturate(bld_base, values[chan]);
+                       val[chan] = si_llvm_saturate(bld_base, values[chan]);
                        val[chan] = LLVMBuildFMul(builder, val[chan],
                                                  lp_build_const_float(gallivm, 65535), "");
                        val[chan] = LLVMBuildFAdd(builder, val[chan],
@@ -2134,13 +2099,13 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
 
-       if (ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_NEVER) {
-               LLVMValueRef alpha_ref = LLVMGetParam(ctx->radeon_bld.main_fn,
+       if (ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_NEVER) {
+               LLVMValueRef alpha_ref = LLVMGetParam(ctx->main_fn,
                                SI_PARAM_ALPHA_REF);
 
                LLVMValueRef alpha_pass =
                        lp_build_cmp(&bld_base->base,
-                                    ctx->shader->key.ps.epilog.alpha_func,
+                                    ctx->shader->key.part.ps.epilog.alpha_func,
                                     alpha, alpha_ref);
                LLVMValueRef arg =
                        lp_build_select(&bld_base->base,
@@ -2165,13 +2130,13 @@ static LLVMValueRef si_scale_alpha_by_sample_mask(struct lp_build_tgsi_context *
        LLVMValueRef coverage;
 
        /* alpha = alpha * popcount(coverage) / SI_NUM_SMOOTH_AA_SAMPLES */
-       coverage = LLVMGetParam(ctx->radeon_bld.main_fn,
+       coverage = LLVMGetParam(ctx->main_fn,
                                samplemask_param);
        coverage = bitcast(bld_base, TGSI_TYPE_SIGNED, coverage);
 
        coverage = lp_build_intrinsic(gallivm->builder, "llvm.ctpop.i32",
                                   ctx->i32,
-                                  &coverage, 1, LLVMReadNoneAttribute);
+                                  &coverage, 1, LP_FUNC_ATTR_READNONE);
 
        coverage = LLVMBuildUIToFP(gallivm->builder, coverage,
                                   ctx->f32, "");
@@ -2188,12 +2153,12 @@ static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context *bld_base,
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint = &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        unsigned reg_index;
        unsigned chan;
        unsigned const_chan;
        LLVMValueRef base_elt;
-       LLVMValueRef ptr = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_RW_BUFFERS);
+       LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS);
        LLVMValueRef constbuf_index = lp_build_const_int32(base->gallivm,
                                                           SI_VS_CONST_CLIP_PLANES);
        LLVMValueRef const_resource = build_indexed_load_const(ctx, ptr, constbuf_index);
@@ -2251,31 +2216,72 @@ static void si_dump_streamout(struct pipe_stream_output_info *so)
        }
 }
 
-/* On SI, the vertex shader is responsible for writing streamout data
- * to buffers. */
-static void si_llvm_emit_streamout(struct si_shader_context *ctx,
-                                  struct si_shader_output_values *outputs,
-                                  unsigned noutput)
+static void emit_streamout_output(struct si_shader_context *ctx,
+                                 LLVMValueRef const *so_buffers,
+                                 LLVMValueRef const *so_write_offsets,
+                                 struct pipe_stream_output *stream_out,
+                                 struct si_shader_output_values *shader_out)
 {
-       struct pipe_stream_output_info *so = &ctx->shader->selector->so;
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
-       int i, j;
-       struct lp_build_if_state if_ctx;
-       LLVMValueRef so_buffers[4];
-       LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
-                                           SI_PARAM_RW_BUFFERS);
+       unsigned buf_idx = stream_out->output_buffer;
+       unsigned start = stream_out->start_component;
+       unsigned num_comps = stream_out->num_components;
+       LLVMValueRef out[4];
 
-       /* Load the descriptors. */
-       for (i = 0; i < 4; ++i) {
-               if (ctx->shader->selector->so.stride[i]) {
-                       LLVMValueRef offset = lp_build_const_int32(gallivm,
-                                                                  SI_VS_STREAMOUT_BUF0 + i);
+       assert(num_comps && num_comps <= 4);
+       if (!num_comps || num_comps > 4)
+               return;
 
-                       so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
+       /* Load the output as int. */
+       for (int j = 0; j < num_comps; j++) {
+               assert(stream_out->stream == shader_out->vertex_stream[start + j]);
+
+               out[j] = LLVMBuildBitCast(builder,
+                                         shader_out->values[start + j],
+                               ctx->i32, "");
+       }
+
+       /* Pack the output. */
+       LLVMValueRef vdata = NULL;
+
+       switch (num_comps) {
+       case 1: /* as i32 */
+               vdata = out[0];
+               break;
+       case 2: /* as v2i32 */
+       case 3: /* as v4i32 (aligned to 4) */
+       case 4: /* as v4i32 */
+               vdata = LLVMGetUndef(LLVMVectorType(ctx->i32, util_next_power_of_two(num_comps)));
+               for (int j = 0; j < num_comps; j++) {
+                       vdata = LLVMBuildInsertElement(builder, vdata, out[j],
+                                                      LLVMConstInt(ctx->i32, j, 0), "");
                }
+               break;
        }
 
+       build_tbuffer_store_dwords(ctx, so_buffers[buf_idx],
+                                  vdata, num_comps,
+                                  so_write_offsets[buf_idx],
+                                  LLVMConstInt(ctx->i32, 0, 0),
+                                  stream_out->dst_offset * 4);
+}
+
+/**
+ * Write streamout data to buffers for vertex stream @p stream (different
+ * vertex streams can occur for GS copy shaders).
+ */
+static void si_llvm_emit_streamout(struct si_shader_context *ctx,
+                                  struct si_shader_output_values *outputs,
+                                  unsigned noutput, unsigned stream)
+{
+       struct si_shader_selector *sel = ctx->shader->selector;
+       struct pipe_stream_output_info *so = &sel->so;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       LLVMBuilderRef builder = gallivm->builder;
+       int i;
+       struct lp_build_if_state if_ctx;
+
        /* Get bits [22:16], i.e. (so_param >> 16) & 127; */
        LLVMValueRef so_vtx_count =
                unpack_param(ctx, ctx->param_streamout_config, 16, 7);
@@ -2286,9 +2292,6 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
        LLVMValueRef can_emit =
                LLVMBuildICmp(builder, LLVMIntULT, tid, so_vtx_count, "");
 
-       LLVMValueRef stream_id =
-               unpack_param(ctx, ctx->param_streamout_config, 24, 2);
-
        /* Emit the streamout code conditionally. This actually avoids
         * out-of-bounds buffer access. The hw tells us via the SGPR
         * (so_vtx_count) which threads are allowed to emit streamout data. */
@@ -2301,19 +2304,29 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
                  */
 
                LLVMValueRef so_write_index =
-                       LLVMGetParam(ctx->radeon_bld.main_fn,
+                       LLVMGetParam(ctx->main_fn,
                                     ctx->param_streamout_write_index);
 
                /* Compute (streamout_write_index + thread_id). */
                so_write_index = LLVMBuildAdd(builder, so_write_index, tid, "");
 
-               /* Compute the write offset for each enabled buffer. */
+               /* Load the descriptor and compute the write offset for each
+                * enabled buffer. */
                LLVMValueRef so_write_offset[4] = {};
+               LLVMValueRef so_buffers[4];
+               LLVMValueRef buf_ptr = LLVMGetParam(ctx->main_fn,
+                                                   SI_PARAM_RW_BUFFERS);
+
                for (i = 0; i < 4; i++) {
                        if (!so->stride[i])
                                continue;
 
-                       LLVMValueRef so_offset = LLVMGetParam(ctx->radeon_bld.main_fn,
+                       LLVMValueRef offset = lp_build_const_int32(gallivm,
+                                                                  SI_VS_STREAMOUT_BUF0 + i);
+
+                       so_buffers[i] = build_indexed_load_const(ctx, buf_ptr, offset);
+
+                       LLVMValueRef so_offset = LLVMGetParam(ctx->main_fn,
                                                              ctx->param_streamout_offset[i]);
                        so_offset = LLVMBuildMul(builder, so_offset, LLVMConstInt(ctx->i32, 4, 0), "");
 
@@ -2324,58 +2337,16 @@ static void si_llvm_emit_streamout(struct si_shader_context *ctx,
 
                /* Write streamout data. */
                for (i = 0; i < so->num_outputs; i++) {
-                       unsigned buf_idx = so->output[i].output_buffer;
                        unsigned reg = so->output[i].register_index;
-                       unsigned start = so->output[i].start_component;
-                       unsigned num_comps = so->output[i].num_components;
-                       unsigned stream = so->output[i].stream;
-                       LLVMValueRef out[4];
-                       struct lp_build_if_state if_ctx_stream;
-
-                       assert(num_comps && num_comps <= 4);
-                       if (!num_comps || num_comps > 4)
-                               continue;
 
                        if (reg >= noutput)
                                continue;
 
-                       /* Load the output as int. */
-                       for (j = 0; j < num_comps; j++) {
-                               out[j] = LLVMBuildBitCast(builder,
-                                                         outputs[reg].values[start+j],
-                                               ctx->i32, "");
-                       }
-
-                       /* Pack the output. */
-                       LLVMValueRef vdata = NULL;
-
-                       switch (num_comps) {
-                       case 1: /* as i32 */
-                               vdata = out[0];
-                               break;
-                       case 2: /* as v2i32 */
-                       case 3: /* as v4i32 (aligned to 4) */
-                       case 4: /* as v4i32 */
-                               vdata = LLVMGetUndef(LLVMVectorType(ctx->i32, util_next_power_of_two(num_comps)));
-                               for (j = 0; j < num_comps; j++) {
-                                       vdata = LLVMBuildInsertElement(builder, vdata, out[j],
-                                                                      LLVMConstInt(ctx->i32, j, 0), "");
-                               }
-                               break;
-                       }
+                       if (stream != so->output[i].stream)
+                               continue;
 
-                       LLVMValueRef can_emit_stream =
-                               LLVMBuildICmp(builder, LLVMIntEQ,
-                                             stream_id,
-                                             lp_build_const_int32(gallivm, stream), "");
-
-                       lp_build_if(&if_ctx_stream, gallivm, can_emit_stream);
-                       build_tbuffer_store_dwords(ctx, so_buffers[buf_idx],
-                                                  vdata, num_comps,
-                                                  so_write_offset[buf_idx],
-                                                  LLVMConstInt(ctx->i32, 0, 0),
-                                                  so->output[i].dst_offset*4);
-                       lp_build_endif(&if_ctx_stream);
+                       emit_streamout_output(ctx, so_buffers, so_write_offset,
+                                             &so->output[i], &outputs[reg]);
                }
        }
        lp_build_endif(&if_ctx);
@@ -2390,8 +2361,7 @@ static void si_llvm_export_vs(struct lp_build_tgsi_context *bld_base,
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
        struct lp_build_context *base = &bld_base->base;
-       struct lp_build_context *uint =
-                               &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_context *uint = &ctx->bld_base.uint_bld;
        LLVMValueRef args[9];
        LLVMValueRef pos_args[4][9] = { { 0 } };
        LLVMValueRef psize_value = NULL, edgeflag_value = NULL, layer_value = NULL, viewport_index_value = NULL;
@@ -2401,13 +2371,35 @@ static void si_llvm_export_vs(struct lp_build_tgsi_context *bld_base,
        unsigned pos_idx;
        int i;
 
-       if (outputs && ctx->shader->selector->so.num_outputs) {
-               si_llvm_emit_streamout(ctx, outputs, noutput);
-       }
-
        for (i = 0; i < noutput; i++) {
-               semantic_name = outputs[i].name;
-               semantic_index = outputs[i].sid;
+               semantic_name = outputs[i].semantic_name;
+               semantic_index = outputs[i].semantic_index;
+               bool export_param = true;
+
+               switch (semantic_name) {
+               case TGSI_SEMANTIC_POSITION: /* ignore these */
+               case TGSI_SEMANTIC_PSIZE:
+               case TGSI_SEMANTIC_CLIPVERTEX:
+               case TGSI_SEMANTIC_EDGEFLAG:
+                       break;
+               case TGSI_SEMANTIC_GENERIC:
+               case TGSI_SEMANTIC_CLIPDIST:
+                       if (shader->key.opt.hw_vs.kill_outputs &
+                           (1ull << si_shader_io_get_unique_index(semantic_name, semantic_index)))
+                               export_param = false;
+                       break;
+               default:
+                       if (shader->key.opt.hw_vs.kill_outputs2 &
+                           (1u << si_shader_io_get_unique_index2(semantic_name, semantic_index)))
+                               export_param = false;
+                       break;
+               }
+
+               if (outputs[i].vertex_stream[0] != 0 &&
+                   outputs[i].vertex_stream[1] != 0 &&
+                   outputs[i].vertex_stream[2] != 0 &&
+                   outputs[i].vertex_stream[3] != 0)
+                       export_param = false;
 
 handle_semantic:
                /* Select the correct target */
@@ -2429,23 +2421,26 @@ handle_semantic:
                case TGSI_SEMANTIC_POSITION:
                        target = V_008DFC_SQ_EXP_POS;
                        break;
-               case TGSI_SEMANTIC_COLOR:
-               case TGSI_SEMANTIC_BCOLOR:
-                       target = V_008DFC_SQ_EXP_PARAM + param_count;
-                       assert(i < ARRAY_SIZE(shader->info.vs_output_param_offset));
-                       shader->info.vs_output_param_offset[i] = param_count;
-                       param_count++;
-                       break;
                case TGSI_SEMANTIC_CLIPDIST:
+                       if (shader->key.opt.hw_vs.clip_disable) {
+                               semantic_name = TGSI_SEMANTIC_GENERIC;
+                               goto handle_semantic;
+                       }
                        target = V_008DFC_SQ_EXP_POS + 2 + semantic_index;
                        break;
                case TGSI_SEMANTIC_CLIPVERTEX:
+                       if (shader->key.opt.hw_vs.clip_disable)
+                               continue;
                        si_llvm_emit_clipvertex(bld_base, pos_args, outputs[i].values);
                        continue;
+               case TGSI_SEMANTIC_COLOR:
+               case TGSI_SEMANTIC_BCOLOR:
                case TGSI_SEMANTIC_PRIMID:
                case TGSI_SEMANTIC_FOG:
                case TGSI_SEMANTIC_TEXCOORD:
                case TGSI_SEMANTIC_GENERIC:
+                       if (!export_param)
+                               continue;
                        target = V_008DFC_SQ_EXP_PARAM + param_count;
                        assert(i < ARRAY_SIZE(shader->info.vs_output_param_offset));
                        shader->info.vs_output_param_offset[i] = param_count;
@@ -2557,6 +2552,10 @@ handle_semantic:
        }
 }
 
+/**
+ * Forward all outputs from the vertex shader to the TES. This is only used
+ * for the fixed function TCS.
+ */
 static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
@@ -2567,11 +2566,11 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
 
        invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
 
-       rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_RW_BUFFERS);
+       rw_buffers = LLVMGetParam(ctx->main_fn, SI_PARAM_RW_BUFFERS);
        buffer = build_indexed_load_const(ctx, rw_buffers,
                        lp_build_const_int32(gallivm, SI_HS_RING_TESS_OFFCHIP));
 
-       buffer_offset = LLVMGetParam(ctx->radeon_bld.main_fn, ctx->param_oc_lds);
+       buffer_offset = LLVMGetParam(ctx->main_fn, ctx->param_oc_lds);
 
        lds_vertex_stride = unpack_param(ctx, SI_PARAM_TCS_IN_LAYOUT, 13, 8);
        lds_vertex_offset = LLVMBuildMul(gallivm->builder, invocation_id,
@@ -2579,7 +2578,7 @@ static void si_copy_tcs_inputs(struct lp_build_tgsi_context *bld_base)
        lds_base = get_tcs_in_current_patch_offset(ctx);
        lds_base = LLVMBuildAdd(gallivm->builder, lds_base, lds_vertex_offset, "");
 
-       inputs = ctx->shader->key.tcs.epilog.inputs_to_copy;
+       inputs = ctx->shader->key.mono.tcs.inputs_to_copy;
        while (inputs) {
                unsigned i = u_bit_scan64(&inputs);
 
@@ -2626,7 +2625,7 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                                  invocation_id, bld_base->uint_bld.zero, ""));
 
        /* Determine the layout of one tess factor element in the buffer. */
-       switch (shader->key.tcs.epilog.prim_mode) {
+       switch (shader->key.part.tcs.epilog.prim_mode) {
        case PIPE_PRIM_LINES:
                stride = 2; /* 2 dwords, 1 vec2 store */
                outer_comps = 2;
@@ -2661,10 +2660,18 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                                 lp_build_const_int32(gallivm,
                                                      tess_outer_index * 4), "");
 
-       for (i = 0; i < outer_comps; i++)
-               out[i] = lds_load(bld_base, TGSI_TYPE_SIGNED, i, lds_outer);
-       for (i = 0; i < inner_comps; i++)
-               out[outer_comps+i] = lds_load(bld_base, TGSI_TYPE_SIGNED, i, lds_inner);
+       if (shader->key.part.tcs.epilog.prim_mode == PIPE_PRIM_LINES) {
+               /* For isolines, the hardware expects tess factors in the
+                * reverse order from what GLSL / TGSI specify.
+                */
+               out[0] = lds_load(bld_base, TGSI_TYPE_SIGNED, 1, lds_outer);
+               out[1] = lds_load(bld_base, TGSI_TYPE_SIGNED, 0, lds_outer);
+       } else {
+               for (i = 0; i < outer_comps; i++)
+                       out[i] = lds_load(bld_base, TGSI_TYPE_SIGNED, i, lds_outer);
+               for (i = 0; i < inner_comps; i++)
+                       out[outer_comps+i] = lds_load(bld_base, TGSI_TYPE_SIGNED, i, lds_inner);
+       }
 
        /* Convert the outputs to vectors for stores. */
        vec0 = lp_build_gather_values(gallivm, out, MIN2(stride, 4));
@@ -2674,13 +2681,13 @@ static void si_write_tess_factors(struct lp_build_tgsi_context *bld_base,
                vec1 = lp_build_gather_values(gallivm, out+4, stride - 4);
 
        /* Get the buffer. */
-       rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn,
+       rw_buffers = LLVMGetParam(ctx->main_fn,
                                  SI_PARAM_RW_BUFFERS);
        buffer = build_indexed_load_const(ctx, rw_buffers,
                        lp_build_const_int32(gallivm, SI_HS_RING_TESS_FACTOR));
 
        /* Get the offset. */
-       tf_base = LLVMGetParam(ctx->radeon_bld.main_fn,
+       tf_base = LLVMGetParam(ctx->main_fn,
                               SI_PARAM_TESS_FACTOR_OFFSET);
        byteoffset = LLVMBuildMul(gallivm->builder, rel_patch_id,
                                  lp_build_const_int32(gallivm, 4 * stride), "");
@@ -2711,50 +2718,46 @@ static void si_llvm_emit_tcs_epilogue(struct lp_build_tgsi_context *bld_base)
        struct si_shader_context *ctx = si_shader_context(bld_base);
        LLVMValueRef rel_patch_id, invocation_id, tf_lds_offset;
 
+       si_copy_tcs_inputs(bld_base);
+
        rel_patch_id = get_rel_patch_id(ctx);
        invocation_id = unpack_param(ctx, SI_PARAM_REL_IDS, 8, 5);
        tf_lds_offset = get_tcs_out_current_patch_data_offset(ctx);
 
-       if (!ctx->is_monolithic) {
-               /* Return epilog parameters from this function. */
-               LLVMBuilderRef builder = bld_base->base.gallivm->builder;
-               LLVMValueRef ret = ctx->return_value;
-               LLVMValueRef rw_buffers, rw0, rw1, tf_soffset;
-               unsigned vgpr;
-
-               /* RW_BUFFERS pointer */
-               rw_buffers = LLVMGetParam(ctx->radeon_bld.main_fn,
-                                         SI_PARAM_RW_BUFFERS);
-               rw_buffers = LLVMBuildPtrToInt(builder, rw_buffers, ctx->i64, "");
-               rw_buffers = LLVMBuildBitCast(builder, rw_buffers, ctx->v2i32, "");
-               rw0 = LLVMBuildExtractElement(builder, rw_buffers,
-                                             bld_base->uint_bld.zero, "");
-               rw1 = LLVMBuildExtractElement(builder, rw_buffers,
-                                             bld_base->uint_bld.one, "");
-               ret = LLVMBuildInsertValue(builder, ret, rw0, 0, "");
-               ret = LLVMBuildInsertValue(builder, ret, rw1, 1, "");
-
-               /* Tess factor buffer soffset is after user SGPRs. */
-               tf_soffset = LLVMGetParam(ctx->radeon_bld.main_fn,
-                                         SI_PARAM_TESS_FACTOR_OFFSET);
-               ret = LLVMBuildInsertValue(builder, ret, tf_soffset,
-                                          SI_TCS_NUM_USER_SGPR + 1, "");
-
-               /* VGPRs */
-               rel_patch_id = bitcast(bld_base, TGSI_TYPE_FLOAT, rel_patch_id);
-               invocation_id = bitcast(bld_base, TGSI_TYPE_FLOAT, invocation_id);
-               tf_lds_offset = bitcast(bld_base, TGSI_TYPE_FLOAT, tf_lds_offset);
-
-               vgpr = SI_TCS_NUM_USER_SGPR + 2;
-               ret = LLVMBuildInsertValue(builder, ret, rel_patch_id, vgpr++, "");
-               ret = LLVMBuildInsertValue(builder, ret, invocation_id, vgpr++, "");
-               ret = LLVMBuildInsertValue(builder, ret, tf_lds_offset, vgpr++, "");
-               ctx->return_value = ret;
-               return;
-       }
+       /* Return epilog parameters from this function. */
+       LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+       LLVMValueRef ret = ctx->return_value;
+       LLVMValueRef rw_buffers, rw0, rw1, tf_soffset;
+       unsigned vgpr;
 
-       si_copy_tcs_inputs(bld_base);
-       si_write_tess_factors(bld_base, rel_patch_id, invocation_id, tf_lds_offset);
+       /* RW_BUFFERS pointer */
+       rw_buffers = LLVMGetParam(ctx->main_fn,
+                                 SI_PARAM_RW_BUFFERS);
+       rw_buffers = LLVMBuildPtrToInt(builder, rw_buffers, ctx->i64, "");
+       rw_buffers = LLVMBuildBitCast(builder, rw_buffers, ctx->v2i32, "");
+       rw0 = LLVMBuildExtractElement(builder, rw_buffers,
+                                     bld_base->uint_bld.zero, "");
+       rw1 = LLVMBuildExtractElement(builder, rw_buffers,
+                                     bld_base->uint_bld.one, "");
+       ret = LLVMBuildInsertValue(builder, ret, rw0, 0, "");
+       ret = LLVMBuildInsertValue(builder, ret, rw1, 1, "");
+
+       /* Tess factor buffer soffset is after user SGPRs. */
+       tf_soffset = LLVMGetParam(ctx->main_fn,
+                                 SI_PARAM_TESS_FACTOR_OFFSET);
+       ret = LLVMBuildInsertValue(builder, ret, tf_soffset,
+                                  SI_TCS_NUM_USER_SGPR + 1, "");
+
+       /* VGPRs */
+       rel_patch_id = bitcast(bld_base, TGSI_TYPE_FLOAT, rel_patch_id);
+       invocation_id = bitcast(bld_base, TGSI_TYPE_FLOAT, invocation_id);
+       tf_lds_offset = bitcast(bld_base, TGSI_TYPE_FLOAT, tf_lds_offset);
+
+       vgpr = SI_TCS_NUM_USER_SGPR + 2;
+       ret = LLVMBuildInsertValue(builder, ret, rel_patch_id, vgpr++, "");
+       ret = LLVMBuildInsertValue(builder, ret, invocation_id, vgpr++, "");
+       ret = LLVMBuildInsertValue(builder, ret, tf_lds_offset, vgpr++, "");
+       ctx->return_value = ret;
 }
 
 static void si_llvm_emit_ls_epilogue(struct lp_build_tgsi_context *bld_base)
@@ -2764,7 +2767,7 @@ static void si_llvm_emit_ls_epilogue(struct lp_build_tgsi_context *bld_base)
        struct tgsi_shader_info *info = &shader->selector->info;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        unsigned i, chan;
-       LLVMValueRef vertex_id = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef vertex_id = LLVMGetParam(ctx->main_fn,
                                              ctx->param_rel_auto_id);
        LLVMValueRef vertex_dw_stride =
                unpack_param(ctx, SI_PARAM_LS_OUT_LAYOUT, 13, 8);
@@ -2774,7 +2777,7 @@ static void si_llvm_emit_ls_epilogue(struct lp_build_tgsi_context *bld_base)
        /* Write outputs to LDS. The next shader (TCS aka HS) will read
         * its inputs from it. */
        for (i = 0; i < info->num_outputs; i++) {
-               LLVMValueRef *out_ptr = ctx->radeon_bld.soa.outputs[i];
+               LLVMValueRef *out_ptr = ctx->outputs[i];
                unsigned name = info->output_semantic_name[i];
                unsigned index = info->output_semantic_index[i];
                int param = si_shader_io_get_unique_index(name, index);
@@ -2794,14 +2797,13 @@ static void si_llvm_emit_es_epilogue(struct lp_build_tgsi_context *bld_base)
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        struct si_shader *es = ctx->shader;
        struct tgsi_shader_info *info = &es->selector->info;
-       LLVMValueRef soffset = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef soffset = LLVMGetParam(ctx->main_fn,
                                            ctx->param_es2gs_offset);
        unsigned chan;
        int i;
 
        for (i = 0; i < info->num_outputs; i++) {
-               LLVMValueRef *out_ptr =
-                       ctx->radeon_bld.soa.outputs[i];
+               LLVMValueRef *out_ptr = ctx->outputs[i];
                int param_index;
 
                if (info->output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX ||
@@ -2834,7 +2836,7 @@ static void si_llvm_emit_gs_epilogue(struct lp_build_tgsi_context *bld_base)
        LLVMValueRef args[2];
 
        args[0] = lp_build_const_int32(gallivm, SENDMSG_GS_OP_NOP | SENDMSG_GS_DONE);
-       args[1] = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_GS_WAVE_ID);
+       args[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_GS_WAVE_ID);
        lp_build_intrinsic(gallivm->builder, "llvm.SI.sendmsg",
                           ctx->voidt, args, 2, 0);
 }
@@ -2847,7 +2849,7 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
        struct si_shader_output_values *outputs = NULL;
        int i,j;
 
-       assert(!ctx->is_gs_copy_shader);
+       assert(!ctx->shader->is_gs_copy_shader);
 
        outputs = MALLOC((info->num_outputs + 1) * sizeof(outputs[0]));
 
@@ -2870,7 +2872,7 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
                        /* We've found a color. */
                        if (!cond) {
                                /* The state is in the first bit of the user SGPR. */
-                               cond = LLVMGetParam(ctx->radeon_bld.main_fn,
+                               cond = LLVMGetParam(ctx->main_fn,
                                                    SI_PARAM_VS_STATE_BITS);
                                cond = LLVMBuildTrunc(gallivm->builder, cond,
                                                      ctx->i1, "");
@@ -2878,9 +2880,9 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
                        }
 
                        for (j = 0; j < 4; j++) {
-                               addr = ctx->radeon_bld.soa.outputs[i][j];
+                               addr = ctx->outputs[i][j];
                                val = LLVMBuildLoad(gallivm->builder, addr, "");
-                               val = radeon_llvm_saturate(bld_base, val);
+                               val = si_llvm_saturate(bld_base, val);
                                LLVMBuildStore(gallivm->builder, val, addr);
                        }
                }
@@ -2890,38 +2892,30 @@ static void si_llvm_emit_vs_epilogue(struct lp_build_tgsi_context *bld_base)
        }
 
        for (i = 0; i < info->num_outputs; i++) {
-               outputs[i].name = info->output_semantic_name[i];
-               outputs[i].sid = info->output_semantic_index[i];
+               outputs[i].semantic_name = info->output_semantic_name[i];
+               outputs[i].semantic_index = info->output_semantic_index[i];
 
-               for (j = 0; j < 4; j++)
+               for (j = 0; j < 4; j++) {
                        outputs[i].values[j] =
                                LLVMBuildLoad(gallivm->builder,
-                                             ctx->radeon_bld.soa.outputs[i][j],
+                                             ctx->outputs[i][j],
                                              "");
-       }
-
-       if (ctx->is_monolithic) {
-               /* Export PrimitiveID when PS needs it. */
-               if (si_vs_exports_prim_id(ctx->shader)) {
-                       outputs[i].name = TGSI_SEMANTIC_PRIMID;
-                       outputs[i].sid = 0;
-                       outputs[i].values[0] = bitcast(bld_base, TGSI_TYPE_FLOAT,
-                                                      get_primitive_id(bld_base, 0));
-                       outputs[i].values[1] = bld_base->base.undef;
-                       outputs[i].values[2] = bld_base->base.undef;
-                       outputs[i].values[3] = bld_base->base.undef;
-                       i++;
+                       outputs[i].vertex_stream[j] =
+                               (info->output_streams[i] >> (2 * j)) & 3;
                }
-       } else {
-               /* Return the primitive ID from the LLVM function. */
-               ctx->return_value =
-                       LLVMBuildInsertValue(gallivm->builder,
-                                            ctx->return_value,
-                                            bitcast(bld_base, TGSI_TYPE_FLOAT,
-                                                    get_primitive_id(bld_base, 0)),
-                                            VS_EPILOG_PRIMID_LOC, "");
+
        }
 
+       /* Return the primitive ID from the LLVM function. */
+       ctx->return_value =
+               LLVMBuildInsertValue(gallivm->builder,
+                                    ctx->return_value,
+                                    bitcast(bld_base, TGSI_TYPE_FLOAT,
+                                            get_primitive_id(bld_base, 0)),
+                                    VS_EPILOG_PRIMID_LOC, "");
+
+       if (ctx->shader->selector->so.num_outputs)
+               si_llvm_emit_streamout(ctx, outputs, i, 0);
        si_llvm_export_vs(bld_base, outputs, i);
        FREE(outputs);
 }
@@ -3009,10 +3003,11 @@ static void si_export_mrt_z(struct lp_build_tgsi_context *bld_base,
                }
        }
 
-       /* SI (except OLAND) has a bug that it only looks
+       /* SI (except OLAND and HAINAN) has a bug that it only looks
         * at the X writemask component. */
        if (ctx->screen->b.chip_class == SI &&
-           ctx->screen->b.family != CHIP_OLAND)
+           ctx->screen->b.family != CHIP_OLAND &&
+           ctx->screen->b.family != CHIP_HAINAN)
                mask |= 0x1;
 
        /* Specify which components to enable */
@@ -3031,31 +3026,31 @@ static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base,
        int i;
 
        /* Clamp color */
-       if (ctx->shader->key.ps.epilog.clamp_color)
+       if (ctx->shader->key.part.ps.epilog.clamp_color)
                for (i = 0; i < 4; i++)
-                       color[i] = radeon_llvm_saturate(bld_base, color[i]);
+                       color[i] = si_llvm_saturate(bld_base, color[i]);
 
        /* Alpha to one */
-       if (ctx->shader->key.ps.epilog.alpha_to_one)
+       if (ctx->shader->key.part.ps.epilog.alpha_to_one)
                color[3] = base->one;
 
        /* Alpha test */
        if (index == 0 &&
-           ctx->shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS)
+           ctx->shader->key.part.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS)
                si_alpha_test(bld_base, color[3]);
 
        /* Line & polygon smoothing */
-       if (ctx->shader->key.ps.epilog.poly_line_smoothing)
+       if (ctx->shader->key.part.ps.epilog.poly_line_smoothing)
                color[3] = si_scale_alpha_by_sample_mask(bld_base, color[3],
                                                         samplemask_param);
 
        /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
-       if (ctx->shader->key.ps.epilog.last_cbuf > 0) {
+       if (ctx->shader->key.part.ps.epilog.last_cbuf > 0) {
                LLVMValueRef args[8][9];
                int c, last = -1;
 
                /* Get the export arguments, also find out what the last one is. */
-               for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) {
+               for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; c++) {
                        si_llvm_init_export_args(bld_base, color,
                                                 V_008DFC_SQ_EXP_MRT + c, args[c]);
                        if (args[c][0] != bld_base->uint_bld.zero)
@@ -3063,7 +3058,7 @@ static void si_export_mrt_color(struct lp_build_tgsi_context *bld_base,
                }
 
                /* Emit all exports. */
-               for (c = 0; c <= ctx->shader->key.ps.epilog.last_cbuf; c++) {
+               for (c = 0; c <= ctx->shader->key.part.ps.epilog.last_cbuf; c++) {
                        if (is_last && last == c) {
                                args[c][1] = bld_base->uint_bld.one; /* whether the EXEC mask is valid */
                                args[c][2] = bld_base->uint_bld.one; /* DONE bit */
@@ -3092,7 +3087,7 @@ static void si_emit_ps_exports(struct si_shader_context *ctx,
                               struct si_ps_exports *exp)
 {
        for (unsigned i = 0; i < exp->num; i++)
-               lp_build_intrinsic(ctx->radeon_bld.gallivm.builder,
+               lp_build_intrinsic(ctx->gallivm.builder,
                                   "llvm.SI.export", ctx->voidt,
                                   exp->args[i], 9, 0);
 }
@@ -3118,125 +3113,33 @@ static void si_export_null(struct lp_build_tgsi_context *bld_base)
                           ctx->voidt, args, 9, 0);
 }
 
-static void si_llvm_emit_fs_epilogue(struct lp_build_tgsi_context *bld_base)
+/**
+ * Return PS outputs in this order:
+ *
+ * v[0:3] = color0.xyzw
+ * v[4:7] = color1.xyzw
+ * ...
+ * vN+0 = Depth
+ * vN+1 = Stencil
+ * vN+2 = SampleMask
+ * vN+3 = SampleMaskIn (used for OpenGL smoothing)
+ *
+ * The alpha-ref SGPR is returned via its original location.
+ */
+static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
        struct lp_build_context *base = &bld_base->base;
        struct tgsi_shader_info *info = &shader->selector->info;
        LLVMBuilderRef builder = base->gallivm->builder;
-       LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
-       int last_color_export = -1;
-       int i;
-       struct si_ps_exports exp = {};
-
-       /* Determine the last export. If MRTZ is present, it's always last.
-        * Otherwise, find the last color export.
-        */
-       if (!info->writes_z && !info->writes_stencil && !info->writes_samplemask) {
-               unsigned spi_format = shader->key.ps.epilog.spi_shader_col_format;
-
-               /* Don't export NULL and return if alpha-test is enabled. */
-               if (shader->key.ps.epilog.alpha_func != PIPE_FUNC_ALWAYS &&
-                   shader->key.ps.epilog.alpha_func != PIPE_FUNC_NEVER &&
-                   (spi_format & 0xf) == 0)
-                       spi_format |= V_028714_SPI_SHADER_32_AR;
-
-               for (i = 0; i < info->num_outputs; i++) {
-                       unsigned index = info->output_semantic_index[i];
-
-                       if (info->output_semantic_name[i] != TGSI_SEMANTIC_COLOR)
-                               continue;
-
-                       /* If last_cbuf > 0, FS_COLOR0_WRITES_ALL_CBUFS is true. */
-                       if (shader->key.ps.epilog.last_cbuf > 0) {
-                               /* Just set this if any of the colorbuffers are enabled. */
-                               if (spi_format &
-                                   ((1llu << (4 * (shader->key.ps.epilog.last_cbuf + 1))) - 1))
-                                       last_color_export = i;
-                               continue;
-                       }
-
-                       if ((spi_format >> (index * 4)) & 0xf)
-                               last_color_export = i;
-               }
+       unsigned i, j, first_vgpr, vgpr;
 
-               /* If there are no outputs, export NULL. */
-               if (last_color_export == -1) {
-                       si_export_null(bld_base);
-                       return;
-               }
-       }
+       LLVMValueRef color[8][4] = {};
+       LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
+       LLVMValueRef ret;
 
-       for (i = 0; i < info->num_outputs; i++) {
-               unsigned semantic_name = info->output_semantic_name[i];
-               unsigned semantic_index = info->output_semantic_index[i];
-               unsigned j;
-               LLVMValueRef color[4] = {};
-
-               /* Select the correct target */
-               switch (semantic_name) {
-               case TGSI_SEMANTIC_POSITION:
-                       depth = LLVMBuildLoad(builder,
-                                             ctx->radeon_bld.soa.outputs[i][2], "");
-                       break;
-               case TGSI_SEMANTIC_STENCIL:
-                       stencil = LLVMBuildLoad(builder,
-                                               ctx->radeon_bld.soa.outputs[i][1], "");
-                       break;
-               case TGSI_SEMANTIC_SAMPLEMASK:
-                       samplemask = LLVMBuildLoad(builder,
-                                                  ctx->radeon_bld.soa.outputs[i][0], "");
-                       break;
-               case TGSI_SEMANTIC_COLOR:
-                       for (j = 0; j < 4; j++)
-                               color[j] = LLVMBuildLoad(builder,
-                                                        ctx->radeon_bld.soa.outputs[i][j], "");
-
-                       si_export_mrt_color(bld_base, color, semantic_index,
-                                           SI_PARAM_SAMPLE_COVERAGE,
-                                           last_color_export == i, &exp);
-                       break;
-               default:
-                       fprintf(stderr,
-                               "Warning: SI unhandled fs output type:%d\n",
-                               semantic_name);
-               }
-       }
-
-       if (depth || stencil || samplemask)
-               si_export_mrt_z(bld_base, depth, stencil, samplemask, &exp);
-
-       si_emit_ps_exports(ctx, &exp);
-}
-
-/**
- * Return PS outputs in this order:
- *
- * v[0:3] = color0.xyzw
- * v[4:7] = color1.xyzw
- * ...
- * vN+0 = Depth
- * vN+1 = Stencil
- * vN+2 = SampleMask
- * vN+3 = SampleMaskIn (used for OpenGL smoothing)
- *
- * The alpha-ref SGPR is returned via its original location.
- */
-static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
-{
-       struct si_shader_context *ctx = si_shader_context(bld_base);
-       struct si_shader *shader = ctx->shader;
-       struct lp_build_context *base = &bld_base->base;
-       struct tgsi_shader_info *info = &shader->selector->info;
-       LLVMBuilderRef builder = base->gallivm->builder;
-       unsigned i, j, first_vgpr, vgpr;
-
-       LLVMValueRef color[8][4] = {};
-       LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
-       LLVMValueRef ret;
-
-       /* Read the output values. */
+       /* Read the output values. */
        for (i = 0; i < info->num_outputs; i++) {
                unsigned semantic_name = info->output_semantic_name[i];
                unsigned semantic_index = info->output_semantic_index[i];
@@ -3245,22 +3148,22 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
                case TGSI_SEMANTIC_COLOR:
                        assert(semantic_index < 8);
                        for (j = 0; j < 4; j++) {
-                               LLVMValueRef ptr = ctx->radeon_bld.soa.outputs[i][j];
+                               LLVMValueRef ptr = ctx->outputs[i][j];
                                LLVMValueRef result = LLVMBuildLoad(builder, ptr, "");
                                color[semantic_index][j] = result;
                        }
                        break;
                case TGSI_SEMANTIC_POSITION:
                        depth = LLVMBuildLoad(builder,
-                                             ctx->radeon_bld.soa.outputs[i][2], "");
+                                             ctx->outputs[i][2], "");
                        break;
                case TGSI_SEMANTIC_STENCIL:
                        stencil = LLVMBuildLoad(builder,
-                                               ctx->radeon_bld.soa.outputs[i][1], "");
+                                               ctx->outputs[i][1], "");
                        break;
                case TGSI_SEMANTIC_SAMPLEMASK:
                        samplemask = LLVMBuildLoad(builder,
-                                                  ctx->radeon_bld.soa.outputs[i][0], "");
+                                                  ctx->outputs[i][0], "");
                        break;
                default:
                        fprintf(stderr, "Warning: SI unhandled fs output type:%d\n",
@@ -3274,7 +3177,7 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
        /* Set SGPRs. */
        ret = LLVMBuildInsertValue(builder, ret,
                                   bitcast(bld_base, TGSI_TYPE_SIGNED,
-                                          LLVMGetParam(ctx->radeon_bld.main_fn,
+                                          LLVMGetParam(ctx->main_fn,
                                                        SI_PARAM_ALPHA_REF)),
                                   SI_SGPR_ALPHA_REF, "");
 
@@ -3298,7 +3201,7 @@ static void si_llvm_return_fs_outputs(struct lp_build_tgsi_context *bld_base)
        if (vgpr < first_vgpr + PS_EPILOG_SAMPLEMASK_MIN_LOC)
                vgpr = first_vgpr + PS_EPILOG_SAMPLEMASK_MIN_LOC;
        ret = LLVMBuildInsertValue(builder, ret,
-                                  LLVMGetParam(ctx->radeon_bld.main_fn,
+                                  LLVMGetParam(ctx->main_fn,
                                                SI_PARAM_SAMPLE_COVERAGE), vgpr++, "");
 
        ctx->return_value = ret;
@@ -3317,7 +3220,7 @@ static LLVMValueRef get_buffer_size(
        LLVMBuilderRef builder = gallivm->builder;
        LLVMValueRef size =
                LLVMBuildExtractElement(builder, descriptor,
-                                       lp_build_const_int32(gallivm, 6), "");
+                                       lp_build_const_int32(gallivm, 2), "");
 
        if (ctx->screen->b.chip_class >= VI) {
                /* On VI, the descriptor contains the size in bytes,
@@ -3326,7 +3229,7 @@ static LLVMValueRef get_buffer_size(
                 */
                LLVMValueRef stride =
                        LLVMBuildExtractElement(builder, descriptor,
-                                               lp_build_const_int32(gallivm, 5), "");
+                                               lp_build_const_int32(gallivm, 1), "");
                stride = LLVMBuildLShr(builder, stride,
                                       lp_build_const_int32(gallivm, 16), "");
                stride = LLVMBuildAnd(builder, stride,
@@ -3342,17 +3245,39 @@ static LLVMValueRef get_buffer_size(
  * Given the i32 or vNi32 \p type, generate the textual name (e.g. for use with
  * intrinsic names).
  */
-static void build_int_type_name(
+static void build_type_name_for_intr(
        LLVMTypeRef type,
        char *buf, unsigned bufsize)
 {
-       assert(bufsize >= 6);
+       LLVMTypeRef elem_type = type;
 
-       if (LLVMGetTypeKind(type) == LLVMVectorTypeKind)
-               snprintf(buf, bufsize, "v%ui32",
-                        LLVMGetVectorSize(type));
-       else
-               strcpy(buf, "i32");
+       assert(bufsize >= 8);
+
+       if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
+               int ret = snprintf(buf, bufsize, "v%u",
+                                       LLVMGetVectorSize(type));
+               if (ret < 0) {
+                       char *type_name = LLVMPrintTypeToString(type);
+                       fprintf(stderr, "Error building type name for: %s\n",
+                               type_name);
+                       return;
+               }
+               elem_type = LLVMGetElementType(type);
+               buf += ret;
+               bufsize -= ret;
+       }
+       switch (LLVMGetTypeKind(elem_type)) {
+       default: break;
+       case LLVMIntegerTypeKind:
+               snprintf(buf, bufsize, "i%d", LLVMGetIntTypeWidth(elem_type));
+               break;
+       case LLVMFloatTypeKind:
+               snprintf(buf, bufsize, "f32");
+               break;
+       case LLVMDoubleTypeKind:
+               snprintf(buf, bufsize, "f64");
+               break;
+       }
 }
 
 static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
@@ -3363,20 +3288,27 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
  * point in the program by emitting empty inline assembly that is marked as
  * having side effects.
  */
+#if 0 /* unused currently */
 static void emit_optimization_barrier(struct si_shader_context *ctx)
 {
-       LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
+       LLVMBuilderRef builder = ctx->gallivm.builder;
        LLVMTypeRef ftype = LLVMFunctionType(ctx->voidt, NULL, 0, false);
        LLVMValueRef inlineasm = LLVMConstInlineAsm(ftype, "", "", true, false);
        LLVMBuildCall(builder, inlineasm, NULL, 0, "");
 }
+#endif
+
+/* Combine these with & instead of |. */
+#define NOOP_WAITCNT 0xf7f
+#define LGKM_CNT 0x07f
+#define VM_CNT 0xf70
 
-static void emit_waitcnt(struct si_shader_context *ctx)
+static void emit_waitcnt(struct si_shader_context *ctx, unsigned simm16)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        LLVMValueRef args[1] = {
-               lp_build_const_int32(gallivm, 0xf70)
+               lp_build_const_int32(gallivm, simm16)
        };
        lp_build_intrinsic(builder, "llvm.amdgcn.s.waitcnt",
                           ctx->voidt, args, 1, 0);
@@ -3388,8 +3320,23 @@ static void membar_emit(
                struct lp_build_emit_data *emit_data)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
+       LLVMValueRef src0 = lp_build_emit_fetch(bld_base, emit_data->inst, 0, 0);
+       unsigned flags = LLVMConstIntGetZExtValue(src0);
+       unsigned waitcnt = NOOP_WAITCNT;
+
+       if (flags & TGSI_MEMBAR_THREAD_GROUP)
+               waitcnt &= VM_CNT & LGKM_CNT;
+
+       if (flags & (TGSI_MEMBAR_ATOMIC_BUFFER |
+                    TGSI_MEMBAR_SHADER_BUFFER |
+                    TGSI_MEMBAR_SHADER_IMAGE))
+               waitcnt &= VM_CNT;
 
-       emit_waitcnt(ctx);
+       if (flags & TGSI_MEMBAR_SHARED)
+               waitcnt &= LGKM_CNT;
+
+       if (waitcnt != NOOP_WAITCNT)
+               emit_waitcnt(ctx, waitcnt);
 }
 
 static LLVMValueRef
@@ -3397,7 +3344,7 @@ shader_buffer_fetch_rsrc(struct si_shader_context *ctx,
                         const struct tgsi_full_src_register *reg)
 {
        LLVMValueRef index;
-       LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->main_fn,
                                             SI_PARAM_SHADER_BUFFERS);
 
        if (!reg->Register.Indirect)
@@ -3448,7 +3395,7 @@ static LLVMValueRef force_dcc_off(struct si_shader_context *ctx,
        if (ctx->screen->b.chip_class <= CIK) {
                return rsrc;
        } else {
-               LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
+               LLVMBuilderRef builder = ctx->gallivm.builder;
                LLVMValueRef i32_6 = LLVMConstInt(ctx->i32, 6, 0);
                LLVMValueRef i32_C = LLVMConstInt(ctx->i32, C_008F28_COMPRESSION_EN, 0);
                LLVMValueRef tmp;
@@ -3459,6 +3406,12 @@ static LLVMValueRef force_dcc_off(struct si_shader_context *ctx,
        }
 }
 
+static LLVMTypeRef const_array(LLVMTypeRef elem_type, int num_elements)
+{
+       return LLVMPointerType(LLVMArrayType(elem_type, num_elements),
+                              CONST_ADDR_SPACE);
+}
+
 /**
  * Load the resource descriptor for \p image.
  */
@@ -3466,13 +3419,14 @@ static void
 image_fetch_rsrc(
        struct lp_build_tgsi_context *bld_base,
        const struct tgsi_full_src_register *image,
-       bool dcc_off,
+       bool is_store, unsigned target,
        LLVMValueRef *rsrc)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->main_fn,
                                             SI_PARAM_IMAGES);
        LLVMValueRef index, tmp;
+       bool dcc_off = target != TGSI_TEXTURE_BUFFER && is_store;
 
        assert(image->Register.File == TGSI_FILE_IMAGE);
 
@@ -3482,7 +3436,7 @@ image_fetch_rsrc(
                index = LLVMConstInt(ctx->i32, image->Register.Index, 0);
 
                if (info->images_writemask & (1 << image->Register.Index) &&
-                   !(info->images_buffers & (1 << image->Register.Index)))
+                   target != TGSI_TEXTURE_BUFFER)
                        dcc_off = true;
        } else {
                /* From the GL_ARB_shader_image_load_store extension spec:
@@ -3499,6 +3453,19 @@ image_fetch_rsrc(
                                                   SI_NUM_IMAGES);
        }
 
+       if (target == TGSI_TEXTURE_BUFFER) {
+               LLVMBuilderRef builder = ctx->gallivm.builder;
+
+               rsrc_ptr = LLVMBuildPointerCast(builder, rsrc_ptr,
+                                               const_array(ctx->v4i32, 0), "");
+               index = LLVMBuildMul(builder, index,
+                                    LLVMConstInt(ctx->i32, 2, 0), "");
+               index = LLVMBuildAdd(builder, index,
+                                    LLVMConstInt(ctx->i32, 1, 0), "");
+               *rsrc = build_indexed_load_const(ctx, rsrc_ptr, index);
+               return;
+       }
+
        tmp = build_indexed_load_const(ctx, rsrc_ptr, index);
        if (dcc_off)
                tmp = force_dcc_off(ctx, tmp);
@@ -3543,40 +3510,36 @@ static void image_append_args(
                struct si_shader_context *ctx,
                struct lp_build_emit_data * emit_data,
                unsigned target,
-               bool atomic)
+               bool atomic,
+               bool force_glc)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        LLVMValueRef i1false = LLVMConstInt(ctx->i1, 0, 0);
        LLVMValueRef i1true = LLVMConstInt(ctx->i1, 1, 0);
-
-       emit_data->args[emit_data->arg_count++] = i1false; /* r128 */
-       emit_data->args[emit_data->arg_count++] =
-               tgsi_is_array_image(target) ? i1true : i1false; /* da */
-       if (!atomic) {
-               emit_data->args[emit_data->arg_count++] =
-                       inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | TGSI_MEMORY_VOLATILE) ?
-                       i1true : i1false; /* glc */
+       LLVMValueRef r128 = i1false;
+       LLVMValueRef da = tgsi_is_array_image(target) ? i1true : i1false;
+       LLVMValueRef glc =
+               force_glc ||
+               inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | TGSI_MEMORY_VOLATILE) ?
+               i1true : i1false;
+       LLVMValueRef slc = i1false;
+       LLVMValueRef lwe = i1false;
+
+       if (atomic || (HAVE_LLVM <= 0x0309)) {
+               emit_data->args[emit_data->arg_count++] = r128;
+               emit_data->args[emit_data->arg_count++] = da;
+               if (!atomic) {
+                       emit_data->args[emit_data->arg_count++] = glc;
+               }
+               emit_data->args[emit_data->arg_count++] = slc;
+               return;
        }
-       emit_data->args[emit_data->arg_count++] = i1false; /* slc */
-}
 
-/**
- * Given a 256 bit resource, extract the top half (which stores the buffer
- * resource in the case of textures and images).
- */
-static LLVMValueRef extract_rsrc_top_half(
-               struct si_shader_context *ctx,
-               LLVMValueRef rsrc)
-{
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
-       LLVMTypeRef v2i128 = LLVMVectorType(ctx->i128, 2);
-
-       rsrc = LLVMBuildBitCast(gallivm->builder, rsrc, v2i128, "");
-       rsrc = LLVMBuildExtractElement(gallivm->builder, rsrc, bld_base->uint_bld.one, "");
-       rsrc = LLVMBuildBitCast(gallivm->builder, rsrc, ctx->v4i32, "");
-
-       return rsrc;
+       /* HAVE_LLVM >= 0x0400 */
+       emit_data->args[emit_data->arg_count++] = glc;
+       emit_data->args[emit_data->arg_count++] = slc;
+       emit_data->args[emit_data->arg_count++] = lwe;
+       emit_data->args[emit_data->arg_count++] = da;
 }
 
 /**
@@ -3592,7 +3555,8 @@ static void buffer_append_args(
                LLVMValueRef rsrc,
                LLVMValueRef index,
                LLVMValueRef offset,
-               bool atomic)
+               bool atomic,
+               bool force_glc)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        LLVMValueRef i1false = LLVMConstInt(ctx->i1, 0, 0);
@@ -3603,6 +3567,7 @@ static void buffer_append_args(
        emit_data->args[emit_data->arg_count++] = offset; /* voffset */
        if (!atomic) {
                emit_data->args[emit_data->arg_count++] =
+                       force_glc ||
                        inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | TGSI_MEMORY_VOLATILE) ?
                        i1true : i1false; /* glc */
        }
@@ -3632,24 +3597,23 @@ static void load_fetch_args(
                offset = LLVMBuildBitCast(builder, tmp, bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, bld_base->uint_bld.zero,
-                                  offset, false);
+                                  offset, false, false);
        } else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
                LLVMValueRef coords;
 
-               image_fetch_rsrc(bld_base, &inst->Src[0], false, &rsrc);
+               image_fetch_rsrc(bld_base, &inst->Src[0], false, target, &rsrc);
                coords = image_fetch_coords(bld_base, inst, 1);
 
                if (target == TGSI_TEXTURE_BUFFER) {
-                       rsrc = extract_rsrc_top_half(ctx, rsrc);
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                       bld_base->uint_bld.zero, false);
+                                          bld_base->uint_bld.zero, false, false);
                } else {
                        emit_data->args[0] = coords;
                        emit_data->args[1] = rsrc;
                        emit_data->args[2] = lp_build_const_int32(gallivm, 15); /* dmask */
                        emit_data->arg_count = 3;
 
-                       image_append_args(ctx, emit_data, target, false);
+                       image_append_args(ctx, emit_data, target, false, false);
                }
        }
 }
@@ -3658,7 +3622,7 @@ static void load_emit_buffer(struct si_shader_context *ctx,
                             struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        uint writemask = inst->Dst[0].Register.WriteMask;
        uint count = util_last_bit(writemask);
@@ -3683,19 +3647,19 @@ static void load_emit_buffer(struct si_shader_context *ctx,
        emit_data->output[emit_data->chan] = lp_build_intrinsic(
                        builder, intrinsic_name, dst_type,
                        emit_data->args, emit_data->arg_count,
-                       LLVMReadOnlyAttribute);
+                       LP_FUNC_ATTR_READONLY);
 }
 
 static LLVMValueRef get_memory_ptr(struct si_shader_context *ctx,
                                    const struct tgsi_full_instruction *inst,
                                    LLVMTypeRef type, int arg)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        LLVMValueRef offset, ptr;
        int addr_space;
 
-       offset = lp_build_emit_fetch(&ctx->radeon_bld.soa.bld_base, inst, arg, 0);
+       offset = lp_build_emit_fetch(&ctx->bld_base, inst, arg, 0);
        offset = LLVMBuildBitCast(builder, offset, ctx->i32, "");
 
        ptr = ctx->shared_memory;
@@ -3711,8 +3675,8 @@ static void load_emit_memory(
                struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
-       struct lp_build_context *base = &ctx->radeon_bld.soa.bld_base.base;
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct lp_build_context *base = &ctx->bld_base.base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        unsigned writemask = inst->Dst[0].Register.WriteMask;
        LLVMValueRef channels[4], ptr, derived_ptr, index;
@@ -3733,6 +3697,32 @@ static void load_emit_memory(
        emit_data->output[emit_data->chan] = lp_build_gather_values(gallivm, channels, 4);
 }
 
+static void get_image_intr_name(const char *base_name,
+                               LLVMTypeRef data_type,
+                               LLVMTypeRef coords_type,
+                               LLVMTypeRef rsrc_type,
+                               char *out_name, unsigned out_len)
+{
+       char coords_type_name[8];
+
+       build_type_name_for_intr(coords_type, coords_type_name,
+                           sizeof(coords_type_name));
+
+       if (HAVE_LLVM <= 0x0309) {
+               snprintf(out_name, out_len, "%s.%s", base_name, coords_type_name);
+       } else {
+               char data_type_name[8];
+               char rsrc_type_name[8];
+
+               build_type_name_for_intr(data_type, data_type_name,
+                                       sizeof(data_type_name));
+               build_type_name_for_intr(rsrc_type, rsrc_type_name,
+                                       sizeof(rsrc_type_name));
+               snprintf(out_name, out_len, "%s.%s.%s.%s", base_name,
+                        data_type_name, coords_type_name, rsrc_type_name);
+       }
+}
+
 static void load_emit(
                const struct lp_build_tgsi_action *action,
                struct lp_build_tgsi_context *bld_base,
@@ -3742,8 +3732,7 @@ static void load_emit(
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
-       char intrinsic_name[32];
-       char coords_type[8];
+       char intrinsic_name[64];
 
        if (inst->Src[0].Register.File == TGSI_FILE_MEMORY) {
                load_emit_memory(ctx, emit_data);
@@ -3751,7 +3740,7 @@ static void load_emit(
        }
 
        if (inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE)
-               emit_waitcnt(ctx);
+               emit_waitcnt(ctx, VM_CNT);
 
        if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
                load_emit_buffer(ctx, emit_data);
@@ -3763,19 +3752,19 @@ static void load_emit(
                        lp_build_intrinsic(
                                builder, "llvm.amdgcn.buffer.load.format.v4f32", emit_data->dst_type,
                                emit_data->args, emit_data->arg_count,
-                               LLVMReadOnlyAttribute);
+                               LP_FUNC_ATTR_READONLY);
        } else {
-               build_int_type_name(LLVMTypeOf(emit_data->args[0]),
-                                   coords_type, sizeof(coords_type));
-
-               snprintf(intrinsic_name, sizeof(intrinsic_name),
-                        "llvm.amdgcn.image.load.%s", coords_type);
+               get_image_intr_name("llvm.amdgcn.image.load",
+                               emit_data->dst_type,            /* vdata */
+                               LLVMTypeOf(emit_data->args[0]), /* coords */
+                               LLVMTypeOf(emit_data->args[1]), /* rsrc */
+                               intrinsic_name, sizeof(intrinsic_name));
 
                emit_data->output[emit_data->chan] =
                        lp_build_intrinsic(
                                builder, intrinsic_name, emit_data->dst_type,
                                emit_data->args, emit_data->arg_count,
-                               LLVMReadOnlyAttribute);
+                               LP_FUNC_ATTR_READONLY);
        }
 }
 
@@ -3814,26 +3803,33 @@ static void store_fetch_args(
                offset = LLVMBuildBitCast(builder, tmp, bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, bld_base->uint_bld.zero,
-                                  offset, false);
+                                  offset, false, false);
        } else if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE) {
                unsigned target = inst->Memory.Texture;
                LLVMValueRef coords;
 
+               /* 8bit/16bit TC L1 write corruption bug on SI.
+                * All store opcodes not aligned to a dword are affected.
+                *
+                * The only way to get unaligned stores in radeonsi is through
+                * shader images.
+                */
+               bool force_glc = ctx->screen->b.chip_class == SI;
+
                coords = image_fetch_coords(bld_base, inst, 0);
 
                if (target == TGSI_TEXTURE_BUFFER) {
-                       image_fetch_rsrc(bld_base, &memory, false, &rsrc);
-
-                       rsrc = extract_rsrc_top_half(ctx, rsrc);
+                       image_fetch_rsrc(bld_base, &memory, true, target, &rsrc);
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                       bld_base->uint_bld.zero, false);
+                                          bld_base->uint_bld.zero, false, force_glc);
                } else {
                        emit_data->args[1] = coords;
-                       image_fetch_rsrc(bld_base, &memory, true, &emit_data->args[2]);
+                       image_fetch_rsrc(bld_base, &memory, true, target,
+                                        &emit_data->args[2]);
                        emit_data->args[3] = lp_build_const_int32(gallivm, 15); /* dmask */
                        emit_data->arg_count = 4;
 
-                       image_append_args(ctx, emit_data, target, false);
+                       image_append_args(ctx, emit_data, target, false, force_glc);
                }
        }
 }
@@ -3843,9 +3839,9 @@ static void store_emit_buffer(
                struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
-       struct lp_build_context *uint_bld = &ctx->radeon_bld.soa.bld_base.uint_bld;
+       struct lp_build_context *uint_bld = &ctx->bld_base.uint_bld;
        LLVMValueRef base_data = emit_data->args[0];
        LLVMValueRef base_offset = emit_data->args[3];
        unsigned writemask = inst->Dst[0].Register.WriteMask;
@@ -3915,8 +3911,8 @@ static void store_emit_memory(
                struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
-       struct lp_build_context *base = &ctx->radeon_bld.soa.bld_base.base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       struct lp_build_context *base = &ctx->bld_base.base;
        LLVMBuilderRef builder = gallivm->builder;
        unsigned writemask = inst->Dst[0].Register.WriteMask;
        LLVMValueRef ptr, derived_ptr, data, index;
@@ -3928,7 +3924,7 @@ static void store_emit_memory(
                if (!(writemask & (1 << chan))) {
                        continue;
                }
-               data = lp_build_emit_fetch(&ctx->radeon_bld.soa.bld_base, inst, 1, chan);
+               data = lp_build_emit_fetch(&ctx->bld_base, inst, 1, chan);
                index = lp_build_const_int32(gallivm, chan);
                derived_ptr = LLVMBuildGEP(builder, ptr, &index, 1, "");
                LLVMBuildStore(builder, data, derived_ptr);
@@ -3945,8 +3941,7 @@ static void store_emit(
        LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        unsigned target = inst->Memory.Texture;
-       char intrinsic_name[32];
-       char coords_type[8];
+       char intrinsic_name[64];
 
        if (inst->Dst[0].Register.File == TGSI_FILE_MEMORY) {
                store_emit_memory(ctx, emit_data);
@@ -3954,7 +3949,7 @@ static void store_emit(
        }
 
        if (inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE)
-               emit_waitcnt(ctx);
+               emit_waitcnt(ctx, VM_CNT);
 
        if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER) {
                store_emit_buffer(ctx, emit_data);
@@ -3967,10 +3962,11 @@ static void store_emit(
                        emit_data->dst_type, emit_data->args,
                        emit_data->arg_count, 0);
        } else {
-               build_int_type_name(LLVMTypeOf(emit_data->args[1]),
-                                   coords_type, sizeof(coords_type));
-               snprintf(intrinsic_name, sizeof(intrinsic_name),
-                        "llvm.amdgcn.image.store.%s", coords_type);
+               get_image_intr_name("llvm.amdgcn.image.store",
+                               LLVMTypeOf(emit_data->args[0]), /* vdata */
+                               LLVMTypeOf(emit_data->args[1]), /* coords */
+                               LLVMTypeOf(emit_data->args[2]), /* rsrc */
+                               intrinsic_name, sizeof(intrinsic_name));
 
                emit_data->output[emit_data->chan] =
                        lp_build_intrinsic(
@@ -4017,43 +4013,41 @@ static void atomic_fetch_args(
                offset = LLVMBuildBitCast(builder, tmp, bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, bld_base->uint_bld.zero,
-                                  offset, true);
+                                  offset, true, false);
        } else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
                unsigned target = inst->Memory.Texture;
                LLVMValueRef coords;
 
-               image_fetch_rsrc(bld_base, &inst->Src[0],
-                                target != TGSI_TEXTURE_BUFFER, &rsrc);
+               image_fetch_rsrc(bld_base, &inst->Src[0], true, target, &rsrc);
                coords = image_fetch_coords(bld_base, inst, 1);
 
                if (target == TGSI_TEXTURE_BUFFER) {
-                       rsrc = extract_rsrc_top_half(ctx, rsrc);
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                          bld_base->uint_bld.zero, true);
+                                          bld_base->uint_bld.zero, true, false);
                } else {
                        emit_data->args[emit_data->arg_count++] = coords;
                        emit_data->args[emit_data->arg_count++] = rsrc;
 
-                       image_append_args(ctx, emit_data, target, true);
+                       image_append_args(ctx, emit_data, target, true, false);
                }
        }
 }
 
 static void atomic_emit_memory(struct si_shader_context *ctx,
                                struct lp_build_emit_data *emit_data) {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        LLVMValueRef ptr, result, arg;
 
        ptr = get_memory_ptr(ctx, inst, ctx->i32, 1);
 
-       arg = lp_build_emit_fetch(&ctx->radeon_bld.soa.bld_base, inst, 2, 0);
+       arg = lp_build_emit_fetch(&ctx->bld_base, inst, 2, 0);
        arg = LLVMBuildBitCast(builder, arg, ctx->i32, "");
 
        if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS) {
                LLVMValueRef new_data;
-               new_data = lp_build_emit_fetch(&ctx->radeon_bld.soa.bld_base,
+               new_data = lp_build_emit_fetch(&ctx->bld_base,
                                               inst, 3, 0);
 
                new_data = LLVMBuildBitCast(builder, new_data, ctx->i32, "");
@@ -4130,10 +4124,15 @@ static void atomic_emit(
                snprintf(intrinsic_name, sizeof(intrinsic_name),
                         "llvm.amdgcn.buffer.atomic.%s", action->intr_name);
        } else {
+               LLVMValueRef coords;
                char coords_type[8];
 
-               build_int_type_name(LLVMTypeOf(emit_data->args[1]),
-                                   coords_type, sizeof(coords_type));
+               if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS)
+                       coords = emit_data->args[2];
+               else
+                       coords = emit_data->args[1];
+
+               build_type_name_for_intr(LLVMTypeOf(coords), coords_type, sizeof(coords_type));
                snprintf(intrinsic_name, sizeof(intrinsic_name),
                         "llvm.amdgcn.image.atomic.%s.%s",
                         action->intr_name, coords_type);
@@ -4161,11 +4160,13 @@ static void resq_fetch_args(
                emit_data->args[0] = shader_buffer_fetch_rsrc(ctx, reg);
                emit_data->arg_count = 1;
        } else if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
-               image_fetch_rsrc(bld_base, reg, false, &emit_data->args[0]);
+               image_fetch_rsrc(bld_base, reg, false, inst->Memory.Texture,
+                                &emit_data->args[0]);
                emit_data->arg_count = 1;
        } else {
                emit_data->args[0] = bld_base->uint_bld.zero; /* mip level */
-               image_fetch_rsrc(bld_base, reg, false, &emit_data->args[1]);
+               image_fetch_rsrc(bld_base, reg, false, inst->Memory.Texture,
+                                &emit_data->args[1]);
                emit_data->args[2] = lp_build_const_int32(gallivm, 15); /* dmask */
                emit_data->args[3] = bld_base->uint_bld.zero; /* unorm */
                emit_data->args[4] = bld_base->uint_bld.zero; /* r128 */
@@ -4198,7 +4199,7 @@ static void resq_emit(
                out = lp_build_intrinsic(
                        builder, "llvm.SI.getresinfo.i32", emit_data->dst_type,
                        emit_data->args, emit_data->arg_count,
-                       LLVMReadNoneAttribute);
+                       LP_FUNC_ATTR_READNONE);
 
                /* Divide the number of layers by 6 to get the number of cubes. */
                if (inst->Memory.Texture == TGSI_TEXTURE_CUBE_ARRAY) {
@@ -4221,7 +4222,7 @@ static void set_tex_fetch_args(struct si_shader_context *ctx,
                               LLVMValueRef *param, unsigned count,
                               unsigned dmask)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        unsigned num_args;
        unsigned is_rect = target == TGSI_TEXTURE_RECT;
 
@@ -4264,16 +4265,11 @@ static const struct lp_build_tgsi_action tex_action;
 
 enum desc_type {
        DESC_IMAGE,
+       DESC_BUFFER,
        DESC_FMASK,
-       DESC_SAMPLER
+       DESC_SAMPLER,
 };
 
-static LLVMTypeRef const_array(LLVMTypeRef elem_type, int num_elements)
-{
-       return LLVMPointerType(LLVMArrayType(elem_type, num_elements),
-                              CONST_ADDR_SPACE);
-}
-
 /**
  * Load an image view, fmask view. or sampler state descriptor.
  */
@@ -4281,7 +4277,7 @@ static LLVMValueRef load_sampler_desc_custom(struct si_shader_context *ctx,
                                             LLVMValueRef list, LLVMValueRef index,
                                             enum desc_type type)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
 
        switch (type) {
@@ -4289,6 +4285,13 @@ static LLVMValueRef load_sampler_desc_custom(struct si_shader_context *ctx,
                /* The image is at [0:7]. */
                index = LLVMBuildMul(builder, index, LLVMConstInt(ctx->i32, 2, 0), "");
                break;
+       case DESC_BUFFER:
+               /* The buffer is in [4:7]. */
+               index = LLVMBuildMul(builder, index, LLVMConstInt(ctx->i32, 4, 0), "");
+               index = LLVMBuildAdd(builder, index, LLVMConstInt(ctx->i32, 1, 0), "");
+               list = LLVMBuildPointerCast(builder, list,
+                                           const_array(ctx->v4i32, 0), "");
+               break;
        case DESC_FMASK:
                /* The FMASK is at [8:15]. */
                index = LLVMBuildMul(builder, index, LLVMConstInt(ctx->i32, 2, 0), "");
@@ -4309,7 +4312,7 @@ static LLVMValueRef load_sampler_desc_custom(struct si_shader_context *ctx,
 static LLVMValueRef load_sampler_desc(struct si_shader_context *ctx,
                                     LLVMValueRef index, enum desc_type type)
 {
-       LLVMValueRef list = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef list = LLVMGetParam(ctx->main_fn,
                                         SI_PARAM_SAMPLERS);
 
        return load_sampler_desc_custom(ctx, list, index, type);
@@ -4329,7 +4332,7 @@ static LLVMValueRef load_sampler_desc(struct si_shader_context *ctx,
 static LLVMValueRef sici_fix_sampler_aniso(struct si_shader_context *ctx,
                                           LLVMValueRef res, LLVMValueRef samp)
 {
-       LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
+       LLVMBuilderRef builder = ctx->gallivm.builder;
        LLVMValueRef img7, samp0;
 
        if (ctx->screen->b.chip_class >= VI)
@@ -4370,21 +4373,25 @@ static void tex_fetch_ptrs(
                index = LLVMConstInt(ctx->i32, sampler_index, 0);
        }
 
-       *res_ptr = load_sampler_desc(ctx, index, DESC_IMAGE);
+       if (target == TGSI_TEXTURE_BUFFER)
+               *res_ptr = load_sampler_desc(ctx, index, DESC_BUFFER);
+       else
+               *res_ptr = load_sampler_desc(ctx, index, DESC_IMAGE);
+
+       if (samp_ptr)
+               *samp_ptr = NULL;
+       if (fmask_ptr)
+               *fmask_ptr = NULL;
 
        if (target == TGSI_TEXTURE_2D_MSAA ||
            target == TGSI_TEXTURE_2D_ARRAY_MSAA) {
-               if (samp_ptr)
-                       *samp_ptr = NULL;
                if (fmask_ptr)
                        *fmask_ptr = load_sampler_desc(ctx, index, DESC_FMASK);
-       } else {
+       } else if (target != TGSI_TEXTURE_BUFFER) {
                if (samp_ptr) {
                        *samp_ptr = load_sampler_desc(ctx, index, DESC_SAMPLER);
                        *samp_ptr = sici_fix_sampler_aniso(ctx, *res_ptr, *samp_ptr);
                }
-               if (fmask_ptr)
-                       *fmask_ptr = NULL;
        }
 }
 
@@ -4393,8 +4400,6 @@ static void txq_fetch_args(
        struct lp_build_emit_data *emit_data)
 {
        struct si_shader_context *ctx = si_shader_context(bld_base);
-       struct gallivm_state *gallivm = bld_base->base.gallivm;
-       LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction *inst = emit_data->inst;
        unsigned target = inst->Texture.Texture;
        LLVMValueRef res_ptr;
@@ -4404,8 +4409,7 @@ static void txq_fetch_args(
 
        if (target == TGSI_TEXTURE_BUFFER) {
                /* Read the size from the buffer descriptor directly. */
-               LLVMValueRef res = LLVMBuildBitCast(builder, res_ptr, ctx->v8i32, "");
-               emit_data->args[0] = get_buffer_size(bld_base, res);
+               emit_data->args[0] = get_buffer_size(bld_base, res_ptr);
                return;
        }
 
@@ -4432,7 +4436,7 @@ static void txq_emit(const struct lp_build_tgsi_action *action,
        emit_data->output[emit_data->chan] = lp_build_intrinsic(
                base->gallivm->builder, "llvm.SI.getresinfo.i32",
                emit_data->dst_type, emit_data->args, emit_data->arg_count,
-               LLVMReadNoneAttribute);
+               LP_FUNC_ATTR_READNONE);
 
        /* Divide the number of layers by 6 to get the number of cubes. */
        if (target == TGSI_TEXTURE_CUBE_ARRAY ||
@@ -4473,16 +4477,9 @@ static void tex_fetch_args(
        tex_fetch_ptrs(bld_base, emit_data, &res_ptr, &samp_ptr, &fmask_ptr);
 
        if (target == TGSI_TEXTURE_BUFFER) {
-               LLVMTypeRef v2i128 = LLVMVectorType(ctx->i128, 2);
-
-               /* Bitcast and truncate v8i32 to v16i8. */
-               LLVMValueRef res = res_ptr;
-               res = LLVMBuildBitCast(gallivm->builder, res, v2i128, "");
-               res = LLVMBuildExtractElement(gallivm->builder, res, bld_base->uint_bld.one, "");
-               res = LLVMBuildBitCast(gallivm->builder, res, ctx->v16i8, "");
-
                emit_data->dst_type = ctx->v4f32;
-               emit_data->args[0] = res;
+               emit_data->args[0] = LLVMBuildBitCast(gallivm->builder, res_ptr,
+                                                     ctx->v16i8, "");
                emit_data->args[1] = bld_base->uint_bld.zero;
                emit_data->args[2] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_X);
                emit_data->arg_count = 3;
@@ -4537,12 +4534,26 @@ static void tex_fetch_args(
 
        /* Pack depth comparison value */
        if (tgsi_is_shadow_target(target) && opcode != TGSI_OPCODE_LODQ) {
+               LLVMValueRef z;
+
                if (target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) {
-                       address[count++] = lp_build_emit_fetch(bld_base, inst, 1, TGSI_CHAN_X);
+                       z = lp_build_emit_fetch(bld_base, inst, 1, TGSI_CHAN_X);
                } else {
                        assert(ref_pos >= 0);
-                       address[count++] = coords[ref_pos];
+                       z = coords[ref_pos];
                }
+
+               /* TC-compatible HTILE promotes Z16 and Z24 to Z32_FLOAT,
+                * so the depth comparison value isn't clamped for Z16 and
+                * Z24 anymore. Do it manually here.
+                *
+                * It's unnecessary if the original texture format was
+                * Z32_FLOAT, but we don't know that here.
+                */
+               if (ctx->screen->b.chip_class == VI)
+                       z = si_llvm_saturate(bld_base, z);
+
+               address[count++] = z;
        }
 
        /* Pack user derivatives */
@@ -4592,7 +4603,11 @@ static void tex_fetch_args(
            target == TGSI_TEXTURE_CUBE_ARRAY ||
            target == TGSI_TEXTURE_SHADOWCUBE ||
            target == TGSI_TEXTURE_SHADOWCUBE_ARRAY)
-               radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords, derivs);
+               ac_prepare_cube_coords(&ctx->ac,
+                                      opcode == TGSI_OPCODE_TXD,
+                                      target == TGSI_TEXTURE_CUBE_ARRAY ||
+                                      target == TGSI_TEXTURE_SHADOWCUBE_ARRAY,
+                                      coords, derivs);
 
        if (opcode == TGSI_OPCODE_TXD)
                for (int i = 0; i < num_deriv_channels * 2; i++)
@@ -4706,7 +4721,6 @@ static void tex_fetch_args(
                /* add tex offsets */
                if (inst->Texture.NumOffsets) {
                        struct lp_build_context *uint_bld = &bld_base->uint_bld;
-                       struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
                        const struct tgsi_texture_offset *off = inst->TexOffsets;
 
                        assert(inst->Texture.NumOffsets == 1);
@@ -4714,7 +4728,7 @@ static void tex_fetch_args(
                        switch (target) {
                        case TGSI_TEXTURE_3D:
                                address[2] = lp_build_add(uint_bld, address[2],
-                                               bld->immediates[off->Index][off->SwizzleZ]);
+                                               ctx->imms[off->Index * TGSI_NUM_CHANNELS + off->SwizzleZ]);
                                /* fall through */
                        case TGSI_TEXTURE_2D:
                        case TGSI_TEXTURE_SHADOW2D:
@@ -4724,7 +4738,7 @@ static void tex_fetch_args(
                        case TGSI_TEXTURE_SHADOW2D_ARRAY:
                                address[1] =
                                        lp_build_add(uint_bld, address[1],
-                                               bld->immediates[off->Index][off->SwizzleY]);
+                                               ctx->imms[off->Index * TGSI_NUM_CHANNELS + off->SwizzleY]);
                                /* fall through */
                        case TGSI_TEXTURE_1D:
                        case TGSI_TEXTURE_SHADOW1D:
@@ -4732,7 +4746,7 @@ static void tex_fetch_args(
                        case TGSI_TEXTURE_SHADOW1D_ARRAY:
                                address[0] =
                                        lp_build_add(uint_bld, address[0],
-                                               bld->immediates[off->Index][off->SwizzleX]);
+                                               ctx->imms[off->Index * TGSI_NUM_CHANNELS + off->SwizzleX]);
                                break;
                                /* texture offsets do not apply to other texture targets */
                        }
@@ -4752,13 +4766,12 @@ static void tex_fetch_args(
 
                /* Get the component index from src1.x for Gather4. */
                if (!tgsi_is_shadow_target(target)) {
-                       LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
                        LLVMValueRef comp_imm;
                        struct tgsi_src_register src1 = inst->Src[1].Register;
 
                        assert(src1.File == TGSI_FILE_IMMEDIATE);
 
-                       comp_imm = imms[src1.Index][src1.SwizzleX];
+                       comp_imm = ctx->imms[src1.Index * TGSI_NUM_CHANNELS + src1.SwizzleX];
                        gather_comp = LLVMConstIntGetZExtValue(comp_imm);
                        gather_comp = CLAMP(gather_comp, 0, 3);
                }
@@ -4784,7 +4797,7 @@ static void si_lower_gather4_integer(struct si_shader_context *ctx,
                                     const char *intr_name,
                                     unsigned coord_vgpr_index)
 {
-       LLVMBuilderRef builder = ctx->radeon_bld.gallivm.builder;
+       LLVMBuilderRef builder = ctx->gallivm.builder;
        LLVMValueRef coord = emit_data->args[0];
        LLVMValueRef half_texel[2];
        int c;
@@ -4803,9 +4816,9 @@ static void si_lower_gather4_integer(struct si_shader_context *ctx,
                set_tex_fetch_args(ctx, &txq_emit_data, TGSI_OPCODE_TXQ,
                                   txq_inst.Texture.Texture,
                                   emit_data->args[1], NULL,
-                                  &ctx->radeon_bld.soa.bld_base.uint_bld.zero,
+                                  &ctx->bld_base.uint_bld.zero,
                                   1, 0xf);
-               txq_emit(NULL, &ctx->radeon_bld.soa.bld_base, &txq_emit_data);
+               txq_emit(NULL, &ctx->bld_base, &txq_emit_data);
 
                /* Compute -0.5 / size. */
                for (c = 0; c < 2; c++) {
@@ -4814,7 +4827,7 @@ static void si_lower_gather4_integer(struct si_shader_context *ctx,
                                                        LLVMConstInt(ctx->i32, c, 0), "");
                        half_texel[c] = LLVMBuildUIToFP(builder, half_texel[c], ctx->f32, "");
                        half_texel[c] =
-                               lp_build_emit_llvm_unary(&ctx->radeon_bld.soa.bld_base,
+                               lp_build_emit_llvm_unary(&ctx->bld_base,
                                                         TGSI_OPCODE_RCP, half_texel[c]);
                        half_texel[c] = LLVMBuildFMul(builder, half_texel[c],
                                                      LLVMConstReal(ctx->f32, -0.5), "");
@@ -4836,7 +4849,7 @@ static void si_lower_gather4_integer(struct si_shader_context *ctx,
        emit_data->output[emit_data->chan] =
                lp_build_intrinsic(builder, intr_name, emit_data->dst_type,
                                   emit_data->args, emit_data->arg_count,
-                                  LLVMReadNoneAttribute);
+                                  LP_FUNC_ATTR_READNONE);
 }
 
 static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
@@ -4860,7 +4873,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
                        base->gallivm->builder,
                        "llvm.SI.vs.load.input", emit_data->dst_type,
                        emit_data->args, emit_data->arg_count,
-                       LLVMReadNoneAttribute);
+                       LP_FUNC_ATTR_READNONE);
                return;
        }
 
@@ -4906,7 +4919,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
        }
 
        /* Add the type and suffixes .c, .o if needed. */
-       build_int_type_name(LLVMTypeOf(emit_data->args[0]), type, sizeof(type));
+       build_type_name_for_intr(LLVMTypeOf(emit_data->args[0]), type, sizeof(type));
        sprintf(intr_name, "%s%s%s%s.%s",
                name, is_shadow ? ".c" : "", infix,
                has_offset ? ".o" : "", type);
@@ -4937,7 +4950,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action *action,
        emit_data->output[emit_data->chan] = lp_build_intrinsic(
                base->gallivm->builder, intr_name, emit_data->dst_type,
                emit_data->args, emit_data->arg_count,
-               LLVMReadNoneAttribute);
+               LP_FUNC_ATTR_READNONE);
 }
 
 static void si_llvm_emit_txqs(
@@ -5035,13 +5048,13 @@ static void si_llvm_emit_ddxy(
                args[1] = val;
                tl = lp_build_intrinsic(gallivm->builder,
                                        "llvm.amdgcn.ds.bpermute", ctx->i32,
-                                       args, 2, LLVMReadNoneAttribute);
+                                       args, 2, LP_FUNC_ATTR_READNONE);
 
                args[0] = LLVMBuildMul(gallivm->builder, trbl_tid,
                                       lp_build_const_int32(gallivm, 4), "");
                trbl = lp_build_intrinsic(gallivm->builder,
                                          "llvm.amdgcn.ds.bpermute", ctx->i32,
-                                         args, 2, LLVMReadNoneAttribute);
+                                         args, 2, LP_FUNC_ATTR_READNONE);
        } else {
                LLVMValueRef store_ptr, load_ptr0, load_ptr1;
 
@@ -5114,7 +5127,7 @@ static void interp_fetch_args(
                                                emit_data->inst, 1, TGSI_CHAN_X);
                sample_id = LLVMBuildBitCast(gallivm->builder, sample_id,
                                             ctx->i32, "");
-               sample_position = load_sample_position(&ctx->radeon_bld, sample_id);
+               sample_position = load_sample_position(ctx, sample_id);
 
                emit_data->args[0] = LLVMBuildExtractElement(gallivm->builder,
                                                             sample_position,
@@ -5136,14 +5149,14 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
        struct si_shader_context *ctx = si_shader_context(bld_base);
        struct si_shader *shader = ctx->shader;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
+       struct lp_build_context *uint = &bld_base->uint_bld;
        LLVMValueRef interp_param;
        const struct tgsi_full_instruction *inst = emit_data->inst;
-       const char *intr_name;
        int input_index = inst->Src[0].Register.Index;
        int chan;
        int i;
        LLVMValueRef attr_number;
-       LLVMValueRef params = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_PRIM_MASK);
+       LLVMValueRef params = LLVMGetParam(ctx->main_fn, SI_PARAM_PRIM_MASK);
        int interp_param_idx;
        unsigned interp = shader->selector->info.input_interpolate[input_index];
        unsigned location;
@@ -5160,7 +5173,7 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
        if (interp_param_idx == -1)
                return;
        else if (interp_param_idx)
-               interp_param = get_interp_param(ctx, interp_param_idx);
+               interp_param = LLVMGetParam(ctx->main_fn, interp_param_idx);
        else
                interp_param = NULL;
 
@@ -5199,45 +5212,48 @@ static void build_interp_intrinsic(const struct lp_build_tgsi_action *action,
 
                        temp2 = LLVMBuildFMul(gallivm->builder, ddy_el, emit_data->args[1], "");
 
-                       temp2 = LLVMBuildFAdd(gallivm->builder, temp2, temp1, "");
-
-                       ij_out[i] = LLVMBuildBitCast(gallivm->builder,
-                                                    temp2, ctx->i32, "");
+                       ij_out[i] = LLVMBuildFAdd(gallivm->builder, temp2, temp1, "");
                }
                interp_param = lp_build_gather_values(bld_base->base.gallivm, ij_out, 2);
        }
 
-       intr_name = interp_param ? "llvm.SI.fs.interp" : "llvm.SI.fs.constant";
        for (chan = 0; chan < 4; chan++) {
-               LLVMValueRef args[4];
                LLVMValueRef llvm_chan;
                unsigned schan;
 
                schan = tgsi_util_get_full_src_register_swizzle(&inst->Src[0], chan);
                llvm_chan = lp_build_const_int32(gallivm, schan);
 
-               args[0] = llvm_chan;
-               args[1] = attr_number;
-               args[2] = params;
-               args[3] = interp_param;
-
-               emit_data->output[chan] =
-                       lp_build_intrinsic(gallivm->builder, intr_name,
-                                          ctx->f32, args, args[3] ? 4 : 3,
-                                          LLVMReadNoneAttribute);
+               if (interp_param) {
+                       interp_param = LLVMBuildBitCast(gallivm->builder,
+                               interp_param, LLVMVectorType(ctx->f32, 2), "");
+                       LLVMValueRef i = LLVMBuildExtractElement(
+                               gallivm->builder, interp_param, uint->zero, "");
+                       LLVMValueRef j = LLVMBuildExtractElement(
+                               gallivm->builder, interp_param, uint->one, "");
+                       emit_data->output[chan] = build_fs_interp(bld_base,
+                               llvm_chan, attr_number, params,
+                               i, j);
+               } else {
+                       emit_data->output[chan] = build_fs_interp_mov(bld_base,
+                               lp_build_const_int32(gallivm, 2), /* P0 */
+                               llvm_chan, attr_number, params);
+               }
        }
 }
 
 static unsigned si_llvm_get_stream(struct lp_build_tgsi_context *bld_base,
                                       struct lp_build_emit_data *emit_data)
 {
-       LLVMValueRef (*imms)[4] = lp_soa_context(bld_base)->immediates;
+       struct si_shader_context *ctx = si_shader_context(bld_base);
        struct tgsi_src_register src0 = emit_data->inst->Src[0].Register;
+       LLVMValueRef imm;
        unsigned stream;
 
        assert(src0.File == TGSI_FILE_IMMEDIATE);
 
-       stream = LLVMConstIntGetZExtValue(imms[src0.Index][src0.SwizzleX]) & 0x3;
+       imm = ctx->imms[src0.Index * TGSI_NUM_CHANNELS + src0.SwizzleX];
+       stream = LLVMConstIntGetZExtValue(imm) & 0x3;
        return stream;
 }
 
@@ -5252,12 +5268,13 @@ static void si_llvm_emit_vertex(
        struct si_shader *shader = ctx->shader;
        struct tgsi_shader_info *info = &shader->selector->info;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
-       LLVMValueRef soffset = LLVMGetParam(ctx->radeon_bld.main_fn,
+       struct lp_build_if_state if_state;
+       LLVMValueRef soffset = LLVMGetParam(ctx->main_fn,
                                            SI_PARAM_GS2VS_OFFSET);
        LLVMValueRef gs_next_vertex;
        LLVMValueRef can_emit, kill;
        LLVMValueRef args[2];
-       unsigned chan;
+       unsigned chan, offset;
        int i;
        unsigned stream;
 
@@ -5269,29 +5286,43 @@ static void si_llvm_emit_vertex(
                                       "");
 
        /* If this thread has already emitted the declared maximum number of
-        * vertices, kill it: excessive vertex emissions are not supposed to
-        * have any effect, and GS threads have no externally observable
-        * effects other than emitting vertices.
+        * vertices, skip the write: excessive vertex emissions are not
+        * supposed to have any effect.
+        *
+        * If the shader has no writes to memory, kill it instead. This skips
+        * further memory loads and may allow LLVM to skip to the end
+        * altogether.
         */
-       can_emit = LLVMBuildICmp(gallivm->builder, LLVMIntULE, gs_next_vertex,
+       can_emit = LLVMBuildICmp(gallivm->builder, LLVMIntULT, gs_next_vertex,
                                 lp_build_const_int32(gallivm,
                                                      shader->selector->gs_max_out_vertices), "");
-       kill = lp_build_select(&bld_base->base, can_emit,
-                              lp_build_const_float(gallivm, 1.0f),
-                              lp_build_const_float(gallivm, -1.0f));
 
-       lp_build_intrinsic(gallivm->builder, "llvm.AMDGPU.kill",
-                          ctx->voidt, &kill, 1, 0);
+       bool use_kill = !info->writes_memory;
+       if (use_kill) {
+               kill = lp_build_select(&bld_base->base, can_emit,
+                                      lp_build_const_float(gallivm, 1.0f),
+                                      lp_build_const_float(gallivm, -1.0f));
+
+               lp_build_intrinsic(gallivm->builder, "llvm.AMDGPU.kill",
+                                  ctx->voidt, &kill, 1, 0);
+       } else {
+               lp_build_if(&if_state, gallivm, can_emit);
+       }
 
+       offset = 0;
        for (i = 0; i < info->num_outputs; i++) {
-               LLVMValueRef *out_ptr =
-                       ctx->radeon_bld.soa.outputs[i];
+               LLVMValueRef *out_ptr = ctx->outputs[i];
 
                for (chan = 0; chan < 4; chan++) {
+                       if (!(info->output_usagemask[i] & (1 << chan)) ||
+                           ((info->output_streams[i] >> (2 * chan)) & 3) != stream)
+                               continue;
+
                        LLVMValueRef out_val = LLVMBuildLoad(gallivm->builder, out_ptr[chan], "");
                        LLVMValueRef voffset =
-                               lp_build_const_int32(gallivm, (i * 4 + chan) *
+                               lp_build_const_int32(gallivm, offset *
                                                     shader->selector->gs_max_out_vertices);
+                       offset++;
 
                        voffset = lp_build_add(uint, voffset, gs_next_vertex);
                        voffset = lp_build_mul_imm(uint, voffset, 4);
@@ -5307,6 +5338,7 @@ static void si_llvm_emit_vertex(
                                            1, 0, 1, 1, 0);
                }
        }
+
        gs_next_vertex = lp_build_add(uint, gs_next_vertex,
                                      lp_build_const_int32(gallivm, 1));
 
@@ -5314,9 +5346,12 @@ static void si_llvm_emit_vertex(
 
        /* Signal vertex emission */
        args[0] = lp_build_const_int32(gallivm, SENDMSG_GS_OP_EMIT | SENDMSG_GS | (stream << 8));
-       args[1] = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_GS_WAVE_ID);
+       args[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_GS_WAVE_ID);
        lp_build_intrinsic(gallivm->builder, "llvm.SI.sendmsg",
                           ctx->voidt, args, 2, 0);
+
+       if (!use_kill)
+               lp_build_endif(&if_state);
 }
 
 /* Cut one primitive from the geometry shader */
@@ -5333,7 +5368,7 @@ static void si_llvm_emit_primitive(
        /* Signal primitive cut */
        stream = si_llvm_get_stream(bld_base, emit_data);
        args[0] = lp_build_const_int32(gallivm, SENDMSG_GS_OP_CUT | SENDMSG_GS | (stream << 8));
-       args[1] = LLVMGetParam(ctx->radeon_bld.main_fn, SI_PARAM_GS_WAVE_ID);
+       args[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_GS_WAVE_ID);
        lp_build_intrinsic(gallivm->builder, "llvm.SI.sendmsg",
                           ctx->voidt, args, 2, 0);
 }
@@ -5349,7 +5384,7 @@ static void si_llvm_emit_barrier(const struct lp_build_tgsi_action *action,
         * always fits into a single wave.
         */
        if (ctx->type == PIPE_SHADER_TESS_CTRL) {
-               emit_optimization_barrier(ctx);
+               emit_waitcnt(ctx, LGKM_CNT & VM_CNT);
                return;
        }
 
@@ -5370,19 +5405,20 @@ static const struct lp_build_tgsi_action interp_action = {
 };
 
 static void si_create_function(struct si_shader_context *ctx,
+                              const char *name,
                               LLVMTypeRef *returns, unsigned num_returns,
                               LLVMTypeRef *params, unsigned num_params,
                               int last_sgpr)
 {
        int i;
 
-       radeon_llvm_create_func(&ctx->radeon_bld, returns, num_returns,
-                               params, num_params);
-       radeon_llvm_shader_type(ctx->radeon_bld.main_fn, ctx->type);
-       ctx->return_value = LLVMGetUndef(ctx->radeon_bld.return_type);
+       si_llvm_create_func(ctx, name, returns, num_returns,
+                           params, num_params);
+       si_llvm_shader_type(ctx->main_fn, ctx->type);
+       ctx->return_value = LLVMGetUndef(ctx->return_type);
 
        for (i = 0; i <= last_sgpr; ++i) {
-               LLVMValueRef P = LLVMGetParam(ctx->radeon_bld.main_fn, i);
+               LLVMValueRef P = LLVMGetParam(ctx->main_fn, i);
 
                /* The combination of:
                 * - ByVal
@@ -5392,24 +5428,24 @@ static void si_create_function(struct si_shader_context *ctx,
                 * SGPR spilling significantly.
                 */
                if (LLVMGetTypeKind(LLVMTypeOf(P)) == LLVMPointerTypeKind) {
-                       LLVMAddAttribute(P, LLVMByValAttribute);
+                       lp_add_function_attr(ctx->main_fn, i + 1, LP_FUNC_ATTR_BYVAL);
                        lp_add_attr_dereferenceable(P, UINT64_MAX);
                } else
-                       LLVMAddAttribute(P, LLVMInRegAttribute);
+                       lp_add_function_attr(ctx->main_fn, i + 1, LP_FUNC_ATTR_INREG);
        }
 
        if (ctx->screen->b.debug_flags & DBG_UNSAFE_MATH) {
                /* These were copied from some LLVM test. */
-               LLVMAddTargetDependentFunctionAttr(ctx->radeon_bld.main_fn,
+               LLVMAddTargetDependentFunctionAttr(ctx->main_fn,
                                                   "less-precise-fpmad",
                                                   "true");
-               LLVMAddTargetDependentFunctionAttr(ctx->radeon_bld.main_fn,
+               LLVMAddTargetDependentFunctionAttr(ctx->main_fn,
                                                   "no-infs-fp-math",
                                                   "true");
-               LLVMAddTargetDependentFunctionAttr(ctx->radeon_bld.main_fn,
+               LLVMAddTargetDependentFunctionAttr(ctx->main_fn,
                                                   "no-nans-fp-math",
                                                   "true");
-               LLVMAddTargetDependentFunctionAttr(ctx->radeon_bld.main_fn,
+               LLVMAddTargetDependentFunctionAttr(ctx->main_fn,
                                                   "unsafe-fp-math",
                                                   "true");
        }
@@ -5417,7 +5453,7 @@ static void si_create_function(struct si_shader_context *ctx,
 
 static void create_meta_data(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
 
        ctx->invariant_load_md_kind = LLVMGetMDKindIDInContext(gallivm->context,
                                                               "invariant.load", 14);
@@ -5468,6 +5504,9 @@ static unsigned llvm_get_type_size(LLVMTypeRef type)
        case LLVMVectorTypeKind:
                return LLVMGetVectorSize(type) *
                       llvm_get_type_size(LLVMGetElementType(type));
+       case LLVMArrayTypeKind:
+               return LLVMGetArrayLength(type) *
+                      llvm_get_type_size(LLVMGetElementType(type));
        default:
                assert(0);
                return 0;
@@ -5476,8 +5515,8 @@ static unsigned llvm_get_type_size(LLVMTypeRef type)
 
 static void declare_tess_lds(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        struct lp_build_context *uint = &bld_base->uint_bld;
 
        unsigned lds_size = ctx->screen->b.chip_class >= CIK ? 65536 : 32768;
@@ -5486,15 +5525,33 @@ static void declare_tess_lds(struct si_shader_context *ctx)
                "tess_lds");
 }
 
+static unsigned si_get_max_workgroup_size(struct si_shader *shader)
+{
+       const unsigned *properties = shader->selector->info.properties;
+       unsigned max_work_group_size =
+                      properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] *
+                      properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT] *
+                      properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH];
+
+       if (!max_work_group_size) {
+               /* This is a variable group size compute shader,
+                * compile it for the maximum possible group size.
+                */
+               max_work_group_size = SI_MAX_VARIABLE_THREADS_PER_BLOCK;
+       }
+       return max_work_group_size;
+}
+
 static void create_function(struct si_shader_context *ctx)
 {
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        struct si_shader *shader = ctx->shader;
        LLVMTypeRef params[SI_NUM_PARAMS + SI_NUM_VERTEX_BUFFERS], v3i32;
        LLVMTypeRef returns[16+32*4];
        unsigned i, last_sgpr, num_params, num_return_sgprs;
        unsigned num_returns = 0;
+       unsigned num_prolog_vgprs = 0;
 
        v3i32 = LLVMVectorType(ctx->i32, 3);
 
@@ -5512,13 +5569,13 @@ static void create_function(struct si_shader_context *ctx)
                params[SI_PARAM_DRAWID] = ctx->i32;
                num_params = SI_PARAM_DRAWID+1;
 
-               if (shader->key.vs.as_es) {
+               if (shader->key.as_es) {
                        params[ctx->param_es2gs_offset = num_params++] = ctx->i32;
-               } else if (shader->key.vs.as_ls) {
+               } else if (shader->key.as_ls) {
                        params[SI_PARAM_LS_OUT_LAYOUT] = ctx->i32;
                        num_params = SI_PARAM_LS_OUT_LAYOUT+1;
                } else {
-                       if (ctx->is_gs_copy_shader) {
+                       if (shader->is_gs_copy_shader) {
                                num_params = SI_PARAM_RW_BUFFERS+1;
                        } else {
                                params[SI_PARAM_VS_STATE_BITS] = ctx->i32;
@@ -5538,16 +5595,17 @@ static void create_function(struct si_shader_context *ctx)
                params[ctx->param_vs_prim_id = num_params++] = ctx->i32;
                params[ctx->param_instance_id = num_params++] = ctx->i32;
 
-               if (!ctx->is_monolithic &&
-                   !ctx->is_gs_copy_shader) {
+               if (!shader->is_gs_copy_shader) {
                        /* Vertex load indices. */
                        ctx->param_vertex_index0 = num_params;
 
                        for (i = 0; i < shader->selector->info.num_inputs; i++)
                                params[num_params++] = ctx->i32;
 
+                       num_prolog_vgprs += shader->selector->info.num_inputs;
+
                        /* PrimitiveID output. */
-                       if (!shader->key.vs.as_es && !shader->key.vs.as_ls)
+                       if (!shader->key.as_es && !shader->key.as_ls)
                                for (i = 0; i <= VS_EPILOG_PRIMID_LOC; i++)
                                        returns[num_returns++] = ctx->f32;
                }
@@ -5567,23 +5625,21 @@ static void create_function(struct si_shader_context *ctx)
                params[SI_PARAM_REL_IDS] = ctx->i32;
                num_params = SI_PARAM_REL_IDS+1;
 
-               if (!ctx->is_monolithic) {
-                       /* SI_PARAM_TCS_OC_LDS and PARAM_TESS_FACTOR_OFFSET are
-                        * placed after the user SGPRs.
-                        */
-                       for (i = 0; i < SI_TCS_NUM_USER_SGPR + 2; i++)
-                               returns[num_returns++] = ctx->i32; /* SGPRs */
+               /* SI_PARAM_TCS_OC_LDS and PARAM_TESS_FACTOR_OFFSET are
+                * placed after the user SGPRs.
+                */
+               for (i = 0; i < SI_TCS_NUM_USER_SGPR + 2; i++)
+                       returns[num_returns++] = ctx->i32; /* SGPRs */
 
-                       for (i = 0; i < 3; i++)
-                               returns[num_returns++] = ctx->f32; /* VGPRs */
-               }
+               for (i = 0; i < 3; i++)
+                       returns[num_returns++] = ctx->f32; /* VGPRs */
                break;
 
        case PIPE_SHADER_TESS_EVAL:
                params[SI_PARAM_TCS_OFFCHIP_LAYOUT] = ctx->i32;
                num_params = SI_PARAM_TCS_OFFCHIP_LAYOUT+1;
 
-               if (shader->key.tes.as_es) {
+               if (shader->key.as_es) {
                        params[ctx->param_oc_lds = num_params++] = ctx->i32;
                        params[ctx->param_tess_offchip = num_params++] = ctx->i32;
                        params[ctx->param_es2gs_offset = num_params++] = ctx->i32;
@@ -5602,7 +5658,7 @@ static void create_function(struct si_shader_context *ctx)
                params[ctx->param_tes_patch_id = num_params++] = ctx->i32;
 
                /* PrimitiveID output. */
-               if (!ctx->is_monolithic && !shader->key.tes.as_es)
+               if (!shader->key.as_es)
                        for (i = 0; i <= VS_EPILOG_PRIMID_LOC; i++)
                                returns[num_returns++] = ctx->f32;
                break;
@@ -5641,45 +5697,47 @@ static void create_function(struct si_shader_context *ctx)
                params[SI_PARAM_POS_Z_FLOAT] = ctx->f32;
                params[SI_PARAM_POS_W_FLOAT] = ctx->f32;
                params[SI_PARAM_FRONT_FACE] = ctx->i32;
+               shader->info.face_vgpr_index = 20;
                params[SI_PARAM_ANCILLARY] = ctx->i32;
                params[SI_PARAM_SAMPLE_COVERAGE] = ctx->f32;
                params[SI_PARAM_POS_FIXED_PT] = ctx->i32;
                num_params = SI_PARAM_POS_FIXED_PT+1;
 
-               if (!ctx->is_monolithic) {
-                       /* Color inputs from the prolog. */
-                       if (shader->selector->info.colors_read) {
-                               unsigned num_color_elements =
-                                       util_bitcount(shader->selector->info.colors_read);
+               /* Color inputs from the prolog. */
+               if (shader->selector->info.colors_read) {
+                       unsigned num_color_elements =
+                               util_bitcount(shader->selector->info.colors_read);
 
-                               assert(num_params + num_color_elements <= ARRAY_SIZE(params));
-                               for (i = 0; i < num_color_elements; i++)
-                                       params[num_params++] = ctx->f32;
-                       }
+                       assert(num_params + num_color_elements <= ARRAY_SIZE(params));
+                       for (i = 0; i < num_color_elements; i++)
+                               params[num_params++] = ctx->f32;
 
-                       /* Outputs for the epilog. */
-                       num_return_sgprs = SI_SGPR_ALPHA_REF + 1;
-                       num_returns =
-                               num_return_sgprs +
-                               util_bitcount(shader->selector->info.colors_written) * 4 +
-                               shader->selector->info.writes_z +
-                               shader->selector->info.writes_stencil +
-                               shader->selector->info.writes_samplemask +
-                               1 /* SampleMaskIn */;
-
-                       num_returns = MAX2(num_returns,
-                                          num_return_sgprs +
-                                          PS_EPILOG_SAMPLEMASK_MIN_LOC + 1);
-
-                       for (i = 0; i < num_return_sgprs; i++)
-                               returns[i] = ctx->i32;
-                       for (; i < num_returns; i++)
-                               returns[i] = ctx->f32;
+                       num_prolog_vgprs += num_color_elements;
                }
+
+               /* Outputs for the epilog. */
+               num_return_sgprs = SI_SGPR_ALPHA_REF + 1;
+               num_returns =
+                       num_return_sgprs +
+                       util_bitcount(shader->selector->info.colors_written) * 4 +
+                       shader->selector->info.writes_z +
+                       shader->selector->info.writes_stencil +
+                       shader->selector->info.writes_samplemask +
+                       1 /* SampleMaskIn */;
+
+               num_returns = MAX2(num_returns,
+                                  num_return_sgprs +
+                                  PS_EPILOG_SAMPLEMASK_MIN_LOC + 1);
+
+               for (i = 0; i < num_return_sgprs; i++)
+                       returns[i] = ctx->i32;
+               for (; i < num_returns; i++)
+                       returns[i] = ctx->f32;
                break;
 
        case PIPE_SHADER_COMPUTE:
                params[SI_PARAM_GRID_SIZE] = v3i32;
+               params[SI_PARAM_BLOCK_SIZE] = v3i32;
                params[SI_PARAM_BLOCK_ID] = v3i32;
                last_sgpr = SI_PARAM_BLOCK_ID;
 
@@ -5693,34 +5751,26 @@ static void create_function(struct si_shader_context *ctx)
 
        assert(num_params <= ARRAY_SIZE(params));
 
-       si_create_function(ctx, returns, num_returns, params,
+       si_create_function(ctx, "main", returns, num_returns, params,
                           num_params, last_sgpr);
 
        /* Reserve register locations for VGPR inputs the PS prolog may need. */
        if (ctx->type == PIPE_SHADER_FRAGMENT &&
-           !ctx->is_monolithic) {
-               radeon_llvm_add_attribute(ctx->radeon_bld.main_fn,
-                                         "InitialPSInputAddr",
-                                         S_0286D0_PERSP_SAMPLE_ENA(1) |
-                                         S_0286D0_PERSP_CENTER_ENA(1) |
-                                         S_0286D0_PERSP_CENTROID_ENA(1) |
-                                         S_0286D0_LINEAR_SAMPLE_ENA(1) |
-                                         S_0286D0_LINEAR_CENTER_ENA(1) |
-                                         S_0286D0_LINEAR_CENTROID_ENA(1) |
-                                         S_0286D0_FRONT_FACE_ENA(1) |
-                                         S_0286D0_POS_FIXED_PT_ENA(1));
+           ctx->separate_prolog) {
+               si_llvm_add_attribute(ctx->main_fn,
+                                     "InitialPSInputAddr",
+                                     S_0286D0_PERSP_SAMPLE_ENA(1) |
+                                     S_0286D0_PERSP_CENTER_ENA(1) |
+                                     S_0286D0_PERSP_CENTROID_ENA(1) |
+                                     S_0286D0_LINEAR_SAMPLE_ENA(1) |
+                                     S_0286D0_LINEAR_CENTER_ENA(1) |
+                                     S_0286D0_LINEAR_CENTROID_ENA(1) |
+                                     S_0286D0_FRONT_FACE_ENA(1) |
+                                     S_0286D0_POS_FIXED_PT_ENA(1));
        } else if (ctx->type == PIPE_SHADER_COMPUTE) {
-               const unsigned *properties = shader->selector->info.properties;
-               unsigned max_work_group_size =
-                              properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] *
-                              properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT] *
-                              properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH];
-
-               assert(max_work_group_size);
-
-               radeon_llvm_add_attribute(ctx->radeon_bld.main_fn,
-                                         "amdgpu-max-work-group-size",
-                                         max_work_group_size);
+               si_llvm_add_attribute(ctx->main_fn,
+                                     "amdgpu-max-work-group-size",
+                                     si_get_max_workgroup_size(shader));
        }
 
        shader->info.num_input_sgprs = 0;
@@ -5729,12 +5779,11 @@ static void create_function(struct si_shader_context *ctx)
        for (i = 0; i <= last_sgpr; ++i)
                shader->info.num_input_sgprs += llvm_get_type_size(params[i]) / 4;
 
-       /* Unused fragment shader inputs are eliminated by the compiler,
-        * so we don't know yet how many there will be.
-        */
-       if (ctx->type != PIPE_SHADER_FRAGMENT)
-               for (; i < num_params; ++i)
-                       shader->info.num_input_vgprs += llvm_get_type_size(params[i]) / 4;
+       for (; i < num_params; ++i)
+               shader->info.num_input_vgprs += llvm_get_type_size(params[i]) / 4;
+
+       assert(shader->info.num_input_vgprs >= num_prolog_vgprs);
+       shader->info.num_input_vgprs -= num_prolog_vgprs;
 
        if (!ctx->screen->has_ds_bpermute &&
            bld_base->info &&
@@ -5750,7 +5799,7 @@ static void create_function(struct si_shader_context *ctx)
                                                    "ddxy_lds",
                                                    LOCAL_ADDR_SPACE);
 
-       if ((ctx->type == PIPE_SHADER_VERTEX && shader->key.vs.as_ls) ||
+       if ((ctx->type == PIPE_SHADER_VERTEX && shader->key.as_ls) ||
            ctx->type == PIPE_SHADER_TESS_CTRL ||
            ctx->type == PIPE_SHADER_TESS_EVAL)
                declare_tess_lds(ctx);
@@ -5762,16 +5811,16 @@ static void create_function(struct si_shader_context *ctx)
  */
 static void preload_ring_buffers(struct si_shader_context *ctx)
 {
-       struct gallivm_state *gallivm =
-               ctx->radeon_bld.soa.bld_base.base.gallivm;
+       struct gallivm_state *gallivm = ctx->bld_base.base.gallivm;
+       LLVMBuilderRef builder = gallivm->builder;
 
-       LLVMValueRef buf_ptr = LLVMGetParam(ctx->radeon_bld.main_fn,
+       LLVMValueRef buf_ptr = LLVMGetParam(ctx->main_fn,
                                            SI_PARAM_RW_BUFFERS);
 
        if ((ctx->type == PIPE_SHADER_VERTEX &&
-            ctx->shader->key.vs.as_es) ||
+            ctx->shader->key.as_es) ||
            (ctx->type == PIPE_SHADER_TESS_EVAL &&
-            ctx->shader->key.tes.as_es) ||
+            ctx->shader->key.as_es) ||
            ctx->type == PIPE_SHADER_GEOMETRY) {
                unsigned ring =
                        ctx->type == PIPE_SHADER_GEOMETRY ? SI_GS_RING_ESGS
@@ -5782,19 +5831,81 @@ static void preload_ring_buffers(struct si_shader_context *ctx)
                        build_indexed_load_const(ctx, buf_ptr, offset);
        }
 
-       if (ctx->is_gs_copy_shader) {
-               LLVMValueRef offset = lp_build_const_int32(gallivm, SI_VS_RING_GSVS);
+       if (ctx->shader->is_gs_copy_shader) {
+               LLVMValueRef offset = lp_build_const_int32(gallivm, SI_RING_GSVS);
 
                ctx->gsvs_ring[0] =
                        build_indexed_load_const(ctx, buf_ptr, offset);
-       }
-       if (ctx->type == PIPE_SHADER_GEOMETRY) {
-               int i;
-               for (i = 0; i < 4; i++) {
-                       LLVMValueRef offset = lp_build_const_int32(gallivm, SI_GS_RING_GSVS0 + i);
+       } else if (ctx->type == PIPE_SHADER_GEOMETRY) {
+               const struct si_shader_selector *sel = ctx->shader->selector;
+               struct lp_build_context *uint = &ctx->bld_base.uint_bld;
+               LLVMValueRef offset = lp_build_const_int32(gallivm, SI_RING_GSVS);
+               LLVMValueRef base_ring;
+
+               base_ring = build_indexed_load_const(ctx, buf_ptr, offset);
+
+               /* The conceptual layout of the GSVS ring is
+                *   v0c0 .. vLv0 v0c1 .. vLc1 ..
+                * but the real memory layout is swizzled across
+                * threads:
+                *   t0v0c0 .. t15v0c0 t0v1c0 .. t15v1c0 ... t15vLcL
+                *   t16v0c0 ..
+                * Override the buffer descriptor accordingly.
+                */
+               LLVMTypeRef v2i64 = LLVMVectorType(ctx->i64, 2);
+               uint64_t stream_offset = 0;
+
+               for (unsigned stream = 0; stream < 4; ++stream) {
+                       unsigned num_components;
+                       unsigned stride;
+                       unsigned num_records;
+                       LLVMValueRef ring, tmp;
+
+                       num_components = sel->info.num_stream_output_components[stream];
+                       if (!num_components)
+                               continue;
 
-                       ctx->gsvs_ring[i] =
-                               build_indexed_load_const(ctx, buf_ptr, offset);
+                       stride = 4 * num_components * sel->gs_max_out_vertices;
+
+                       /* Limit on the stride field for <= CIK. */
+                       assert(stride < (1 << 14));
+
+                       num_records = 64;
+
+                       ring = LLVMBuildBitCast(builder, base_ring, v2i64, "");
+                       tmp = LLVMBuildExtractElement(builder, ring, uint->zero, "");
+                       tmp = LLVMBuildAdd(builder, tmp,
+                                          LLVMConstInt(ctx->i64,
+                                                       stream_offset, 0), "");
+                       stream_offset += stride * 64;
+
+                       ring = LLVMBuildInsertElement(builder, ring, tmp, uint->zero, "");
+                       ring = LLVMBuildBitCast(builder, ring, ctx->v4i32, "");
+                       tmp = LLVMBuildExtractElement(builder, ring, uint->one, "");
+                       tmp = LLVMBuildOr(builder, tmp,
+                               LLVMConstInt(ctx->i32,
+                                            S_008F04_STRIDE(stride) |
+                                            S_008F04_SWIZZLE_ENABLE(1), 0), "");
+                       ring = LLVMBuildInsertElement(builder, ring, tmp, uint->one, "");
+                       ring = LLVMBuildInsertElement(builder, ring,
+                                       LLVMConstInt(ctx->i32, num_records, 0),
+                                       LLVMConstInt(ctx->i32, 2, 0), "");
+                       ring = LLVMBuildInsertElement(builder, ring,
+                               LLVMConstInt(ctx->i32,
+                                            S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
+                                            S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
+                                            S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
+                                            S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
+                                            S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+                                            S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
+                                            S_008F0C_ELEMENT_SIZE(1) | /* element_size = 4 (bytes) */
+                                            S_008F0C_INDEX_STRIDE(1) | /* index_stride = 16 (elements) */
+                                            S_008F0C_ADD_TID_ENABLE(1),
+                                            0),
+                               LLVMConstInt(ctx->i32, 3, 0), "");
+                       ring = LLVMBuildBitCast(builder, ring, ctx->v16i8, "");
+
+                       ctx->gsvs_ring[stream] = ring;
                }
        }
 }
@@ -5803,8 +5914,7 @@ static void si_llvm_emit_polygon_stipple(struct si_shader_context *ctx,
                                         LLVMValueRef param_rw_buffers,
                                         unsigned param_pos_fixed_pt)
 {
-       struct lp_build_tgsi_context *bld_base =
-               &ctx->radeon_bld.soa.bld_base;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        LLVMValueRef slot, desc, offset, row, bit, address[2];
@@ -5976,9 +6086,9 @@ int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader)
        assert(!epilog || !epilog->rodata_size);
 
        r600_resource_reference(&shader->bo, NULL);
-       shader->bo = si_resource_create_custom(&sscreen->b.b,
-                                              PIPE_USAGE_IMMUTABLE,
-                                              bo_size);
+       shader->bo = (struct r600_resource*)
+                    pipe_buffer_create(&sscreen->b.b, 0,
+                                       PIPE_USAGE_IMMUTABLE, bo_size);
        if (!shader->bo)
                return -ENOMEM;
 
@@ -6052,19 +6162,22 @@ static void si_shader_dump_disassembly(const struct radeon_shader_binary *binary
 }
 
 static void si_shader_dump_stats(struct si_screen *sscreen,
-                                struct si_shader_config *conf,
-                                unsigned num_inputs,
-                                unsigned code_size,
+                                struct si_shader *shader,
                                 struct pipe_debug_callback *debug,
                                 unsigned processor,
-                                FILE *file)
+                                FILE *file,
+                                bool check_debug_option)
 {
+       struct si_shader_config *conf = &shader->config;
+       unsigned num_inputs = shader->selector ? shader->selector->info.num_inputs : 0;
+       unsigned code_size = si_get_shader_binary_size(shader);
        unsigned lds_increment = sscreen->b.chip_class >= CIK ? 512 : 256;
        unsigned lds_per_wave = 0;
        unsigned max_simd_waves = 10;
 
        /* Compute LDS usage for PS. */
-       if (processor == PIPE_SHADER_FRAGMENT) {
+       switch (processor) {
+       case PIPE_SHADER_FRAGMENT:
                /* The minimum usage per wave is (num_inputs * 48). The maximum
                 * usage is (num_inputs * 48 * 16).
                 * We can get anything in between and it varies between waves.
@@ -6077,6 +6190,15 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
                 */
                lds_per_wave = conf->lds_size * lds_increment +
                               align(num_inputs * 48, lds_increment);
+               break;
+       case PIPE_SHADER_COMPUTE:
+               if (shader->selector) {
+                       unsigned max_workgroup_size =
+                               si_get_max_workgroup_size(shader);
+                       lds_per_wave = (conf->lds_size * lds_increment) /
+                                      DIV_ROUND_UP(max_workgroup_size, 64);
+               }
+               break;
        }
 
        /* Compute the per-SIMD wave counts. */
@@ -6090,13 +6212,12 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
        if (conf->num_vgprs)
                max_simd_waves = MIN2(max_simd_waves, 256 / conf->num_vgprs);
 
-       /* LDS is 64KB per CU (4 SIMDs), divided into 16KB blocks per SIMD
-        * that PS can use.
-        */
+       /* LDS is 64KB per CU (4 SIMDs), which is 16KB per SIMD (usage above
+        * 16KB makes some SIMDs unoccupied). */
        if (lds_per_wave)
                max_simd_waves = MIN2(max_simd_waves, 16384 / lds_per_wave);
 
-       if (file != stderr ||
+       if (!check_debug_option ||
            r600_can_dump_shader(&sscreen->b, processor)) {
                if (processor == PIPE_SHADER_FRAGMENT) {
                        fprintf(file, "*** SHADER CONFIG ***\n"
@@ -6110,13 +6231,15 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
                        "VGPRS: %d\n"
                        "Spilled SGPRs: %d\n"
                        "Spilled VGPRs: %d\n"
+                       "Private memory VGPRs: %d\n"
                        "Code Size: %d bytes\n"
                        "LDS: %d blocks\n"
                        "Scratch: %d bytes per wave\n"
                        "Max Waves: %d\n"
                        "********************\n\n\n",
                        conf->num_sgprs, conf->num_vgprs,
-                       conf->spilled_sgprs, conf->spilled_vgprs, code_size,
+                       conf->spilled_sgprs, conf->spilled_vgprs,
+                       conf->private_mem_vgprs, code_size,
                        conf->lds_size, conf->scratch_bytes_per_wave,
                        max_simd_waves);
        }
@@ -6124,11 +6247,11 @@ static void si_shader_dump_stats(struct si_screen *sscreen,
        pipe_debug_message(debug, SHADER_INFO,
                           "Shader Stats: SGPRS: %d VGPRS: %d Code Size: %d "
                           "LDS: %d Scratch: %d Max Waves: %d Spilled SGPRs: %d "
-                          "Spilled VGPRs: %d",
+                          "Spilled VGPRs: %d PrivMem VGPRs: %d",
                           conf->num_sgprs, conf->num_vgprs, code_size,
                           conf->lds_size, conf->scratch_bytes_per_wave,
                           max_simd_waves, conf->spilled_sgprs,
-                          conf->spilled_vgprs);
+                          conf->spilled_vgprs, conf->private_mem_vgprs);
 }
 
 static const char *si_get_shader_name(struct si_shader *shader,
@@ -6136,21 +6259,21 @@ static const char *si_get_shader_name(struct si_shader *shader,
 {
        switch (processor) {
        case PIPE_SHADER_VERTEX:
-               if (shader->key.vs.as_es)
+               if (shader->key.as_es)
                        return "Vertex Shader as ES";
-               else if (shader->key.vs.as_ls)
+               else if (shader->key.as_ls)
                        return "Vertex Shader as LS";
                else
                        return "Vertex Shader as VS";
        case PIPE_SHADER_TESS_CTRL:
                return "Tessellation Control Shader";
        case PIPE_SHADER_TESS_EVAL:
-               if (shader->key.tes.as_es)
+               if (shader->key.as_es)
                        return "Tessellation Evaluation Shader as ES";
                else
                        return "Tessellation Evaluation Shader as VS";
        case PIPE_SHADER_GEOMETRY:
-               if (shader->gs_copy_shader == NULL)
+               if (shader->is_gs_copy_shader)
                        return "GS Copy Shader as VS";
                else
                        return "Geometry Shader";
@@ -6165,19 +6288,19 @@ static const char *si_get_shader_name(struct si_shader *shader,
 
 void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
                    struct pipe_debug_callback *debug, unsigned processor,
-                   FILE *file)
+                   FILE *file, bool check_debug_option)
 {
-       if (file != stderr ||
+       if (!check_debug_option ||
            r600_can_dump_shader(&sscreen->b, processor))
                si_dump_shader_key(processor, &shader->key, file);
 
-       if (file != stderr && shader->binary.llvm_ir_string) {
+       if (!check_debug_option && shader->binary.llvm_ir_string) {
                fprintf(file, "\n%s - main shader part - LLVM IR:\n\n",
                        si_get_shader_name(shader, processor));
                fprintf(file, "%s\n", shader->binary.llvm_ir_string);
        }
 
-       if (file != stderr ||
+       if (!check_debug_option ||
            (r600_can_dump_shader(&sscreen->b, processor) &&
             !(sscreen->b.debug_flags & DBG_NO_ASM))) {
                fprintf(file, "\n%s:\n", si_get_shader_name(shader, processor));
@@ -6194,10 +6317,8 @@ void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
                fprintf(file, "\n");
        }
 
-       si_shader_dump_stats(sscreen, &shader->config,
-                            shader->selector ? shader->selector->info.num_inputs : 0,
-                            si_get_shader_binary_size(shader), debug, processor,
-                            file);
+       si_shader_dump_stats(sscreen, shader, debug, processor, file,
+                            check_debug_option);
 }
 
 int si_compile_llvm(struct si_screen *sscreen,
@@ -6229,7 +6350,7 @@ int si_compile_llvm(struct si_screen *sscreen,
        }
 
        if (!si_replace_shader(count, binary)) {
-               r = radeon_llvm_compile(mod, binary, tm, debug);
+               r = si_llvm_compile(mod, binary, tm, debug);
                if (r)
                        return r;
        }
@@ -6273,39 +6394,57 @@ int si_compile_llvm(struct si_screen *sscreen,
 static void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
 {
        if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind)
-               LLVMBuildRetVoid(ctx->radeon_bld.gallivm.builder);
+               LLVMBuildRetVoid(ctx->gallivm.builder);
        else
-               LLVMBuildRet(ctx->radeon_bld.gallivm.builder, ret);
+               LLVMBuildRet(ctx->gallivm.builder, ret);
 }
 
 /* Generate code for the hardware VS shader stage to go with a geometry shader */
-static int si_generate_gs_copy_shader(struct si_screen *sscreen,
-                                     struct si_shader_context *ctx,
-                                     struct si_shader *gs,
-                                     struct pipe_debug_callback *debug)
+struct si_shader *
+si_generate_gs_copy_shader(struct si_screen *sscreen,
+                          LLVMTargetMachineRef tm,
+                          struct si_shader_selector *gs_selector,
+                          struct pipe_debug_callback *debug)
 {
-       struct gallivm_state *gallivm = &ctx->radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx->radeon_bld.soa.bld_base;
+       struct si_shader_context ctx;
+       struct si_shader *shader;
+       struct gallivm_state *gallivm = &ctx.gallivm;
+       LLVMBuilderRef builder;
+       struct lp_build_tgsi_context *bld_base = &ctx.bld_base;
        struct lp_build_context *uint = &bld_base->uint_bld;
        struct si_shader_output_values *outputs;
-       struct tgsi_shader_info *gsinfo = &gs->selector->info;
+       struct tgsi_shader_info *gsinfo = &gs_selector->info;
        LLVMValueRef args[9];
        int i, r;
 
        outputs = MALLOC(gsinfo->num_outputs * sizeof(outputs[0]));
 
-       si_init_shader_ctx(ctx, sscreen, ctx->shader, ctx->tm);
-       ctx->type = PIPE_SHADER_VERTEX;
-       ctx->is_gs_copy_shader = true;
+       if (!outputs)
+               return NULL;
 
-       create_meta_data(ctx);
-       create_function(ctx);
-       preload_ring_buffers(ctx);
+       shader = CALLOC_STRUCT(si_shader);
+       if (!shader) {
+               FREE(outputs);
+               return NULL;
+       }
+
+
+       shader->selector = gs_selector;
+       shader->is_gs_copy_shader = true;
+
+       si_init_shader_ctx(&ctx, sscreen, shader, tm);
+       ctx.type = PIPE_SHADER_VERTEX;
+
+       builder = gallivm->builder;
+
+       create_meta_data(&ctx);
+       create_function(&ctx);
+       preload_ring_buffers(&ctx);
 
-       args[0] = ctx->gsvs_ring[0];
+       args[0] = ctx.gsvs_ring[0];
        args[1] = lp_build_mul_imm(uint,
-                                  LLVMGetParam(ctx->radeon_bld.main_fn,
-                                               ctx->param_vertex_id),
+                                  LLVMGetParam(ctx.main_fn,
+                                               ctx.param_vertex_id),
                                   4);
        args[3] = uint->zero;
        args[4] = uint->one;  /* OFFEN */
@@ -6314,29 +6453,84 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen,
        args[7] = uint->one;  /* SLC */
        args[8] = uint->zero; /* TFE */
 
-       /* Fetch vertex data from GSVS ring */
+       /* Fetch the vertex stream ID.*/
+       LLVMValueRef stream_id;
+
+       if (gs_selector->so.num_outputs)
+               stream_id = unpack_param(&ctx, ctx.param_streamout_config, 24, 2);
+       else
+               stream_id = uint->zero;
+
+       /* Fill in output information. */
        for (i = 0; i < gsinfo->num_outputs; ++i) {
-               unsigned chan;
+               outputs[i].semantic_name = gsinfo->output_semantic_name[i];
+               outputs[i].semantic_index = gsinfo->output_semantic_index[i];
 
-               outputs[i].name = gsinfo->output_semantic_name[i];
-               outputs[i].sid = gsinfo->output_semantic_index[i];
+               for (int chan = 0; chan < 4; chan++) {
+                       outputs[i].vertex_stream[chan] =
+                               (gsinfo->output_streams[i] >> (2 * chan)) & 3;
+               }
+       }
 
-               for (chan = 0; chan < 4; chan++) {
-                       args[2] = lp_build_const_int32(gallivm,
-                                                      (i * 4 + chan) *
-                                                      gs->selector->gs_max_out_vertices * 16 * 4);
+       LLVMBasicBlockRef end_bb;
+       LLVMValueRef switch_inst;
+
+       end_bb = LLVMAppendBasicBlockInContext(gallivm->context, ctx.main_fn, "end");
+       switch_inst = LLVMBuildSwitch(builder, stream_id, end_bb, 4);
+
+       for (int stream = 0; stream < 4; stream++) {
+               LLVMBasicBlockRef bb;
+               unsigned offset;
+
+               if (!gsinfo->num_stream_output_components[stream])
+                       continue;
+
+               if (stream > 0 && !gs_selector->so.num_outputs)
+                       continue;
+
+               bb = LLVMInsertBasicBlockInContext(gallivm->context, end_bb, "out");
+               LLVMAddCase(switch_inst, lp_build_const_int32(gallivm, stream), bb);
+               LLVMPositionBuilderAtEnd(builder, bb);
+
+               /* Fetch vertex data from GSVS ring */
+               offset = 0;
+               for (i = 0; i < gsinfo->num_outputs; ++i) {
+                       for (unsigned chan = 0; chan < 4; chan++) {
+                               if (!(gsinfo->output_usagemask[i] & (1 << chan)) ||
+                                   outputs[i].vertex_stream[chan] != stream) {
+                                       outputs[i].values[chan] = ctx.bld_base.base.undef;
+                                       continue;
+                               }
 
-                       outputs[i].values[chan] =
-                               LLVMBuildBitCast(gallivm->builder,
+                               args[2] = lp_build_const_int32(
+                                       gallivm,
+                                       offset * gs_selector->gs_max_out_vertices * 16 * 4);
+                               offset++;
+
+                               outputs[i].values[chan] =
+                                       LLVMBuildBitCast(gallivm->builder,
                                                 lp_build_intrinsic(gallivm->builder,
                                                                 "llvm.SI.buffer.load.dword.i32.i32",
-                                                                ctx->i32, args, 9,
-                                                                LLVMReadOnlyAttribute),
-                                                ctx->f32, "");
+                                                                ctx.i32, args, 9,
+                                                                LP_FUNC_ATTR_READONLY),
+                                                ctx.f32, "");
+                       }
+               }
+
+               /* Streamout and exports. */
+               if (gs_selector->so.num_outputs) {
+                       si_llvm_emit_streamout(&ctx, outputs,
+                                              gsinfo->num_outputs,
+                                              stream);
                }
+
+               if (stream == 0)
+                       si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
+
+               LLVMBuildBr(builder, end_bb);
        }
 
-       si_llvm_export_vs(bld_base, outputs, gsinfo->num_outputs);
+       LLVMPositionBuilderAtEnd(builder, end_bb);
 
        LLVMBuildRetVoid(gallivm->builder);
 
@@ -6345,30 +6539,34 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen,
            r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY))
                LLVMDumpModule(bld_base->base.gallivm->module);
 
-       radeon_llvm_finalize_module(
-               &ctx->radeon_bld,
+       si_llvm_finalize_module(&ctx,
                r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_GEOMETRY));
 
-       r = si_compile_llvm(sscreen, &ctx->shader->binary,
-                           &ctx->shader->config, ctx->tm,
+       r = si_compile_llvm(sscreen, &ctx.shader->binary,
+                           &ctx.shader->config, ctx.tm,
                            bld_base->base.gallivm->module,
                            debug, PIPE_SHADER_GEOMETRY,
                            "GS Copy Shader");
        if (!r) {
                if (r600_can_dump_shader(&sscreen->b, PIPE_SHADER_GEOMETRY))
                        fprintf(stderr, "GS Copy Shader:\n");
-               si_shader_dump(sscreen, ctx->shader, debug,
-                              PIPE_SHADER_GEOMETRY, stderr);
-               r = si_shader_binary_upload(sscreen, ctx->shader);
+               si_shader_dump(sscreen, ctx.shader, debug,
+                              PIPE_SHADER_GEOMETRY, stderr, true);
+               r = si_shader_binary_upload(sscreen, ctx.shader);
        }
 
-       radeon_llvm_dispose(&ctx->radeon_bld);
+       si_llvm_dispose(&ctx);
 
        FREE(outputs);
-       return r;
+
+       if (r != 0) {
+               FREE(shader);
+               shader = NULL;
+       }
+       return shader;
 }
 
-static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
+static void si_dump_shader_key(unsigned shader, struct si_shader_key *key,
                               FILE *f)
 {
        int i;
@@ -6377,51 +6575,65 @@ static void si_dump_shader_key(unsigned shader, union si_shader_key *key,
 
        switch (shader) {
        case PIPE_SHADER_VERTEX:
-               fprintf(f, "  instance_divisors = {");
-               for (i = 0; i < ARRAY_SIZE(key->vs.prolog.instance_divisors); i++)
+               fprintf(f, "  part.vs.prolog.instance_divisors = {");
+               for (i = 0; i < ARRAY_SIZE(key->part.vs.prolog.instance_divisors); i++)
                        fprintf(f, !i ? "%u" : ", %u",
-                               key->vs.prolog.instance_divisors[i]);
+                               key->part.vs.prolog.instance_divisors[i]);
                fprintf(f, "}\n");
-               fprintf(f, "  as_es = %u\n", key->vs.as_es);
-               fprintf(f, "  as_ls = %u\n", key->vs.as_ls);
-               fprintf(f, "  export_prim_id = %u\n", key->vs.epilog.export_prim_id);
+               fprintf(f, "  part.vs.epilog.export_prim_id = %u\n", key->part.vs.epilog.export_prim_id);
+               fprintf(f, "  as_es = %u\n", key->as_es);
+               fprintf(f, "  as_ls = %u\n", key->as_ls);
+               fprintf(f, "  mono.vs.fix_fetch = 0x%x\n", key->mono.vs.fix_fetch);
                break;
 
        case PIPE_SHADER_TESS_CTRL:
-               fprintf(f, "  prim_mode = %u\n", key->tcs.epilog.prim_mode);
+               fprintf(f, "  part.tcs.epilog.prim_mode = %u\n", key->part.tcs.epilog.prim_mode);
+               fprintf(f, "  mono.tcs.inputs_to_copy = 0x%"PRIx64"\n", key->mono.tcs.inputs_to_copy);
                break;
 
        case PIPE_SHADER_TESS_EVAL:
-               fprintf(f, "  as_es = %u\n", key->tes.as_es);
-               fprintf(f, "  export_prim_id = %u\n", key->tes.epilog.export_prim_id);
+               fprintf(f, "  part.tes.epilog.export_prim_id = %u\n", key->part.tes.epilog.export_prim_id);
+               fprintf(f, "  as_es = %u\n", key->as_es);
                break;
 
        case PIPE_SHADER_GEOMETRY:
+               fprintf(f, "  part.gs.prolog.tri_strip_adj_fix = %u\n", key->part.gs.prolog.tri_strip_adj_fix);
+               break;
+
        case PIPE_SHADER_COMPUTE:
                break;
 
        case PIPE_SHADER_FRAGMENT:
-               fprintf(f, "  prolog.color_two_side = %u\n", key->ps.prolog.color_two_side);
-               fprintf(f, "  prolog.flatshade_colors = %u\n", key->ps.prolog.flatshade_colors);
-               fprintf(f, "  prolog.poly_stipple = %u\n", key->ps.prolog.poly_stipple);
-               fprintf(f, "  prolog.force_persp_sample_interp = %u\n", key->ps.prolog.force_persp_sample_interp);
-               fprintf(f, "  prolog.force_linear_sample_interp = %u\n", key->ps.prolog.force_linear_sample_interp);
-               fprintf(f, "  prolog.force_persp_center_interp = %u\n", key->ps.prolog.force_persp_center_interp);
-               fprintf(f, "  prolog.force_linear_center_interp = %u\n", key->ps.prolog.force_linear_center_interp);
-               fprintf(f, "  prolog.bc_optimize_for_persp = %u\n", key->ps.prolog.bc_optimize_for_persp);
-               fprintf(f, "  prolog.bc_optimize_for_linear = %u\n", key->ps.prolog.bc_optimize_for_linear);
-               fprintf(f, "  epilog.spi_shader_col_format = 0x%x\n", key->ps.epilog.spi_shader_col_format);
-               fprintf(f, "  epilog.color_is_int8 = 0x%X\n", key->ps.epilog.color_is_int8);
-               fprintf(f, "  epilog.last_cbuf = %u\n", key->ps.epilog.last_cbuf);
-               fprintf(f, "  epilog.alpha_func = %u\n", key->ps.epilog.alpha_func);
-               fprintf(f, "  epilog.alpha_to_one = %u\n", key->ps.epilog.alpha_to_one);
-               fprintf(f, "  epilog.poly_line_smoothing = %u\n", key->ps.epilog.poly_line_smoothing);
-               fprintf(f, "  epilog.clamp_color = %u\n", key->ps.epilog.clamp_color);
+               fprintf(f, "  part.ps.prolog.color_two_side = %u\n", key->part.ps.prolog.color_two_side);
+               fprintf(f, "  part.ps.prolog.flatshade_colors = %u\n", key->part.ps.prolog.flatshade_colors);
+               fprintf(f, "  part.ps.prolog.poly_stipple = %u\n", key->part.ps.prolog.poly_stipple);
+               fprintf(f, "  part.ps.prolog.force_persp_sample_interp = %u\n", key->part.ps.prolog.force_persp_sample_interp);
+               fprintf(f, "  part.ps.prolog.force_linear_sample_interp = %u\n", key->part.ps.prolog.force_linear_sample_interp);
+               fprintf(f, "  part.ps.prolog.force_persp_center_interp = %u\n", key->part.ps.prolog.force_persp_center_interp);
+               fprintf(f, "  part.ps.prolog.force_linear_center_interp = %u\n", key->part.ps.prolog.force_linear_center_interp);
+               fprintf(f, "  part.ps.prolog.bc_optimize_for_persp = %u\n", key->part.ps.prolog.bc_optimize_for_persp);
+               fprintf(f, "  part.ps.prolog.bc_optimize_for_linear = %u\n", key->part.ps.prolog.bc_optimize_for_linear);
+               fprintf(f, "  part.ps.epilog.spi_shader_col_format = 0x%x\n", key->part.ps.epilog.spi_shader_col_format);
+               fprintf(f, "  part.ps.epilog.color_is_int8 = 0x%X\n", key->part.ps.epilog.color_is_int8);
+               fprintf(f, "  part.ps.epilog.last_cbuf = %u\n", key->part.ps.epilog.last_cbuf);
+               fprintf(f, "  part.ps.epilog.alpha_func = %u\n", key->part.ps.epilog.alpha_func);
+               fprintf(f, "  part.ps.epilog.alpha_to_one = %u\n", key->part.ps.epilog.alpha_to_one);
+               fprintf(f, "  part.ps.epilog.poly_line_smoothing = %u\n", key->part.ps.epilog.poly_line_smoothing);
+               fprintf(f, "  part.ps.epilog.clamp_color = %u\n", key->part.ps.epilog.clamp_color);
                break;
 
        default:
                assert(0);
        }
+
+       if ((shader == PIPE_SHADER_GEOMETRY ||
+            shader == PIPE_SHADER_TESS_EVAL ||
+            shader == PIPE_SHADER_VERTEX) &&
+           !key->as_es && !key->as_ls) {
+               fprintf(f, "  opt.hw_vs.kill_outputs = 0x%"PRIx64"\n", key->opt.hw_vs.kill_outputs);
+               fprintf(f, "  opt.hw_vs.kill_outputs2 = 0x%x\n", key->opt.hw_vs.kill_outputs2);
+               fprintf(f, "  opt.hw_vs.clip_disable = %u\n", key->opt.hw_vs.clip_disable);
+       }
 }
 
 static void si_init_shader_ctx(struct si_shader_context *ctx,
@@ -6432,33 +6644,11 @@ static void si_init_shader_ctx(struct si_shader_context *ctx,
        struct lp_build_tgsi_context *bld_base;
        struct lp_build_tgsi_action tmpl = {};
 
-       memset(ctx, 0, sizeof(*ctx));
-       radeon_llvm_context_init(
-               &ctx->radeon_bld, "amdgcn--",
+       si_llvm_context_init(ctx, sscreen, shader, tm,
                (shader && shader->selector) ? &shader->selector->info : NULL,
                (shader && shader->selector) ? shader->selector->tokens : NULL);
-       ctx->tm = tm;
-       ctx->screen = sscreen;
-       if (shader && shader->selector)
-               ctx->type = shader->selector->info.processor;
-       else
-               ctx->type = -1;
-       ctx->shader = shader;
-
-       ctx->voidt = LLVMVoidTypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->i1 = LLVMInt1TypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->i8 = LLVMInt8TypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->i32 = LLVMInt32TypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->i64 = LLVMInt64TypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->i128 = LLVMIntTypeInContext(ctx->radeon_bld.gallivm.context, 128);
-       ctx->f32 = LLVMFloatTypeInContext(ctx->radeon_bld.gallivm.context);
-       ctx->v16i8 = LLVMVectorType(ctx->i8, 16);
-       ctx->v2i32 = LLVMVectorType(ctx->i32, 2);
-       ctx->v4i32 = LLVMVectorType(ctx->i32, 4);
-       ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
-       ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
-
-       bld_base = &ctx->radeon_bld.soa.bld_base;
+
+       bld_base = &ctx->bld_base;
        bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = fetch_constant;
 
        bld_base->op_actions[TGSI_OPCODE_INTERP_CENTROID] = interp_action;
@@ -6520,110 +6710,832 @@ static void si_init_shader_ctx(struct si_shader_context *ctx,
        bld_base->op_actions[TGSI_OPCODE_EMIT].emit = si_llvm_emit_vertex;
        bld_base->op_actions[TGSI_OPCODE_ENDPRIM].emit = si_llvm_emit_primitive;
        bld_base->op_actions[TGSI_OPCODE_BARRIER].emit = si_llvm_emit_barrier;
-
-       bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
-       bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.maxnum.f32";
-       bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
-       bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.minnum.f32";
 }
 
-int si_compile_tgsi_shader(struct si_screen *sscreen,
-                          LLVMTargetMachineRef tm,
-                          struct si_shader *shader,
-                          bool is_monolithic,
-                          struct pipe_debug_callback *debug)
+/* Return true if the PARAM export has been eliminated. */
+static bool si_eliminate_const_output(struct si_shader_context *ctx,
+                                     LLVMValueRef inst, unsigned offset)
 {
-       struct si_shader_selector *sel = shader->selector;
-       struct si_shader_context ctx;
-       struct lp_build_tgsi_context *bld_base;
-       LLVMModuleRef mod;
-       int r = 0;
+       struct si_shader *shader = ctx->shader;
+       unsigned num_outputs = shader->selector->info.num_outputs;
+       unsigned i, default_val; /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL */
+       bool is_zero[4] = {}, is_one[4] = {};
 
-       /* Dump TGSI code before doing TGSI->LLVM conversion in case the
-        * conversion fails. */
-       if (r600_can_dump_shader(&sscreen->b, sel->info.processor) &&
-           !(sscreen->b.debug_flags & DBG_NO_TGSI)) {
-               tgsi_dump(sel->tokens, 0);
+       for (i = 0; i < 4; i++) {
+               LLVMBool loses_info;
+               LLVMValueRef p = LLVMGetOperand(inst, 5 + i);
+
+               /* It's a constant expression. Undef outputs are eliminated too. */
+               if (LLVMIsUndef(p)) {
+                       is_zero[i] = true;
+                       is_one[i] = true;
+               } else if (LLVMIsAConstantFP(p)) {
+                       double a = LLVMConstRealGetDouble(p, &loses_info);
+
+                       if (a == 0)
+                               is_zero[i] = true;
+                       else if (a == 1)
+                               is_one[i] = true;
+                       else
+                               return false; /* other constant */
+               } else
+                       return false;
+       }
+
+       /* Only certain combinations of 0 and 1 can be eliminated. */
+       if (is_zero[0] && is_zero[1] && is_zero[2])
+               default_val = is_zero[3] ? 0 : 1;
+       else if (is_one[0] && is_one[1] && is_one[2])
+               default_val = is_zero[3] ? 2 : 3;
+       else
+               return false;
+
+       /* The PARAM export can be represented as DEFAULT_VAL. Kill it. */
+       LLVMInstructionEraseFromParent(inst);
+
+       /* Change OFFSET to DEFAULT_VAL. */
+       for (i = 0; i < num_outputs; i++) {
+               if (shader->info.vs_output_param_offset[i] == offset) {
+                       shader->info.vs_output_param_offset[i] =
+                               EXP_PARAM_DEFAULT_VAL_0000 + default_val;
+                       break;
+               }
+       }
+       return true;
+}
+
+struct si_vs_exports {
+       unsigned num;
+       unsigned offset[SI_MAX_VS_OUTPUTS];
+       LLVMValueRef inst[SI_MAX_VS_OUTPUTS];
+};
+
+static void si_eliminate_const_vs_outputs(struct si_shader_context *ctx)
+{
+       struct si_shader *shader = ctx->shader;
+       struct tgsi_shader_info *info = &shader->selector->info;
+       LLVMBasicBlockRef bb;
+       struct si_vs_exports exports;
+       bool removed_any = false;
+
+       exports.num = 0;
+
+       if (ctx->type == PIPE_SHADER_FRAGMENT ||
+           ctx->type == PIPE_SHADER_COMPUTE ||
+           shader->key.as_es ||
+           shader->key.as_ls)
+               return;
+
+       /* Process all LLVM instructions. */
+       bb = LLVMGetFirstBasicBlock(ctx->main_fn);
+       while (bb) {
+               LLVMValueRef inst = LLVMGetFirstInstruction(bb);
+
+               while (inst) {
+                       LLVMValueRef cur = inst;
+                       inst = LLVMGetNextInstruction(inst);
+
+                       if (LLVMGetInstructionOpcode(cur) != LLVMCall)
+                               continue;
+
+                       LLVMValueRef callee = lp_get_called_value(cur);
+
+                       if (!lp_is_function(callee))
+                               continue;
+
+                       const char *name = LLVMGetValueName(callee);
+                       unsigned num_args = LLVMCountParams(callee);
+
+                       /* Check if this is an export instruction. */
+                       if (num_args != 9 || strcmp(name, "llvm.SI.export"))
+                               continue;
+
+                       LLVMValueRef arg = LLVMGetOperand(cur, 3);
+                       unsigned target = LLVMConstIntGetZExtValue(arg);
+
+                       if (target < V_008DFC_SQ_EXP_PARAM)
+                               continue;
+
+                       target -= V_008DFC_SQ_EXP_PARAM;
+
+                       /* Eliminate constant value PARAM exports. */
+                       if (si_eliminate_const_output(ctx, cur, target)) {
+                               removed_any = true;
+                       } else {
+                               exports.offset[exports.num] = target;
+                               exports.inst[exports.num] = cur;
+                               exports.num++;
+                       }
+               }
+               bb = LLVMGetNextBasicBlock(bb);
+       }
+
+       /* Remove holes in export memory due to removed PARAM exports.
+        * This is done by renumbering all PARAM exports.
+        */
+       if (removed_any) {
+               ubyte current_offset[SI_MAX_VS_OUTPUTS];
+               unsigned new_count = 0;
+               unsigned out, i;
+
+               /* Make a copy of the offsets. We need the old version while
+                * we are modifying some of them. */
+               assert(sizeof(current_offset) ==
+                      sizeof(shader->info.vs_output_param_offset));
+               memcpy(current_offset, shader->info.vs_output_param_offset,
+                      sizeof(current_offset));
+
+               for (i = 0; i < exports.num; i++) {
+                       unsigned offset = exports.offset[i];
+
+                       for (out = 0; out < info->num_outputs; out++) {
+                               if (current_offset[out] != offset)
+                                       continue;
+
+                               LLVMSetOperand(exports.inst[i], 3,
+                                              LLVMConstInt(ctx->i32,
+                                                           V_008DFC_SQ_EXP_PARAM + new_count, 0));
+                               shader->info.vs_output_param_offset[out] = new_count;
+                               new_count++;
+                               break;
+                       }
+               }
+               shader->info.nr_param_exports = new_count;
+       }
+}
+
+static void si_count_scratch_private_memory(struct si_shader_context *ctx)
+{
+       ctx->shader->config.private_mem_vgprs = 0;
+
+       /* Process all LLVM instructions. */
+       LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(ctx->main_fn);
+       while (bb) {
+               LLVMValueRef next = LLVMGetFirstInstruction(bb);
+
+               while (next) {
+                       LLVMValueRef inst = next;
+                       next = LLVMGetNextInstruction(next);
+
+                       if (LLVMGetInstructionOpcode(inst) != LLVMAlloca)
+                               continue;
+
+                       LLVMTypeRef type = LLVMGetElementType(LLVMTypeOf(inst));
+                       /* No idea why LLVM aligns allocas to 4 elements. */
+                       unsigned alignment = LLVMGetAlignment(inst);
+                       unsigned dw_size = align(llvm_get_type_size(type) / 4, alignment);
+                       ctx->shader->config.private_mem_vgprs += dw_size;
+               }
+               bb = LLVMGetNextBasicBlock(bb);
+       }
+}
+
+static bool si_compile_tgsi_main(struct si_shader_context *ctx,
+                                struct si_shader *shader)
+{
+       struct si_shader_selector *sel = shader->selector;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
+
+       switch (ctx->type) {
+       case PIPE_SHADER_VERTEX:
+               ctx->load_input = declare_input_vs;
+               if (shader->key.as_ls)
+                       bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
+               else if (shader->key.as_es)
+                       bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
+               else
+                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+               break;
+       case PIPE_SHADER_TESS_CTRL:
+               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
+               bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs;
+               bld_base->emit_store = store_output_tcs;
+               bld_base->emit_epilogue = si_llvm_emit_tcs_epilogue;
+               break;
+       case PIPE_SHADER_TESS_EVAL:
+               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes;
+               if (shader->key.as_es)
+                       bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
+               else
+                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
+               break;
+       case PIPE_SHADER_GEOMETRY:
+               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_gs;
+               bld_base->emit_epilogue = si_llvm_emit_gs_epilogue;
+               break;
+       case PIPE_SHADER_FRAGMENT:
+               ctx->load_input = declare_input_fs;
+               bld_base->emit_epilogue = si_llvm_return_fs_outputs;
+               break;
+       case PIPE_SHADER_COMPUTE:
+               ctx->declare_memory_region = declare_compute_memory;
+               break;
+       default:
+               assert(!"Unsupported shader type");
+               return false;
+       }
+
+       create_meta_data(ctx);
+       create_function(ctx);
+       preload_ring_buffers(ctx);
+
+       if (ctx->type == PIPE_SHADER_GEOMETRY) {
+               int i;
+               for (i = 0; i < 4; i++) {
+                       ctx->gs_next_vertex[i] =
+                               lp_build_alloca(bld_base->base.gallivm,
+                                               ctx->i32, "");
+               }
+       }
+
+       if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
+               fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
+               return false;
+       }
+
+       si_llvm_build_ret(ctx, ctx->return_value);
+       return true;
+}
+
+/**
+ * Compute the VS prolog key, which contains all the information needed to
+ * build the VS prolog function, and set shader->info bits where needed.
+ */
+static void si_get_vs_prolog_key(struct si_shader *shader,
+                                union si_shader_part_key *key)
+{
+       struct tgsi_shader_info *info = &shader->selector->info;
+
+       memset(key, 0, sizeof(*key));
+       key->vs_prolog.states = shader->key.part.vs.prolog;
+       key->vs_prolog.num_input_sgprs = shader->info.num_input_sgprs;
+       key->vs_prolog.last_input = MAX2(1, info->num_inputs) - 1;
+
+       /* Set the instanceID flag. */
+       for (unsigned i = 0; i < info->num_inputs; i++)
+               if (key->vs_prolog.states.instance_divisors[i])
+                       shader->info.uses_instanceid = true;
+}
+
+/**
+ * Compute the VS epilog key, which contains all the information needed to
+ * build the VS epilog function, and set the PrimitiveID output offset.
+ */
+static void si_get_vs_epilog_key(struct si_shader *shader,
+                                struct si_vs_epilog_bits *states,
+                                union si_shader_part_key *key)
+{
+       memset(key, 0, sizeof(*key));
+       key->vs_epilog.states = *states;
+
+       /* Set up the PrimitiveID output. */
+       if (shader->key.part.vs.epilog.export_prim_id) {
+               unsigned index = shader->selector->info.num_outputs;
+               unsigned offset = shader->info.nr_param_exports++;
+
+               key->vs_epilog.prim_id_param_offset = offset;
+               assert(index < ARRAY_SIZE(shader->info.vs_output_param_offset));
+               shader->info.vs_output_param_offset[index] = offset;
+       }
+}
+
+/**
+ * Compute the PS prolog key, which contains all the information needed to
+ * build the PS prolog function, and set related bits in shader->config.
+ */
+static void si_get_ps_prolog_key(struct si_shader *shader,
+                                union si_shader_part_key *key,
+                                bool separate_prolog)
+{
+       struct tgsi_shader_info *info = &shader->selector->info;
+
+       memset(key, 0, sizeof(*key));
+       key->ps_prolog.states = shader->key.part.ps.prolog;
+       key->ps_prolog.colors_read = info->colors_read;
+       key->ps_prolog.num_input_sgprs = shader->info.num_input_sgprs;
+       key->ps_prolog.num_input_vgprs = shader->info.num_input_vgprs;
+       key->ps_prolog.wqm = info->uses_derivatives &&
+               (key->ps_prolog.colors_read ||
+                key->ps_prolog.states.force_persp_sample_interp ||
+                key->ps_prolog.states.force_linear_sample_interp ||
+                key->ps_prolog.states.force_persp_center_interp ||
+                key->ps_prolog.states.force_linear_center_interp ||
+                key->ps_prolog.states.bc_optimize_for_persp ||
+                key->ps_prolog.states.bc_optimize_for_linear);
+
+       if (info->colors_read) {
+               unsigned *color = shader->selector->color_attr_index;
+
+               if (shader->key.part.ps.prolog.color_two_side) {
+                       /* BCOLORs are stored after the last input. */
+                       key->ps_prolog.num_interp_inputs = info->num_inputs;
+                       key->ps_prolog.face_vgpr_index = shader->info.face_vgpr_index;
+                       shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1);
+               }
+
+               for (unsigned i = 0; i < 2; i++) {
+                       unsigned interp = info->input_interpolate[color[i]];
+                       unsigned location = info->input_interpolate_loc[color[i]];
+
+                       if (!(info->colors_read & (0xf << i*4)))
+                               continue;
+
+                       key->ps_prolog.color_attr_index[i] = color[i];
+
+                       if (shader->key.part.ps.prolog.flatshade_colors &&
+                           interp == TGSI_INTERPOLATE_COLOR)
+                               interp = TGSI_INTERPOLATE_CONSTANT;
+
+                       switch (interp) {
+                       case TGSI_INTERPOLATE_CONSTANT:
+                               key->ps_prolog.color_interp_vgpr_index[i] = -1;
+                               break;
+                       case TGSI_INTERPOLATE_PERSPECTIVE:
+                       case TGSI_INTERPOLATE_COLOR:
+                               /* Force the interpolation location for colors here. */
+                               if (shader->key.part.ps.prolog.force_persp_sample_interp)
+                                       location = TGSI_INTERPOLATE_LOC_SAMPLE;
+                               if (shader->key.part.ps.prolog.force_persp_center_interp)
+                                       location = TGSI_INTERPOLATE_LOC_CENTER;
+
+                               switch (location) {
+                               case TGSI_INTERPOLATE_LOC_SAMPLE:
+                                       key->ps_prolog.color_interp_vgpr_index[i] = 0;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_PERSP_SAMPLE_ENA(1);
+                                       break;
+                               case TGSI_INTERPOLATE_LOC_CENTER:
+                                       key->ps_prolog.color_interp_vgpr_index[i] = 2;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_PERSP_CENTER_ENA(1);
+                                       break;
+                               case TGSI_INTERPOLATE_LOC_CENTROID:
+                                       key->ps_prolog.color_interp_vgpr_index[i] = 4;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_PERSP_CENTROID_ENA(1);
+                                       break;
+                               default:
+                                       assert(0);
+                               }
+                               break;
+                       case TGSI_INTERPOLATE_LINEAR:
+                               /* Force the interpolation location for colors here. */
+                               if (shader->key.part.ps.prolog.force_linear_sample_interp)
+                                       location = TGSI_INTERPOLATE_LOC_SAMPLE;
+                               if (shader->key.part.ps.prolog.force_linear_center_interp)
+                                       location = TGSI_INTERPOLATE_LOC_CENTER;
+
+                               /* The VGPR assignment for non-monolithic shaders
+                                * works because InitialPSInputAddr is set on the
+                                * main shader and PERSP_PULL_MODEL is never used.
+                                */
+                               switch (location) {
+                               case TGSI_INTERPOLATE_LOC_SAMPLE:
+                                       key->ps_prolog.color_interp_vgpr_index[i] =
+                                               separate_prolog ? 6 : 9;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_LINEAR_SAMPLE_ENA(1);
+                                       break;
+                               case TGSI_INTERPOLATE_LOC_CENTER:
+                                       key->ps_prolog.color_interp_vgpr_index[i] =
+                                               separate_prolog ? 8 : 11;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_LINEAR_CENTER_ENA(1);
+                                       break;
+                               case TGSI_INTERPOLATE_LOC_CENTROID:
+                                       key->ps_prolog.color_interp_vgpr_index[i] =
+                                               separate_prolog ? 10 : 13;
+                                       shader->config.spi_ps_input_ena |=
+                                               S_0286CC_LINEAR_CENTROID_ENA(1);
+                                       break;
+                               default:
+                                       assert(0);
+                               }
+                               break;
+                       default:
+                               assert(0);
+                       }
+               }
+       }
+}
+
+/**
+ * Check whether a PS prolog is required based on the key.
+ */
+static bool si_need_ps_prolog(const union si_shader_part_key *key)
+{
+       return key->ps_prolog.colors_read ||
+              key->ps_prolog.states.force_persp_sample_interp ||
+              key->ps_prolog.states.force_linear_sample_interp ||
+              key->ps_prolog.states.force_persp_center_interp ||
+              key->ps_prolog.states.force_linear_center_interp ||
+              key->ps_prolog.states.bc_optimize_for_persp ||
+              key->ps_prolog.states.bc_optimize_for_linear ||
+              key->ps_prolog.states.poly_stipple;
+}
+
+/**
+ * Compute the PS epilog key, which contains all the information needed to
+ * build the PS epilog function.
+ */
+static void si_get_ps_epilog_key(struct si_shader *shader,
+                                union si_shader_part_key *key)
+{
+       struct tgsi_shader_info *info = &shader->selector->info;
+       memset(key, 0, sizeof(*key));
+       key->ps_epilog.colors_written = info->colors_written;
+       key->ps_epilog.writes_z = info->writes_z;
+       key->ps_epilog.writes_stencil = info->writes_stencil;
+       key->ps_epilog.writes_samplemask = info->writes_samplemask;
+       key->ps_epilog.states = shader->key.part.ps.epilog;
+}
+
+/**
+ * Build the GS prolog function. Rotate the input vertices for triangle strips
+ * with adjacency.
+ */
+static void si_build_gs_prolog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key)
+{
+       const unsigned num_sgprs = SI_GS_NUM_USER_SGPR + 2;
+       const unsigned num_vgprs = 8;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       LLVMBuilderRef builder = gallivm->builder;
+       LLVMTypeRef params[32];
+       LLVMTypeRef returns[32];
+       LLVMValueRef func, ret;
+
+       for (unsigned i = 0; i < num_sgprs; ++i) {
+               params[i] = ctx->i32;
+               returns[i] = ctx->i32;
+       }
+
+       for (unsigned i = 0; i < num_vgprs; ++i) {
+               params[num_sgprs + i] = ctx->i32;
+               returns[num_sgprs + i] = ctx->f32;
+       }
+
+       /* Create the function. */
+       si_create_function(ctx, "gs_prolog", returns, num_sgprs + num_vgprs,
+                          params, num_sgprs + num_vgprs, num_sgprs - 1);
+       func = ctx->main_fn;
+
+       /* Copy inputs to outputs. This should be no-op, as the registers match,
+        * but it will prevent the compiler from overwriting them unintentionally.
+        */
+       ret = ctx->return_value;
+       for (unsigned i = 0; i < num_sgprs; i++) {
+               LLVMValueRef p = LLVMGetParam(func, i);
+               ret = LLVMBuildInsertValue(builder, ret, p, i, "");
+       }
+       for (unsigned i = 0; i < num_vgprs; i++) {
+               LLVMValueRef p = LLVMGetParam(func, num_sgprs + i);
+               p = LLVMBuildBitCast(builder, p, ctx->f32, "");
+               ret = LLVMBuildInsertValue(builder, ret, p, num_sgprs + i, "");
+       }
+
+       if (key->gs_prolog.states.tri_strip_adj_fix) {
+               /* Remap the input vertices for every other primitive. */
+               const unsigned vtx_params[6] = {
+                       num_sgprs,
+                       num_sgprs + 1,
+                       num_sgprs + 3,
+                       num_sgprs + 4,
+                       num_sgprs + 5,
+                       num_sgprs + 6
+               };
+               LLVMValueRef prim_id, rotate;
+
+               prim_id = LLVMGetParam(func, num_sgprs + 2);
+               rotate = LLVMBuildTrunc(builder, prim_id, ctx->i1, "");
+
+               for (unsigned i = 0; i < 6; ++i) {
+                       LLVMValueRef base, rotated, actual;
+                       base = LLVMGetParam(func, vtx_params[i]);
+                       rotated = LLVMGetParam(func, vtx_params[(i + 4) % 6]);
+                       actual = LLVMBuildSelect(builder, rotate, rotated, base, "");
+                       actual = LLVMBuildBitCast(builder, actual, ctx->f32, "");
+                       ret = LLVMBuildInsertValue(builder, ret, actual, vtx_params[i], "");
+               }
+       }
+
+       LLVMBuildRet(builder, ret);
+}
+
+/**
+ * Given a list of shader part functions, build a wrapper function that
+ * runs them in sequence to form a monolithic shader.
+ */
+static void si_build_wrapper_function(struct si_shader_context *ctx,
+                                     LLVMValueRef *parts,
+                                     unsigned num_parts,
+                                     unsigned main_part)
+{
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       LLVMBuilderRef builder = ctx->gallivm.builder;
+       /* PS epilog has one arg per color component */
+       LLVMTypeRef param_types[48];
+       LLVMValueRef out[48];
+       LLVMTypeRef function_type;
+       unsigned num_params;
+       unsigned num_out;
+       MAYBE_UNUSED unsigned num_out_sgpr; /* used in debug checks */
+       unsigned num_sgprs, num_vgprs;
+       unsigned last_sgpr_param;
+       unsigned gprs;
+
+       for (unsigned i = 0; i < num_parts; ++i) {
+               lp_add_function_attr(parts[i], -1, LP_FUNC_ATTR_ALWAYSINLINE);
+               LLVMSetLinkage(parts[i], LLVMPrivateLinkage);
+       }
+
+       /* The parameters of the wrapper function correspond to those of the
+        * first part in terms of SGPRs and VGPRs, but we use the types of the
+        * main part to get the right types. This is relevant for the
+        * dereferenceable attribute on descriptor table pointers.
+        */
+       num_sgprs = 0;
+       num_vgprs = 0;
+
+       function_type = LLVMGetElementType(LLVMTypeOf(parts[0]));
+       num_params = LLVMCountParamTypes(function_type);
+
+       for (unsigned i = 0; i < num_params; ++i) {
+               LLVMValueRef param = LLVMGetParam(parts[0], i);
+
+               if (ac_is_sgpr_param(param)) {
+                       assert(num_vgprs == 0);
+                       num_sgprs += llvm_get_type_size(LLVMTypeOf(param)) / 4;
+               } else {
+                       num_vgprs += llvm_get_type_size(LLVMTypeOf(param)) / 4;
+               }
+       }
+       assert(num_vgprs + num_sgprs <= ARRAY_SIZE(param_types));
+
+       num_params = 0;
+       last_sgpr_param = 0;
+       gprs = 0;
+       while (gprs < num_sgprs + num_vgprs) {
+               LLVMValueRef param = LLVMGetParam(parts[main_part], num_params);
+               unsigned size;
+
+               param_types[num_params] = LLVMTypeOf(param);
+               if (gprs < num_sgprs)
+                       last_sgpr_param = num_params;
+               size = llvm_get_type_size(param_types[num_params]) / 4;
+               num_params++;
+
+               assert(ac_is_sgpr_param(param) == (gprs < num_sgprs));
+               assert(gprs + size <= num_sgprs + num_vgprs &&
+                      (gprs >= num_sgprs || gprs + size <= num_sgprs));
+
+               gprs += size;
+       }
+
+       si_create_function(ctx, "wrapper", NULL, 0, param_types, num_params, last_sgpr_param);
+
+       /* Record the arguments of the function as if they were an output of
+        * a previous part.
+        */
+       num_out = 0;
+       num_out_sgpr = 0;
+
+       for (unsigned i = 0; i < num_params; ++i) {
+               LLVMValueRef param = LLVMGetParam(ctx->main_fn, i);
+               LLVMTypeRef param_type = LLVMTypeOf(param);
+               LLVMTypeRef out_type = i <= last_sgpr_param ? ctx->i32 : ctx->f32;
+               unsigned size = llvm_get_type_size(param_type) / 4;
+
+               if (size == 1) {
+                       if (param_type != out_type)
+                               param = LLVMBuildBitCast(builder, param, out_type, "");
+                       out[num_out++] = param;
+               } else {
+                       LLVMTypeRef vector_type = LLVMVectorType(out_type, size);
+
+                       if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) {
+                               param = LLVMBuildPtrToInt(builder, param, ctx->i64, "");
+                               param_type = ctx->i64;
+                       }
+
+                       if (param_type != vector_type)
+                               param = LLVMBuildBitCast(builder, param, vector_type, "");
+
+                       for (unsigned j = 0; j < size; ++j)
+                               out[num_out++] = LLVMBuildExtractElement(
+                                       builder, param, LLVMConstInt(ctx->i32, j, 0), "");
+               }
+
+               if (i <= last_sgpr_param)
+                       num_out_sgpr = num_out;
+       }
+
+       /* Now chain the parts. */
+       for (unsigned part = 0; part < num_parts; ++part) {
+               LLVMValueRef in[48];
+               LLVMValueRef ret;
+               LLVMTypeRef ret_type;
+               unsigned out_idx = 0;
+
+               num_params = LLVMCountParams(parts[part]);
+               assert(num_params <= ARRAY_SIZE(param_types));
+
+               /* Derive arguments for the next part from outputs of the
+                * previous one.
+                */
+               for (unsigned param_idx = 0; param_idx < num_params; ++param_idx) {
+                       LLVMValueRef param;
+                       LLVMTypeRef param_type;
+                       bool is_sgpr;
+                       unsigned param_size;
+                       LLVMValueRef arg = NULL;
+
+                       param = LLVMGetParam(parts[part], param_idx);
+                       param_type = LLVMTypeOf(param);
+                       param_size = llvm_get_type_size(param_type) / 4;
+                       is_sgpr = ac_is_sgpr_param(param);
+
+                       if (is_sgpr) {
+#if HAVE_LLVM < 0x0400
+                               LLVMRemoveAttribute(param, LLVMByValAttribute);
+#else
+                               unsigned kind_id = LLVMGetEnumAttributeKindForName("byval", 5);
+                               LLVMRemoveEnumAttributeAtIndex(parts[part], param_idx + 1, kind_id);
+#endif
+                               lp_add_function_attr(parts[part], param_idx + 1, LP_FUNC_ATTR_INREG);
+                       }
+
+                       assert(out_idx + param_size <= (is_sgpr ? num_out_sgpr : num_out));
+                       assert(is_sgpr || out_idx >= num_out_sgpr);
+
+                       if (param_size == 1)
+                               arg = out[out_idx];
+                       else
+                               arg = lp_build_gather_values(gallivm, &out[out_idx], param_size);
+
+                       if (LLVMTypeOf(arg) != param_type) {
+                               if (LLVMGetTypeKind(param_type) == LLVMPointerTypeKind) {
+                                       arg = LLVMBuildBitCast(builder, arg, ctx->i64, "");
+                                       arg = LLVMBuildIntToPtr(builder, arg, param_type, "");
+                               } else {
+                                       arg = LLVMBuildBitCast(builder, arg, param_type, "");
+                               }
+                       }
+
+                       in[param_idx] = arg;
+                       out_idx += param_size;
+               }
+
+               ret = LLVMBuildCall(builder, parts[part], in, num_params, "");
+               ret_type = LLVMTypeOf(ret);
+
+               /* Extract the returned GPRs. */
+               num_out = 0;
+               num_out_sgpr = 0;
+
+               if (LLVMGetTypeKind(ret_type) != LLVMVoidTypeKind) {
+                       assert(LLVMGetTypeKind(ret_type) == LLVMStructTypeKind);
+
+                       unsigned ret_size = LLVMCountStructElementTypes(ret_type);
+
+                       for (unsigned i = 0; i < ret_size; ++i) {
+                               LLVMValueRef val =
+                                       LLVMBuildExtractValue(builder, ret, i, "");
+
+                               out[num_out++] = val;
+
+                               if (LLVMTypeOf(val) == ctx->i32) {
+                                       assert(num_out_sgpr + 1 == num_out);
+                                       num_out_sgpr = num_out;
+                               }
+                       }
+               }
+       }
+
+       LLVMBuildRetVoid(builder);
+}
+
+int si_compile_tgsi_shader(struct si_screen *sscreen,
+                          LLVMTargetMachineRef tm,
+                          struct si_shader *shader,
+                          bool is_monolithic,
+                          struct pipe_debug_callback *debug)
+{
+       struct si_shader_selector *sel = shader->selector;
+       struct si_shader_context ctx;
+       struct lp_build_tgsi_context *bld_base;
+       LLVMModuleRef mod;
+       int r = -1;
+
+       /* Dump TGSI code before doing TGSI->LLVM conversion in case the
+        * conversion fails. */
+       if (r600_can_dump_shader(&sscreen->b, sel->info.processor) &&
+           !(sscreen->b.debug_flags & DBG_NO_TGSI)) {
+               tgsi_dump(sel->tokens, 0);
                si_dump_streamout(&sel->so);
        }
 
        si_init_shader_ctx(&ctx, sscreen, shader, tm);
-       ctx.is_monolithic = is_monolithic;
+       ctx.separate_prolog = !is_monolithic;
+
+       memset(shader->info.vs_output_param_offset, EXP_PARAM_UNDEFINED,
+              sizeof(shader->info.vs_output_param_offset));
 
        shader->info.uses_instanceid = sel->info.uses_instanceid;
 
-       bld_base = &ctx.radeon_bld.soa.bld_base;
-       ctx.radeon_bld.load_system_value = declare_system_value;
+       bld_base = &ctx.bld_base;
+       ctx.load_system_value = declare_system_value;
 
-       switch (ctx.type) {
-       case PIPE_SHADER_VERTEX:
-               ctx.radeon_bld.load_input = declare_input_vs;
-               if (shader->key.vs.as_ls)
-                       bld_base->emit_epilogue = si_llvm_emit_ls_epilogue;
-               else if (shader->key.vs.as_es)
-                       bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
-               else
-                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
-               break;
-       case PIPE_SHADER_TESS_CTRL:
-               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tcs;
-               bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = fetch_output_tcs;
-               bld_base->emit_store = store_output_tcs;
-               bld_base->emit_epilogue = si_llvm_emit_tcs_epilogue;
-               break;
-       case PIPE_SHADER_TESS_EVAL:
-               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_tes;
-               if (shader->key.tes.as_es)
-                       bld_base->emit_epilogue = si_llvm_emit_es_epilogue;
-               else
-                       bld_base->emit_epilogue = si_llvm_emit_vs_epilogue;
-               break;
-       case PIPE_SHADER_GEOMETRY:
-               bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = fetch_input_gs;
-               bld_base->emit_epilogue = si_llvm_emit_gs_epilogue;
-               break;
-       case PIPE_SHADER_FRAGMENT:
-               ctx.radeon_bld.load_input = declare_input_fs;
-               if (is_monolithic)
-                       bld_base->emit_epilogue = si_llvm_emit_fs_epilogue;
-               else
-                       bld_base->emit_epilogue = si_llvm_return_fs_outputs;
-               break;
-       case PIPE_SHADER_COMPUTE:
-               ctx.radeon_bld.declare_memory_region = declare_compute_memory;
-               break;
-       default:
-               assert(!"Unsupported shader type");
+       if (!si_compile_tgsi_main(&ctx, shader)) {
+               si_llvm_dispose(&ctx);
                return -1;
        }
 
-       create_meta_data(&ctx);
-       create_function(&ctx);
-       preload_ring_buffers(&ctx);
+       if (is_monolithic && ctx.type == PIPE_SHADER_VERTEX) {
+               LLVMValueRef parts[3];
+               bool need_prolog;
+               bool need_epilog;
 
-       if (ctx.is_monolithic && sel->type == PIPE_SHADER_FRAGMENT &&
-           shader->key.ps.prolog.poly_stipple) {
-               LLVMValueRef list = LLVMGetParam(ctx.radeon_bld.main_fn,
-                                                SI_PARAM_RW_BUFFERS);
-               si_llvm_emit_polygon_stipple(&ctx, list,
-                                            SI_PARAM_POS_FIXED_PT);
-       }
+               need_prolog = sel->info.num_inputs;
+               need_epilog = !shader->key.as_es && !shader->key.as_ls;
 
-       if (ctx.type == PIPE_SHADER_GEOMETRY) {
-               int i;
-               for (i = 0; i < 4; i++) {
-                       ctx.gs_next_vertex[i] =
-                               lp_build_alloca(bld_base->base.gallivm,
-                                               ctx.i32, "");
+               parts[need_prolog ? 1 : 0] = ctx.main_fn;
+
+               if (need_prolog) {
+                       union si_shader_part_key prolog_key;
+                       si_get_vs_prolog_key(shader, &prolog_key);
+                       si_build_vs_prolog_function(&ctx, &prolog_key);
+                       parts[0] = ctx.main_fn;
                }
-       }
 
-       if (!lp_build_tgsi_llvm(bld_base, sel->tokens)) {
-               fprintf(stderr, "Failed to translate shader from TGSI to LLVM\n");
-               goto out;
+               if (need_epilog) {
+                       union si_shader_part_key epilog_key;
+                       si_get_vs_epilog_key(shader, &shader->key.part.vs.epilog, &epilog_key);
+                       si_build_vs_epilog_function(&ctx, &epilog_key);
+                       parts[need_prolog ? 2 : 1] = ctx.main_fn;
+               }
+
+               si_build_wrapper_function(&ctx, parts, 1 + need_prolog + need_epilog,
+                                         need_prolog ? 1 : 0);
+       } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_CTRL) {
+               LLVMValueRef parts[2];
+               union si_shader_part_key epilog_key;
+
+               parts[0] = ctx.main_fn;
+
+               memset(&epilog_key, 0, sizeof(epilog_key));
+               epilog_key.tcs_epilog.states = shader->key.part.tcs.epilog;
+               si_build_tcs_epilog_function(&ctx, &epilog_key);
+               parts[1] = ctx.main_fn;
+
+               si_build_wrapper_function(&ctx, parts, 2, 0);
+       } else if (is_monolithic && ctx.type == PIPE_SHADER_TESS_EVAL &&
+                  !shader->key.as_es) {
+               LLVMValueRef parts[2];
+               union si_shader_part_key epilog_key;
+
+               parts[0] = ctx.main_fn;
+
+               si_get_vs_epilog_key(shader, &shader->key.part.tes.epilog, &epilog_key);
+               si_build_vs_epilog_function(&ctx, &epilog_key);
+               parts[1] = ctx.main_fn;
+
+               si_build_wrapper_function(&ctx, parts, 2, 0);
+       } else if (is_monolithic && ctx.type == PIPE_SHADER_GEOMETRY) {
+               LLVMValueRef parts[2];
+               union si_shader_part_key prolog_key;
+
+               parts[1] = ctx.main_fn;
+
+               memset(&prolog_key, 0, sizeof(prolog_key));
+               prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
+               si_build_gs_prolog_function(&ctx, &prolog_key);
+               parts[0] = ctx.main_fn;
+
+               si_build_wrapper_function(&ctx, parts, 2, 1);
+       } else if (is_monolithic && ctx.type == PIPE_SHADER_FRAGMENT) {
+               LLVMValueRef parts[3];
+               union si_shader_part_key prolog_key;
+               union si_shader_part_key epilog_key;
+               bool need_prolog;
+
+               si_get_ps_prolog_key(shader, &prolog_key, false);
+               need_prolog = si_need_ps_prolog(&prolog_key);
+
+               parts[need_prolog ? 1 : 0] = ctx.main_fn;
+
+               if (need_prolog) {
+                       si_build_ps_prolog_function(&ctx, &prolog_key);
+                       parts[0] = ctx.main_fn;
+               }
+
+               si_get_ps_epilog_key(shader, &epilog_key);
+               si_build_ps_epilog_function(&ctx, &epilog_key);
+               parts[need_prolog ? 2 : 1] = ctx.main_fn;
+
+               si_build_wrapper_function(&ctx, parts, need_prolog ? 3 : 2, need_prolog ? 1 : 0);
        }
 
-       si_llvm_build_ret(&ctx, ctx.return_value);
        mod = bld_base->base.gallivm->module;
 
        /* Dump LLVM IR before any optimization passes */
@@ -6631,33 +7543,35 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
            r600_can_dump_shader(&sscreen->b, ctx.type))
                LLVMDumpModule(mod);
 
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, ctx.type));
+       si_llvm_finalize_module(&ctx,
+                                   r600_extra_shader_checks(&sscreen->b, ctx.type));
+
+       /* Post-optimization transformations and analysis. */
+       si_eliminate_const_vs_outputs(&ctx);
 
+       if ((debug && debug->debug_message) ||
+           r600_can_dump_shader(&sscreen->b, ctx.type))
+               si_count_scratch_private_memory(&ctx);
+
+       /* Compile to bytecode. */
        r = si_compile_llvm(sscreen, &shader->binary, &shader->config, tm,
                            mod, debug, ctx.type, "TGSI shader");
+       si_llvm_dispose(&ctx);
        if (r) {
                fprintf(stderr, "LLVM failed to compile shader\n");
-               goto out;
+               return r;
        }
 
-       radeon_llvm_dispose(&ctx.radeon_bld);
-
        /* Validate SGPR and VGPR usage for compute to detect compiler bugs.
         * LLVM 3.9svn has this bug.
         */
        if (sel->type == PIPE_SHADER_COMPUTE) {
-               unsigned *props = sel->info.properties;
                unsigned wave_size = 64;
                unsigned max_vgprs = 256;
                unsigned max_sgprs = sscreen->b.chip_class >= VI ? 800 : 512;
                unsigned max_sgprs_per_wave = 128;
-               unsigned min_waves_per_cu =
-                       DIV_ROUND_UP(props[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH] *
-                                    props[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT] *
-                                    props[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH],
-                                    wave_size);
+               unsigned max_block_threads = si_get_max_workgroup_size(shader);
+               unsigned min_waves_per_cu = DIV_ROUND_UP(max_block_threads, wave_size);
                unsigned min_waves_per_simd = DIV_ROUND_UP(min_waves_per_cu, 4);
 
                max_vgprs = max_vgprs / min_waves_per_simd;
@@ -6724,20 +7638,7 @@ int si_compile_tgsi_shader(struct si_screen *sscreen,
                        shader->info.num_input_vgprs += 1;
        }
 
-       if (ctx.type == PIPE_SHADER_GEOMETRY) {
-               shader->gs_copy_shader = CALLOC_STRUCT(si_shader);
-               shader->gs_copy_shader->selector = shader->selector;
-               ctx.shader = shader->gs_copy_shader;
-               if ((r = si_generate_gs_copy_shader(sscreen, &ctx,
-                                                   shader, debug))) {
-                       free(shader->gs_copy_shader);
-                       shader->gs_copy_shader = NULL;
-                       goto out;
-               }
-       }
-
-out:
-       return r;
+       return 0;
 }
 
 /**
@@ -6745,22 +7646,25 @@ out:
  *
  * \param sscreen      screen
  * \param list         list of shader parts of the same category
+ * \param type         shader type
  * \param key          shader part key
+ * \param prolog       whether the part being requested is a prolog
  * \param tm           LLVM target machine
  * \param debug                debug callback
- * \param compile      the callback responsible for compilation
+ * \param build                the callback responsible for building the main function
  * \return             non-NULL on success
  */
 static struct si_shader_part *
 si_get_shader_part(struct si_screen *sscreen,
                   struct si_shader_part **list,
+                  enum pipe_shader_type type,
+                  bool prolog,
                   union si_shader_part_key *key,
                   LLVMTargetMachineRef tm,
                   struct pipe_debug_callback *debug,
-                  bool (*compile)(struct si_screen *,
-                                  LLVMTargetMachineRef,
-                                  struct pipe_debug_callback *,
-                                  struct si_shader_part *))
+                  void (*build)(struct si_shader_context *,
+                                union si_shader_part_key *),
+                  const char *name)
 {
        struct si_shader_part *result;
 
@@ -6777,24 +7681,62 @@ si_get_shader_part(struct si_screen *sscreen,
        /* Compile a new one. */
        result = CALLOC_STRUCT(si_shader_part);
        result->key = *key;
-       if (!compile(sscreen, tm, debug, result)) {
+
+       struct si_shader shader = {};
+       struct si_shader_context ctx;
+       struct gallivm_state *gallivm = &ctx.gallivm;
+
+       si_init_shader_ctx(&ctx, sscreen, &shader, tm);
+       ctx.type = type;
+
+       switch (type) {
+       case PIPE_SHADER_VERTEX:
+               break;
+       case PIPE_SHADER_TESS_CTRL:
+               assert(!prolog);
+               shader.key.part.tcs.epilog = key->tcs_epilog.states;
+               break;
+       case PIPE_SHADER_GEOMETRY:
+               assert(prolog);
+               break;
+       case PIPE_SHADER_FRAGMENT:
+               if (prolog)
+                       shader.key.part.ps.prolog = key->ps_prolog.states;
+               else
+                       shader.key.part.ps.epilog = key->ps_epilog.states;
+               break;
+       default:
+               unreachable("bad shader part");
+       }
+
+       build(&ctx, key);
+
+       /* Compile. */
+       si_llvm_finalize_module(&ctx,
+               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT));
+
+       if (si_compile_llvm(sscreen, &result->binary, &result->config, tm,
+                           gallivm->module, debug, ctx.type, name)) {
                FREE(result);
-               pipe_mutex_unlock(sscreen->shader_parts_mutex);
-               return NULL;
+               result = NULL;
+               goto out;
        }
 
        result->next = *list;
        *list = result;
+
+out:
+       si_llvm_dispose(&ctx);
        pipe_mutex_unlock(sscreen->shader_parts_mutex);
        return result;
 }
 
 /**
- * Create a vertex shader prolog.
+ * Build the vertex shader prolog function.
  *
  * The inputs are the same as VS (a lot of SGPRs and 4 VGPR system values).
  * All inputs are returned unmodified. The vertex load indices are
- * stored after them, which will used by the API VS for fetching inputs.
+ * stored after them, which will be used by the API VS for fetching inputs.
  *
  * For example, the expected outputs for instance_divisors[] = {0, 1, 2} are:
  *   input_v0,
@@ -6805,24 +7747,16 @@ si_get_shader_part(struct si_screen *sscreen,
  *   (InstanceID + StartInstance),
  *   (InstanceID / 2 + StartInstance)
  */
-static bool si_compile_vs_prolog(struct si_screen *sscreen,
-                                LLVMTargetMachineRef tm,
-                                struct pipe_debug_callback *debug,
-                                struct si_shader_part *out)
+static void si_build_vs_prolog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key)
 {
-       union si_shader_part_key *key = &out->key;
-       struct si_shader shader = {};
-       struct si_shader_context ctx;
-       struct gallivm_state *gallivm = &ctx.radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMTypeRef *params, *returns;
        LLVMValueRef ret, func;
        int last_sgpr, num_params, num_returns, i;
-       bool status = true;
 
-       si_init_shader_ctx(&ctx, sscreen, &shader, tm);
-       ctx.type = PIPE_SHADER_VERTEX;
-       ctx.param_vertex_id = key->vs_prolog.num_input_sgprs;
-       ctx.param_instance_id = key->vs_prolog.num_input_sgprs + 3;
+       ctx->param_vertex_id = key->vs_prolog.num_input_sgprs;
+       ctx->param_instance_id = key->vs_prolog.num_input_sgprs + 3;
 
        /* 4 preloaded VGPRs + vertex load indices as prolog outputs */
        params = alloca((key->vs_prolog.num_input_sgprs + 4) *
@@ -6836,37 +7770,37 @@ static bool si_compile_vs_prolog(struct si_screen *sscreen,
        /* Declare input and output SGPRs. */
        num_params = 0;
        for (i = 0; i < key->vs_prolog.num_input_sgprs; i++) {
-               params[num_params++] = ctx.i32;
-               returns[num_returns++] = ctx.i32;
+               params[num_params++] = ctx->i32;
+               returns[num_returns++] = ctx->i32;
        }
        last_sgpr = num_params - 1;
 
        /* 4 preloaded VGPRs (outputs must be floats) */
        for (i = 0; i < 4; i++) {
-               params[num_params++] = ctx.i32;
-               returns[num_returns++] = ctx.f32;
+               params[num_params++] = ctx->i32;
+               returns[num_returns++] = ctx->f32;
        }
 
        /* Vertex load indices. */
        for (i = 0; i <= key->vs_prolog.last_input; i++)
-               returns[num_returns++] = ctx.f32;
+               returns[num_returns++] = ctx->f32;
 
        /* Create the function. */
-       si_create_function(&ctx, returns, num_returns, params,
+       si_create_function(ctx, "vs_prolog", returns, num_returns, params,
                           num_params, last_sgpr);
-       func = ctx.radeon_bld.main_fn;
+       func = ctx->main_fn;
 
        /* Copy inputs to outputs. This should be no-op, as the registers match,
         * but it will prevent the compiler from overwriting them unintentionally.
         */
-       ret = ctx.return_value;
+       ret = ctx->return_value;
        for (i = 0; i < key->vs_prolog.num_input_sgprs; i++) {
                LLVMValueRef p = LLVMGetParam(func, i);
                ret = LLVMBuildInsertValue(gallivm->builder, ret, p, i, "");
        }
        for (i = num_params - 4; i < num_params; i++) {
                LLVMValueRef p = LLVMGetParam(func, i);
-               p = LLVMBuildBitCast(gallivm->builder, p, ctx.f32, "");
+               p = LLVMBuildBitCast(gallivm->builder, p, ctx->f32, "");
                ret = LLVMBuildInsertValue(gallivm->builder, ret, p, i, "");
        }
 
@@ -6877,38 +7811,26 @@ static bool si_compile_vs_prolog(struct si_screen *sscreen,
 
                if (divisor) {
                        /* InstanceID / Divisor + StartInstance */
-                       index = get_instance_index_for_fetch(&ctx.radeon_bld,
+                       index = get_instance_index_for_fetch(ctx,
                                                             SI_SGPR_START_INSTANCE,
                                                             divisor);
                } else {
                        /* VertexID + BaseVertex */
                        index = LLVMBuildAdd(gallivm->builder,
-                                            LLVMGetParam(func, ctx.param_vertex_id),
+                                            LLVMGetParam(func, ctx->param_vertex_id),
                                             LLVMGetParam(func, SI_SGPR_BASE_VERTEX), "");
                }
 
-               index = LLVMBuildBitCast(gallivm->builder, index, ctx.f32, "");
+               index = LLVMBuildBitCast(gallivm->builder, index, ctx->f32, "");
                ret = LLVMBuildInsertValue(gallivm->builder, ret, index,
                                           num_params++, "");
        }
 
-       /* Compile. */
-       si_llvm_build_ret(&ctx, ret);
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_VERTEX));
-
-       if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
-                           gallivm->module, debug, ctx.type,
-                           "Vertex Shader Prolog"))
-               status = false;
-
-       radeon_llvm_dispose(&ctx.radeon_bld);
-       return status;
+       si_llvm_build_ret(ctx, ret);
 }
 
 /**
- * Compile the vertex shader epilog. This is also used by the tessellation
+ * Build the vertex shader epilog function. This is also used by the tessellation
  * evaluation shader compiled as VS.
  *
  * The input is PrimitiveID.
@@ -6916,21 +7838,13 @@ static bool si_compile_vs_prolog(struct si_screen *sscreen,
  * If PrimitiveID is required by the pixel shader, export it.
  * Otherwise, do nothing.
  */
-static bool si_compile_vs_epilog(struct si_screen *sscreen,
-                                LLVMTargetMachineRef tm,
-                                struct pipe_debug_callback *debug,
-                                struct si_shader_part *out)
+static void si_build_vs_epilog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key)
 {
-       union si_shader_part_key *key = &out->key;
-       struct si_shader_context ctx;
-       struct gallivm_state *gallivm = &ctx.radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx.radeon_bld.soa.bld_base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        LLVMTypeRef params[5];
        int num_params, i;
-       bool status = true;
-
-       si_init_shader_ctx(&ctx, sscreen, NULL, tm);
-       ctx.type = PIPE_SHADER_VERTEX;
 
        /* Declare input VGPRs. */
        num_params = key->vs_epilog.states.export_prim_id ?
@@ -6938,10 +7852,10 @@ static bool si_compile_vs_epilog(struct si_screen *sscreen,
        assert(num_params <= ARRAY_SIZE(params));
 
        for (i = 0; i < num_params; i++)
-               params[i] = ctx.f32;
+               params[i] = ctx->f32;
 
        /* Create the function. */
-       si_create_function(&ctx, NULL, 0, params, num_params, -1);
+       si_create_function(ctx, "vs_epilog", NULL, 0, params, num_params, -1);
 
        /* Emit exports. */
        if (key->vs_epilog.states.export_prim_id) {
@@ -6955,30 +7869,18 @@ static bool si_compile_vs_epilog(struct si_screen *sscreen,
                args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_PARAM +
                                               key->vs_epilog.prim_id_param_offset);
                args[4] = uint->zero; /* COMPR flag (0 = 32-bit export) */
-               args[5] = LLVMGetParam(ctx.radeon_bld.main_fn,
+               args[5] = LLVMGetParam(ctx->main_fn,
                                       VS_EPILOG_PRIMID_LOC); /* X */
-               args[6] = uint->undef; /* Y */
-               args[7] = uint->undef; /* Z */
-               args[8] = uint->undef; /* W */
+               args[6] = base->undef; /* Y */
+               args[7] = base->undef; /* Z */
+               args[8] = base->undef; /* W */
 
                lp_build_intrinsic(base->gallivm->builder, "llvm.SI.export",
                                   LLVMVoidTypeInContext(base->gallivm->context),
                                   args, 9, 0);
        }
 
-       /* Compile. */
        LLVMBuildRetVoid(gallivm->builder);
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_VERTEX));
-
-       if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
-                           gallivm->module, debug, ctx.type,
-                           "Vertex Shader Epilog"))
-               status = false;
-
-       radeon_llvm_dispose(&ctx.radeon_bld);
-       return status;
 }
 
 /**
@@ -6992,22 +7894,13 @@ static bool si_get_vs_epilog(struct si_screen *sscreen,
 {
        union si_shader_part_key epilog_key;
 
-       memset(&epilog_key, 0, sizeof(epilog_key));
-       epilog_key.vs_epilog.states = *states;
-
-       /* Set up the PrimitiveID output. */
-       if (shader->key.vs.epilog.export_prim_id) {
-               unsigned index = shader->selector->info.num_outputs;
-               unsigned offset = shader->info.nr_param_exports++;
-
-               epilog_key.vs_epilog.prim_id_param_offset = offset;
-               assert(index < ARRAY_SIZE(shader->info.vs_output_param_offset));
-               shader->info.vs_output_param_offset[index] = offset;
-       }
+       si_get_vs_epilog_key(shader, states, &epilog_key);
 
        shader->epilog = si_get_shader_part(sscreen, &sscreen->vs_epilogs,
+                                           PIPE_SHADER_VERTEX, true,
                                            &epilog_key, tm, debug,
-                                           si_compile_vs_epilog);
+                                           si_build_vs_epilog_function,
+                                           "Vertex Shader Epilog");
        return shader->epilog != NULL;
 }
 
@@ -7021,35 +7914,28 @@ static bool si_shader_select_vs_parts(struct si_screen *sscreen,
 {
        struct tgsi_shader_info *info = &shader->selector->info;
        union si_shader_part_key prolog_key;
-       unsigned i;
 
        /* Get the prolog. */
-       memset(&prolog_key, 0, sizeof(prolog_key));
-       prolog_key.vs_prolog.states = shader->key.vs.prolog;
-       prolog_key.vs_prolog.num_input_sgprs = shader->info.num_input_sgprs;
-       prolog_key.vs_prolog.last_input = MAX2(1, info->num_inputs) - 1;
+       si_get_vs_prolog_key(shader, &prolog_key);
 
        /* The prolog is a no-op if there are no inputs. */
        if (info->num_inputs) {
                shader->prolog =
                        si_get_shader_part(sscreen, &sscreen->vs_prologs,
+                                          PIPE_SHADER_VERTEX, true,
                                           &prolog_key, tm, debug,
-                                          si_compile_vs_prolog);
+                                          si_build_vs_prolog_function,
+                                          "Vertex Shader Prolog");
                if (!shader->prolog)
                        return false;
        }
 
        /* Get the epilog. */
-       if (!shader->key.vs.as_es && !shader->key.vs.as_ls &&
+       if (!shader->key.as_es && !shader->key.as_ls &&
            !si_get_vs_epilog(sscreen, tm, shader, debug,
-                             &shader->key.vs.epilog))
+                             &shader->key.part.vs.epilog))
                return false;
 
-       /* Set the instanceID flag. */
-       for (i = 0; i < info->num_inputs; i++)
-               if (prolog_key.vs_prolog.states.instance_divisors[i])
-                       shader->info.uses_instanceid = true;
-
        return true;
 }
 
@@ -7061,79 +7947,57 @@ static bool si_shader_select_tes_parts(struct si_screen *sscreen,
                                       struct si_shader *shader,
                                       struct pipe_debug_callback *debug)
 {
-       if (shader->key.tes.as_es)
+       if (shader->key.as_es)
                return true;
 
        /* TES compiled as VS. */
        return si_get_vs_epilog(sscreen, tm, shader, debug,
-                               &shader->key.tes.epilog);
+                               &shader->key.part.tes.epilog);
 }
 
 /**
- * Compile the TCS epilog. This writes tesselation factors to memory based on
- * the output primitive type of the tesselator (determined by TES).
+ * Compile the TCS epilog function. This writes tesselation factors to memory
+ * based on the output primitive type of the tesselator (determined by TES).
  */
-static bool si_compile_tcs_epilog(struct si_screen *sscreen,
-                                 LLVMTargetMachineRef tm,
-                                 struct pipe_debug_callback *debug,
-                                 struct si_shader_part *out)
+static void si_build_tcs_epilog_function(struct si_shader_context *ctx,
+                                        union si_shader_part_key *key)
 {
-       union si_shader_part_key *key = &out->key;
-       struct si_shader shader = {};
-       struct si_shader_context ctx;
-       struct gallivm_state *gallivm = &ctx.radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx.radeon_bld.soa.bld_base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        LLVMTypeRef params[16];
        LLVMValueRef func;
        int last_sgpr, num_params;
-       bool status = true;
-
-       si_init_shader_ctx(&ctx, sscreen, &shader, tm);
-       ctx.type = PIPE_SHADER_TESS_CTRL;
-       shader.key.tcs.epilog = key->tcs_epilog.states;
 
        /* Declare inputs. Only RW_BUFFERS and TESS_FACTOR_OFFSET are used. */
-       params[SI_PARAM_RW_BUFFERS] = const_array(ctx.v16i8, SI_NUM_RW_BUFFERS);
-       params[SI_PARAM_CONST_BUFFERS] = ctx.i64;
-       params[SI_PARAM_SAMPLERS] = ctx.i64;
-       params[SI_PARAM_IMAGES] = ctx.i64;
-       params[SI_PARAM_SHADER_BUFFERS] = ctx.i64;
-       params[SI_PARAM_TCS_OFFCHIP_LAYOUT] = ctx.i32;
-       params[SI_PARAM_TCS_OUT_OFFSETS] = ctx.i32;
-       params[SI_PARAM_TCS_OUT_LAYOUT] = ctx.i32;
-       params[SI_PARAM_TCS_IN_LAYOUT] = ctx.i32;
-       params[ctx.param_oc_lds = SI_PARAM_TCS_OC_LDS] = ctx.i32;
-       params[SI_PARAM_TESS_FACTOR_OFFSET] = ctx.i32;
+       params[SI_PARAM_RW_BUFFERS] = const_array(ctx->v16i8, SI_NUM_RW_BUFFERS);
+       params[SI_PARAM_CONST_BUFFERS] = ctx->i64;
+       params[SI_PARAM_SAMPLERS] = ctx->i64;
+       params[SI_PARAM_IMAGES] = ctx->i64;
+       params[SI_PARAM_SHADER_BUFFERS] = ctx->i64;
+       params[SI_PARAM_TCS_OFFCHIP_LAYOUT] = ctx->i32;
+       params[SI_PARAM_TCS_OUT_OFFSETS] = ctx->i32;
+       params[SI_PARAM_TCS_OUT_LAYOUT] = ctx->i32;
+       params[SI_PARAM_TCS_IN_LAYOUT] = ctx->i32;
+       params[ctx->param_oc_lds = SI_PARAM_TCS_OC_LDS] = ctx->i32;
+       params[SI_PARAM_TESS_FACTOR_OFFSET] = ctx->i32;
        last_sgpr = SI_PARAM_TESS_FACTOR_OFFSET;
        num_params = last_sgpr + 1;
 
-       params[num_params++] = ctx.i32; /* patch index within the wave (REL_PATCH_ID) */
-       params[num_params++] = ctx.i32; /* invocation ID within the patch */
-       params[num_params++] = ctx.i32; /* LDS offset where tess factors should be loaded from */
+       params[num_params++] = ctx->i32; /* patch index within the wave (REL_PATCH_ID) */
+       params[num_params++] = ctx->i32; /* invocation ID within the patch */
+       params[num_params++] = ctx->i32; /* LDS offset where tess factors should be loaded from */
 
        /* Create the function. */
-       si_create_function(&ctx, NULL, 0, params, num_params, last_sgpr);
-       declare_tess_lds(&ctx);
-       func = ctx.radeon_bld.main_fn;
+       si_create_function(ctx, "tcs_epilog", NULL, 0, params, num_params, last_sgpr);
+       declare_tess_lds(ctx);
+       func = ctx->main_fn;
 
        si_write_tess_factors(bld_base,
                              LLVMGetParam(func, last_sgpr + 1),
                              LLVMGetParam(func, last_sgpr + 2),
                              LLVMGetParam(func, last_sgpr + 3));
 
-       /* Compile. */
        LLVMBuildRetVoid(gallivm->builder);
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_TESS_CTRL));
-
-       if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
-                           gallivm->module, debug, ctx.type,
-                           "Tessellation Control Shader Epilog"))
-               status = false;
-
-       radeon_llvm_dispose(&ctx.radeon_bld);
-       return status;
 }
 
 /**
@@ -7148,16 +8012,42 @@ static bool si_shader_select_tcs_parts(struct si_screen *sscreen,
 
        /* Get the epilog. */
        memset(&epilog_key, 0, sizeof(epilog_key));
-       epilog_key.tcs_epilog.states = shader->key.tcs.epilog;
+       epilog_key.tcs_epilog.states = shader->key.part.tcs.epilog;
 
        shader->epilog = si_get_shader_part(sscreen, &sscreen->tcs_epilogs,
+                                           PIPE_SHADER_TESS_CTRL, false,
                                            &epilog_key, tm, debug,
-                                           si_compile_tcs_epilog);
+                                           si_build_tcs_epilog_function,
+                                           "Tessellation Control Shader Epilog");
        return shader->epilog != NULL;
 }
 
 /**
- * Compile the pixel shader prolog. This handles:
+ * Select and compile (or reuse) GS parts (prolog).
+ */
+static bool si_shader_select_gs_parts(struct si_screen *sscreen,
+                                     LLVMTargetMachineRef tm,
+                                     struct si_shader *shader,
+                                     struct pipe_debug_callback *debug)
+{
+       union si_shader_part_key prolog_key;
+
+       if (!shader->key.part.gs.prolog.tri_strip_adj_fix)
+               return true;
+
+       memset(&prolog_key, 0, sizeof(prolog_key));
+       prolog_key.gs_prolog.states = shader->key.part.gs.prolog;
+
+       shader->prolog = si_get_shader_part(sscreen, &sscreen->gs_prologs,
+                                           PIPE_SHADER_GEOMETRY, true,
+                                           &prolog_key, tm, debug,
+                                           si_build_gs_prolog_function,
+                                           "Geometry Shader Prolog");
+       return shader->prolog != NULL;
+}
+
+/**
+ * Build the pixel shader prolog function. This handles:
  * - two-side color selection and interpolation
  * - overriding interpolation parameters for the API PS
  * - polygon stippling
@@ -7166,23 +8056,15 @@ static bool si_shader_select_tcs_parts(struct si_screen *sscreen,
  * overriden by other states. (e.g. per-sample interpolation)
  * Interpolated colors are stored after the preloaded VGPRs.
  */
-static bool si_compile_ps_prolog(struct si_screen *sscreen,
-                                LLVMTargetMachineRef tm,
-                                struct pipe_debug_callback *debug,
-                                struct si_shader_part *out)
+static void si_build_ps_prolog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key)
 {
-       union si_shader_part_key *key = &out->key;
-       struct si_shader shader = {};
-       struct si_shader_context ctx;
-       struct gallivm_state *gallivm = &ctx.radeon_bld.gallivm;
+       struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMTypeRef *params;
        LLVMValueRef ret, func;
        int last_sgpr, num_params, num_returns, i, num_color_channels;
-       bool status = true;
 
-       si_init_shader_ctx(&ctx, sscreen, &shader, tm);
-       ctx.type = PIPE_SHADER_FRAGMENT;
-       shader.key.ps.prolog = key->ps_prolog.states;
+       assert(si_need_ps_prolog(key));
 
        /* Number of inputs + 8 color elements. */
        params = alloca((key->ps_prolog.num_input_sgprs +
@@ -7192,27 +8074,27 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
        /* Declare inputs. */
        num_params = 0;
        for (i = 0; i < key->ps_prolog.num_input_sgprs; i++)
-               params[num_params++] = ctx.i32;
+               params[num_params++] = ctx->i32;
        last_sgpr = num_params - 1;
 
        for (i = 0; i < key->ps_prolog.num_input_vgprs; i++)
-               params[num_params++] = ctx.f32;
+               params[num_params++] = ctx->f32;
 
        /* Declare outputs (same as inputs + add colors if needed) */
        num_returns = num_params;
        num_color_channels = util_bitcount(key->ps_prolog.colors_read);
        for (i = 0; i < num_color_channels; i++)
-               params[num_returns++] = ctx.f32;
+               params[num_returns++] = ctx->f32;
 
        /* Create the function. */
-       si_create_function(&ctx, params, num_returns, params,
+       si_create_function(ctx, "ps_prolog", params, num_returns, params,
                           num_params, last_sgpr);
-       func = ctx.radeon_bld.main_fn;
+       func = ctx->main_fn;
 
        /* Copy inputs to outputs. This should be no-op, as the registers match,
         * but it will prevent the compiler from overwriting them unintentionally.
         */
-       ret = ctx.return_value;
+       ret = ctx->return_value;
        for (i = 0; i < num_params; i++) {
                LLVMValueRef p = LLVMGetParam(func, i);
                ret = LLVMBuildInsertValue(gallivm->builder, ret, p, i, "");
@@ -7229,11 +8111,11 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
                ptr[0] = LLVMGetParam(func, SI_SGPR_RW_BUFFERS);
                ptr[1] = LLVMGetParam(func, SI_SGPR_RW_BUFFERS_HI);
                list = lp_build_gather_values(gallivm, ptr, 2);
-               list = LLVMBuildBitCast(gallivm->builder, list, ctx.i64, "");
+               list = LLVMBuildBitCast(gallivm->builder, list, ctx->i64, "");
                list = LLVMBuildIntToPtr(gallivm->builder, list,
-                                         const_array(ctx.v16i8, SI_NUM_RW_BUFFERS), "");
+                                         const_array(ctx->v16i8, SI_NUM_RW_BUFFERS), "");
 
-               si_llvm_emit_polygon_stipple(&ctx, list, pos);
+               si_llvm_emit_polygon_stipple(ctx, list, pos);
        }
 
        if (key->ps_prolog.states.bc_optimize_for_persp ||
@@ -7249,9 +8131,9 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
                 */
                bc_optimize = LLVMGetParam(func, SI_PS_NUM_USER_SGPR);
                bc_optimize = LLVMBuildLShr(gallivm->builder, bc_optimize,
-                                           LLVMConstInt(ctx.i32, 31, 0), "");
+                                           LLVMConstInt(ctx->i32, 31, 0), "");
                bc_optimize = LLVMBuildTrunc(gallivm->builder, bc_optimize,
-                                            ctx.i1, "");
+                                            ctx->i1, "");
 
                if (key->ps_prolog.states.bc_optimize_for_persp) {
                        /* Read PERSP_CENTER. */
@@ -7375,8 +8257,6 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
                        interp[1] = LLVMBuildExtractValue(gallivm->builder, ret,
                                                          interp_vgpr + 1, "");
                        interp_ij = lp_build_gather_values(gallivm, interp, 2);
-                       interp_ij = LLVMBuildBitCast(gallivm->builder, interp_ij,
-                                                    ctx.v2i32, "");
                }
 
                /* Use the absolute location of the input. */
@@ -7384,10 +8264,10 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
 
                if (key->ps_prolog.states.color_two_side) {
                        face = LLVMGetParam(func, face_vgpr);
-                       face = LLVMBuildBitCast(gallivm->builder, face, ctx.i32, "");
+                       face = LLVMBuildBitCast(gallivm->builder, face, ctx->i32, "");
                }
 
-               interp_fs_input(&ctx,
+               interp_fs_input(ctx,
                                key->ps_prolog.color_attr_index[i],
                                TGSI_SEMANTIC_COLOR, i,
                                key->ps_prolog.num_interp_inputs,
@@ -7407,52 +8287,30 @@ static bool si_compile_ps_prolog(struct si_screen *sscreen,
                                                   "amdgpu-ps-wqm-outputs", "");
        }
 
-       /* Compile. */
-       si_llvm_build_ret(&ctx, ret);
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT));
-
-       if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
-                           gallivm->module, debug, ctx.type,
-                           "Fragment Shader Prolog"))
-               status = false;
-
-       radeon_llvm_dispose(&ctx.radeon_bld);
-       return status;
+       si_llvm_build_ret(ctx, ret);
 }
 
 /**
- * Compile the pixel shader epilog. This handles everything that must be
+ * Build the pixel shader epilog function. This handles everything that must be
  * emulated for pixel shader exports. (alpha-test, format conversions, etc)
  */
-static bool si_compile_ps_epilog(struct si_screen *sscreen,
-                                LLVMTargetMachineRef tm,
-                                struct pipe_debug_callback *debug,
-                                struct si_shader_part *out)
+static void si_build_ps_epilog_function(struct si_shader_context *ctx,
+                                       union si_shader_part_key *key)
 {
-       union si_shader_part_key *key = &out->key;
-       struct si_shader shader = {};
-       struct si_shader_context ctx;
-       struct gallivm_state *gallivm = &ctx.radeon_bld.gallivm;
-       struct lp_build_tgsi_context *bld_base = &ctx.radeon_bld.soa.bld_base;
+       struct gallivm_state *gallivm = &ctx->gallivm;
+       struct lp_build_tgsi_context *bld_base = &ctx->bld_base;
        LLVMTypeRef params[16+8*4+3];
        LLVMValueRef depth = NULL, stencil = NULL, samplemask = NULL;
        int last_sgpr, num_params, i;
-       bool status = true;
        struct si_ps_exports exp = {};
 
-       si_init_shader_ctx(&ctx, sscreen, &shader, tm);
-       ctx.type = PIPE_SHADER_FRAGMENT;
-       shader.key.ps.epilog = key->ps_epilog.states;
-
        /* Declare input SGPRs. */
-       params[SI_PARAM_RW_BUFFERS] = ctx.i64;
-       params[SI_PARAM_CONST_BUFFERS] = ctx.i64;
-       params[SI_PARAM_SAMPLERS] = ctx.i64;
-       params[SI_PARAM_IMAGES] = ctx.i64;
-       params[SI_PARAM_SHADER_BUFFERS] = ctx.i64;
-       params[SI_PARAM_ALPHA_REF] = ctx.f32;
+       params[SI_PARAM_RW_BUFFERS] = ctx->i64;
+       params[SI_PARAM_CONST_BUFFERS] = ctx->i64;
+       params[SI_PARAM_SAMPLERS] = ctx->i64;
+       params[SI_PARAM_IMAGES] = ctx->i64;
+       params[SI_PARAM_SHADER_BUFFERS] = ctx->i64;
+       params[SI_PARAM_ALPHA_REF] = ctx->f32;
        last_sgpr = SI_PARAM_ALPHA_REF;
 
        /* Declare input VGPRs. */
@@ -7468,12 +8326,12 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen,
        assert(num_params <= ARRAY_SIZE(params));
 
        for (i = last_sgpr + 1; i < num_params; i++)
-               params[i] = ctx.f32;
+               params[i] = ctx->f32;
 
        /* Create the function. */
-       si_create_function(&ctx, NULL, 0, params, num_params, last_sgpr);
+       si_create_function(ctx, "ps_epilog", NULL, 0, params, num_params, last_sgpr);
        /* Disable elimination of unused inputs. */
-       radeon_llvm_add_attribute(ctx.radeon_bld.main_fn,
+       si_llvm_add_attribute(ctx->main_fn,
                                  "InitialPSInputAddr", 0xffffff);
 
        /* Process colors. */
@@ -7506,7 +8364,7 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen,
                int mrt = u_bit_scan(&colors_written);
 
                for (i = 0; i < 4; i++)
-                       color[i] = LLVMGetParam(ctx.radeon_bld.main_fn, vgpr++);
+                       color[i] = LLVMGetParam(ctx->main_fn, vgpr++);
 
                si_export_mrt_color(bld_base, color, mrt,
                                    num_params - 1,
@@ -7515,11 +8373,11 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen,
 
        /* Process depth, stencil, samplemask. */
        if (key->ps_epilog.writes_z)
-               depth = LLVMGetParam(ctx.radeon_bld.main_fn, vgpr++);
+               depth = LLVMGetParam(ctx->main_fn, vgpr++);
        if (key->ps_epilog.writes_stencil)
-               stencil = LLVMGetParam(ctx.radeon_bld.main_fn, vgpr++);
+               stencil = LLVMGetParam(ctx->main_fn, vgpr++);
        if (key->ps_epilog.writes_samplemask)
-               samplemask = LLVMGetParam(ctx.radeon_bld.main_fn, vgpr++);
+               samplemask = LLVMGetParam(ctx->main_fn, vgpr++);
 
        if (depth || stencil || samplemask)
                si_export_mrt_z(bld_base, depth, stencil, samplemask, &exp);
@@ -7527,21 +8385,10 @@ static bool si_compile_ps_epilog(struct si_screen *sscreen,
                si_export_null(bld_base);
 
        if (exp.num)
-               si_emit_ps_exports(&ctx, &exp);
+               si_emit_ps_exports(ctx, &exp);
 
        /* Compile. */
        LLVMBuildRetVoid(gallivm->builder);
-       radeon_llvm_finalize_module(
-               &ctx.radeon_bld,
-               r600_extra_shader_checks(&sscreen->b, PIPE_SHADER_FRAGMENT));
-
-       if (si_compile_llvm(sscreen, &out->binary, &out->config, tm,
-                           gallivm->module, debug, ctx.type,
-                           "Fragment Shader Epilog"))
-               status = false;
-
-       radeon_llvm_dispose(&ctx.radeon_bld);
-       return status;
 }
 
 /**
@@ -7552,175 +8399,65 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen,
                                      struct si_shader *shader,
                                      struct pipe_debug_callback *debug)
 {
-       struct tgsi_shader_info *info = &shader->selector->info;
        union si_shader_part_key prolog_key;
        union si_shader_part_key epilog_key;
-       unsigned i;
 
        /* Get the prolog. */
-       memset(&prolog_key, 0, sizeof(prolog_key));
-       prolog_key.ps_prolog.states = shader->key.ps.prolog;
-       prolog_key.ps_prolog.colors_read = info->colors_read;
-       prolog_key.ps_prolog.num_input_sgprs = shader->info.num_input_sgprs;
-       prolog_key.ps_prolog.num_input_vgprs = shader->info.num_input_vgprs;
-       prolog_key.ps_prolog.wqm = info->uses_derivatives &&
-               (prolog_key.ps_prolog.colors_read ||
-                prolog_key.ps_prolog.states.force_persp_sample_interp ||
-                prolog_key.ps_prolog.states.force_linear_sample_interp ||
-                prolog_key.ps_prolog.states.force_persp_center_interp ||
-                prolog_key.ps_prolog.states.force_linear_center_interp ||
-                prolog_key.ps_prolog.states.bc_optimize_for_persp ||
-                prolog_key.ps_prolog.states.bc_optimize_for_linear);
-
-       if (info->colors_read) {
-               unsigned *color = shader->selector->color_attr_index;
-
-               if (shader->key.ps.prolog.color_two_side) {
-                       /* BCOLORs are stored after the last input. */
-                       prolog_key.ps_prolog.num_interp_inputs = info->num_inputs;
-                       prolog_key.ps_prolog.face_vgpr_index = shader->info.face_vgpr_index;
-                       shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1);
-               }
-
-               for (i = 0; i < 2; i++) {
-                       unsigned interp = info->input_interpolate[color[i]];
-                       unsigned location = info->input_interpolate_loc[color[i]];
-
-                       if (!(info->colors_read & (0xf << i*4)))
-                               continue;
-
-                       prolog_key.ps_prolog.color_attr_index[i] = color[i];
-
-                       if (shader->key.ps.prolog.flatshade_colors &&
-                           interp == TGSI_INTERPOLATE_COLOR)
-                               interp = TGSI_INTERPOLATE_CONSTANT;
-
-                       switch (interp) {
-                       case TGSI_INTERPOLATE_CONSTANT:
-                               prolog_key.ps_prolog.color_interp_vgpr_index[i] = -1;
-                               break;
-                       case TGSI_INTERPOLATE_PERSPECTIVE:
-                       case TGSI_INTERPOLATE_COLOR:
-                               /* Force the interpolation location for colors here. */
-                               if (shader->key.ps.prolog.force_persp_sample_interp)
-                                       location = TGSI_INTERPOLATE_LOC_SAMPLE;
-                               if (shader->key.ps.prolog.force_persp_center_interp)
-                                       location = TGSI_INTERPOLATE_LOC_CENTER;
-
-                               switch (location) {
-                               case TGSI_INTERPOLATE_LOC_SAMPLE:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 0;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_SAMPLE_ENA(1);
-                                       break;
-                               case TGSI_INTERPOLATE_LOC_CENTER:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 2;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_CENTER_ENA(1);
-                                       break;
-                               case TGSI_INTERPOLATE_LOC_CENTROID:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 4;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_PERSP_CENTROID_ENA(1);
-                                       break;
-                               default:
-                                       assert(0);
-                               }
-                               break;
-                       case TGSI_INTERPOLATE_LINEAR:
-                               /* Force the interpolation location for colors here. */
-                               if (shader->key.ps.prolog.force_linear_sample_interp)
-                                       location = TGSI_INTERPOLATE_LOC_SAMPLE;
-                               if (shader->key.ps.prolog.force_linear_center_interp)
-                                       location = TGSI_INTERPOLATE_LOC_CENTER;
-
-                               switch (location) {
-                               case TGSI_INTERPOLATE_LOC_SAMPLE:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 6;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_SAMPLE_ENA(1);
-                                       break;
-                               case TGSI_INTERPOLATE_LOC_CENTER:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 8;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_CENTER_ENA(1);
-                                       break;
-                               case TGSI_INTERPOLATE_LOC_CENTROID:
-                                       prolog_key.ps_prolog.color_interp_vgpr_index[i] = 10;
-                                       shader->config.spi_ps_input_ena |=
-                                               S_0286CC_LINEAR_CENTROID_ENA(1);
-                                       break;
-                               default:
-                                       assert(0);
-                               }
-                               break;
-                       default:
-                               assert(0);
-                       }
-               }
-       }
+       si_get_ps_prolog_key(shader, &prolog_key, true);
 
        /* The prolog is a no-op if these aren't set. */
-       if (prolog_key.ps_prolog.colors_read ||
-           prolog_key.ps_prolog.states.force_persp_sample_interp ||
-           prolog_key.ps_prolog.states.force_linear_sample_interp ||
-           prolog_key.ps_prolog.states.force_persp_center_interp ||
-           prolog_key.ps_prolog.states.force_linear_center_interp ||
-           prolog_key.ps_prolog.states.bc_optimize_for_persp ||
-           prolog_key.ps_prolog.states.bc_optimize_for_linear ||
-           prolog_key.ps_prolog.states.poly_stipple) {
+       if (si_need_ps_prolog(&prolog_key)) {
                shader->prolog =
                        si_get_shader_part(sscreen, &sscreen->ps_prologs,
+                                          PIPE_SHADER_FRAGMENT, true,
                                           &prolog_key, tm, debug,
-                                          si_compile_ps_prolog);
+                                          si_build_ps_prolog_function,
+                                          "Fragment Shader Prolog");
                if (!shader->prolog)
                        return false;
        }
 
        /* Get the epilog. */
-       memset(&epilog_key, 0, sizeof(epilog_key));
-       epilog_key.ps_epilog.colors_written = info->colors_written;
-       epilog_key.ps_epilog.writes_z = info->writes_z;
-       epilog_key.ps_epilog.writes_stencil = info->writes_stencil;
-       epilog_key.ps_epilog.writes_samplemask = info->writes_samplemask;
-       epilog_key.ps_epilog.states = shader->key.ps.epilog;
+       si_get_ps_epilog_key(shader, &epilog_key);
 
        shader->epilog =
                si_get_shader_part(sscreen, &sscreen->ps_epilogs,
+                                  PIPE_SHADER_FRAGMENT, false,
                                   &epilog_key, tm, debug,
-                                  si_compile_ps_epilog);
+                                  si_build_ps_epilog_function,
+                                  "Fragment Shader Epilog");
        if (!shader->epilog)
                return false;
 
        /* Enable POS_FIXED_PT if polygon stippling is enabled. */
-       if (shader->key.ps.prolog.poly_stipple) {
+       if (shader->key.part.ps.prolog.poly_stipple) {
                shader->config.spi_ps_input_ena |= S_0286CC_POS_FIXED_PT_ENA(1);
                assert(G_0286CC_POS_FIXED_PT_ENA(shader->config.spi_ps_input_addr));
        }
 
        /* Set up the enable bits for per-sample shading if needed. */
-       if (shader->key.ps.prolog.force_persp_sample_interp &&
+       if (shader->key.part.ps.prolog.force_persp_sample_interp &&
            (G_0286CC_PERSP_CENTER_ENA(shader->config.spi_ps_input_ena) ||
             G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_ena))) {
                shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTER_ENA;
                shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTROID_ENA;
                shader->config.spi_ps_input_ena |= S_0286CC_PERSP_SAMPLE_ENA(1);
        }
-       if (shader->key.ps.prolog.force_linear_sample_interp &&
+       if (shader->key.part.ps.prolog.force_linear_sample_interp &&
            (G_0286CC_LINEAR_CENTER_ENA(shader->config.spi_ps_input_ena) ||
             G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_ena))) {
                shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_CENTER_ENA;
                shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_CENTROID_ENA;
                shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_SAMPLE_ENA(1);
        }
-       if (shader->key.ps.prolog.force_persp_center_interp &&
+       if (shader->key.part.ps.prolog.force_persp_center_interp &&
            (G_0286CC_PERSP_SAMPLE_ENA(shader->config.spi_ps_input_ena) ||
             G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_ena))) {
                shader->config.spi_ps_input_ena &= C_0286CC_PERSP_SAMPLE_ENA;
                shader->config.spi_ps_input_ena &= C_0286CC_PERSP_CENTROID_ENA;
                shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTER_ENA(1);
        }
-       if (shader->key.ps.prolog.force_linear_center_interp &&
+       if (shader->key.part.ps.prolog.force_linear_center_interp &&
            (G_0286CC_LINEAR_SAMPLE_ENA(shader->config.spi_ps_input_ena) ||
             G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_ena))) {
                shader->config.spi_ps_input_ena &= C_0286CC_LINEAR_SAMPLE_ENA;
@@ -7744,39 +8481,55 @@ static bool si_shader_select_ps_parts(struct si_screen *sscreen,
        /* The sample mask input is always enabled, because the API shader always
         * passes it through to the epilog. Disable it here if it's unused.
         */
-       if (!shader->key.ps.epilog.poly_line_smoothing &&
+       if (!shader->key.part.ps.epilog.poly_line_smoothing &&
            !shader->selector->info.reads_samplemask)
                shader->config.spi_ps_input_ena &= C_0286CC_SAMPLE_COVERAGE_ENA;
 
        return true;
 }
 
-static void si_fix_num_sgprs(struct si_shader *shader)
+void si_multiwave_lds_size_workaround(struct si_screen *sscreen,
+                                     unsigned *lds_size)
+{
+       /* SPI barrier management bug:
+        *   Make sure we have at least 4k of LDS in use to avoid the bug.
+        *   It applies to workgroup sizes of more than one wavefront.
+        */
+       if (sscreen->b.family == CHIP_BONAIRE ||
+           sscreen->b.family == CHIP_KABINI ||
+           sscreen->b.family == CHIP_MULLINS)
+               *lds_size = MAX2(*lds_size, 8);
+}
+
+static void si_fix_resource_usage(struct si_screen *sscreen,
+                                 struct si_shader *shader)
 {
        unsigned min_sgprs = shader->info.num_input_sgprs + 2; /* VCC */
 
        shader->config.num_sgprs = MAX2(shader->config.num_sgprs, min_sgprs);
+
+       if (shader->selector->type == PIPE_SHADER_COMPUTE &&
+           si_get_max_workgroup_size(shader) > 64) {
+               si_multiwave_lds_size_workaround(sscreen,
+                                                &shader->config.lds_size);
+       }
 }
 
 int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                     struct si_shader *shader,
                     struct pipe_debug_callback *debug)
 {
-       struct si_shader *mainp = shader->selector->main_shader_part;
+       struct si_shader_selector *sel = shader->selector;
+       struct si_shader *mainp = sel->main_shader_part;
        int r;
 
        /* LS, ES, VS are compiled on demand if the main part hasn't been
         * compiled for that stage.
+        *
+        * Vertex shaders are compiled on demand when a vertex fetch
+        * workaround must be applied.
         */
-       if (!mainp ||
-           (shader->selector->type == PIPE_SHADER_VERTEX &&
-            (shader->key.vs.as_es != mainp->key.vs.as_es ||
-             shader->key.vs.as_ls != mainp->key.vs.as_ls)) ||
-           (shader->selector->type == PIPE_SHADER_TESS_EVAL &&
-            shader->key.tes.as_es != mainp->key.tes.as_es) ||
-           (shader->selector->type == PIPE_SHADER_TESS_CTRL &&
-            shader->key.tcs.epilog.inputs_to_copy) ||
-           shader->selector->type == PIPE_SHADER_COMPUTE) {
+       if (shader->is_monolithic) {
                /* Monolithic shader (compiled as a whole, has many variants,
                 * may take a long time to compile).
                 */
@@ -7810,7 +8563,7 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                shader->info.nr_param_exports = mainp->info.nr_param_exports;
 
                /* Select prologs and/or epilogs. */
-               switch (shader->selector->type) {
+               switch (sel->type) {
                case PIPE_SHADER_VERTEX:
                        if (!si_shader_select_vs_parts(sscreen, tm, shader, debug))
                                return -1;
@@ -7823,6 +8576,10 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                        if (!si_shader_select_tes_parts(sscreen, tm, shader, debug))
                                return -1;
                        break;
+               case PIPE_SHADER_GEOMETRY:
+                       if (!si_shader_select_gs_parts(sscreen, tm, shader, debug))
+                               return -1;
+                       break;
                case PIPE_SHADER_FRAGMENT:
                        if (!si_shader_select_ps_parts(sscreen, tm, shader, debug))
                                return -1;
@@ -7850,9 +8607,9 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
                }
        }
 
-       si_fix_num_sgprs(shader);
-       si_shader_dump(sscreen, shader, debug, shader->selector->info.processor,
-                      stderr);
+       si_fix_resource_usage(sscreen, shader);
+       si_shader_dump(sscreen, shader, debug, sel->info.processor,
+                      stderr, true);
 
        /* Upload. */
        r = si_shader_binary_upload(sscreen, shader);
@@ -7866,11 +8623,6 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
 
 void si_shader_destroy(struct si_shader *shader)
 {
-       if (shader->gs_copy_shader) {
-               si_shader_destroy(shader->gs_copy_shader);
-               FREE(shader->gs_copy_shader);
-       }
-
        if (shader->scratch_bo)
                r600_resource_reference(&shader->scratch_bo, NULL);