nir: add nir_var_shader_storage
[mesa.git] / src / glsl / nir / nir.h
index 923b53366f2cb1a6db8c3e2372ff362849d9abdc..e9a506c59712b370a57304070516d0d8cf45e555 100644 (file)
 #pragma once
 
 #include "util/hash_table.h"
-#include "main/set.h"
 #include "../list.h"
 #include "GL/gl.h" /* GLenum */
+#include "util/list.h"
 #include "util/ralloc.h"
-#include "main/mtypes.h"
-#include "main/bitset.h"
+#include "util/set.h"
+#include "util/bitset.h"
 #include "nir_types.h"
+#include "glsl/shader_enums.h"
 #include <stdio.h>
 
+#include "nir_opcodes.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct gl_program;
+struct gl_shader_program;
+
 #define NIR_FALSE 0u
 #define NIR_TRUE (~0u)
 
@@ -62,6 +68,7 @@ name(const in_type *parent)                              \
 struct nir_function_overload;
 struct nir_function;
 struct nir_shader;
+struct nir_instr;
 
 
 /**
@@ -80,6 +87,7 @@ typedef enum {
    nir_var_global,
    nir_var_local,
    nir_var_uniform,
+   nir_var_shader_storage,
    nir_var_system_value
 } nir_variable_mode;
 
@@ -383,13 +391,13 @@ typedef struct {
    bool is_packed;
 
    /** set of nir_instr's where this register is used (read from) */
-   struct set *uses;
+   struct list_head uses;
 
    /** set of nir_instr's where this register is defined (written to) */
-   struct set *defs;
+   struct list_head defs;
 
    /** set of nir_if's where this register is used as a condition */
-   struct set *if_uses;
+   struct list_head if_uses;
 } nir_register;
 
 typedef enum {
@@ -404,20 +412,36 @@ typedef enum {
    nir_instr_type_parallel_copy,
 } nir_instr_type;
 
-typedef struct {
+typedef struct nir_instr {
    struct exec_node node;
    nir_instr_type type;
    struct nir_block *block;
 
-   /* flag for dead code elimination (see nir_opt_dce.c) */
-   bool live;
+   /* A temporary for optimization and analysis passes to use for storing
+    * flags.  For instance, DCE uses this to store the "dead/live" info.
+    */
+   uint8_t pass_flags;
 } nir_instr;
 
-#define nir_instr_next(instr) \
-   exec_node_data(nir_instr, (instr)->node.next, node)
+static inline nir_instr *
+nir_instr_next(nir_instr *instr)
+{
+   struct exec_node *next = exec_node_get_next(&instr->node);
+   if (exec_node_is_tail_sentinel(next))
+      return NULL;
+   else
+      return exec_node_data(nir_instr, next, node);
+}
 
-#define nir_instr_prev(instr) \
-   exec_node_data(nir_instr, (instr)->node.prev, node)
+static inline nir_instr *
+nir_instr_prev(nir_instr *instr)
+{
+   struct exec_node *prev = exec_node_get_prev(&instr->node);
+   if (exec_node_is_head_sentinel(prev))
+      return NULL;
+   else
+      return exec_node_data(nir_instr, prev, node);
+}
 
 typedef struct {
    /** for debugging only, can be NULL */
@@ -432,10 +456,10 @@ typedef struct {
    nir_instr *parent_instr;
 
    /** set of nir_instr's where this register is used (read from) */
-   struct set *uses;
+   struct list_head uses;
 
    /** set of nir_if's where this register is used as a condition */
-   struct set *if_uses;
+   struct list_head if_uses;
 
    uint8_t num_components;
 } nir_ssa_def;
@@ -451,6 +475,9 @@ typedef struct {
 } nir_reg_src;
 
 typedef struct {
+   nir_instr *parent_instr;
+   struct list_head def_link;
+
    nir_register *reg;
    struct nir_src *indirect; /** < NULL for no indirect offset */
    unsigned base_offset;
@@ -458,7 +485,16 @@ typedef struct {
    /* TODO def-use chain goes here */
 } nir_reg_dest;
 
+struct nir_if;
+
 typedef struct nir_src {
+   union {
+      nir_instr *parent_instr;
+      struct nir_if *parent_if;
+   };
+
+   struct list_head use_link;
+
    union {
       nir_reg_src reg;
       nir_ssa_def *ssa;
@@ -467,6 +503,20 @@ typedef struct nir_src {
    bool is_ssa;
 } nir_src;
 
+#define NIR_SRC_INIT (nir_src) { { NULL } }
+
+#define nir_foreach_use(reg_or_ssa_def, src) \
+   list_for_each_entry(nir_src, src, &(reg_or_ssa_def)->uses, use_link)
+
+#define nir_foreach_use_safe(reg_or_ssa_def, src) \
+   list_for_each_entry_safe(nir_src, src, &(reg_or_ssa_def)->uses, use_link)
+
+#define nir_foreach_if_use(reg_or_ssa_def, src) \
+   list_for_each_entry(nir_src, src, &(reg_or_ssa_def)->if_uses, use_link)
+
+#define nir_foreach_if_use_safe(reg_or_ssa_def, src) \
+   list_for_each_entry_safe(nir_src, src, &(reg_or_ssa_def)->if_uses, use_link)
+
 typedef struct {
    union {
       nir_reg_dest reg;
@@ -476,8 +526,50 @@ typedef struct {
    bool is_ssa;
 } nir_dest;
 
-nir_src nir_src_copy(nir_src src, void *mem_ctx);
-nir_dest nir_dest_copy(nir_dest dest, void *mem_ctx);
+#define NIR_DEST_INIT (nir_dest) { { { NULL } } }
+
+#define nir_foreach_def(reg, dest) \
+   list_for_each_entry(nir_dest, dest, &(reg)->defs, reg.def_link)
+
+#define nir_foreach_def_safe(reg, dest) \
+   list_for_each_entry_safe(nir_dest, dest, &(reg)->defs, reg.def_link)
+
+static inline nir_src
+nir_src_for_ssa(nir_ssa_def *def)
+{
+   nir_src src = NIR_SRC_INIT;
+
+   src.is_ssa = true;
+   src.ssa = def;
+
+   return src;
+}
+
+static inline nir_src
+nir_src_for_reg(nir_register *reg)
+{
+   nir_src src = NIR_SRC_INIT;
+
+   src.is_ssa = false;
+   src.reg.reg = reg;
+   src.reg.indirect = NULL;
+   src.reg.base_offset = 0;
+
+   return src;
+}
+
+static inline nir_dest
+nir_dest_for_reg(nir_register *reg)
+{
+   nir_dest dest = NIR_DEST_INIT;
+
+   dest.reg.reg = reg;
+
+   return dest;
+}
+
+void nir_src_copy(nir_src *dest, const nir_src *src, void *mem_ctx);
+void nir_dest_copy(nir_dest *dest, const nir_dest *src, void *mem_ctx);
 
 typedef struct {
    nir_src src;
@@ -526,21 +618,12 @@ typedef struct {
    unsigned write_mask : 4; /* ignored if dest.is_ssa is true */
 } nir_alu_dest;
 
-#define OPCODE(name, num_inputs, output_size, output_type, \
-               input_sizes, input_types, algebraic_props) \
-   nir_op_##name,
-
-#define LAST_OPCODE(name) nir_last_opcode = nir_op_##name,
-
-typedef enum {
-#include "nir_opcodes.h"
-   nir_num_opcodes = nir_last_opcode + 1
-} nir_op;
-
-#undef OPCODE
-#undef LAST_OPCODE
+void nir_alu_src_copy(nir_alu_src *dest, const nir_alu_src *src, void *mem_ctx);
+void nir_alu_dest_copy(nir_alu_dest *dest, const nir_alu_dest *src,
+                       void *mem_ctx);
 
 typedef enum {
+   nir_type_invalid = 0, /* Not a valid type */
    nir_type_float,
    nir_type_int,
    nir_type_unsigned,
@@ -617,6 +700,21 @@ nir_alu_instr_channel_used(nir_alu_instr *instr, unsigned src, unsigned channel)
    return (instr->dest.write_mask >> channel) & 1;
 }
 
+/*
+ * For instructions whose destinations are SSA, get the number of channels
+ * used for a source
+ */
+static inline unsigned
+nir_ssa_alu_instr_src_components(nir_alu_instr *instr, unsigned src)
+{
+   assert(instr->dest.dest.is_ssa);
+
+   if (nir_op_infos[instr->op].input_sizes[src] > 0)
+      return nir_op_infos[instr->op].input_sizes[src];
+
+   return instr->dest.dest.ssa.num_components;
+}
+
 typedef enum {
    nir_deref_type_var,
    nir_deref_type_array,
@@ -748,20 +846,20 @@ typedef struct {
  *
  * \sa nir_intrinsic_info::flags
  */
-/*@{*/
-/**
- * whether the intrinsic can be safely eliminated if none of its register
* outputs are being used.
- */
-#define NIR_INTRINSIC_CAN_ELIMINATE (1 << 0)
+typedef enum {
+   /**
+    * whether the intrinsic can be safely eliminated if none of its output
   * value is not being used.
   */
+   NIR_INTRINSIC_CAN_ELIMINATE = (1 << 0),
 
-/**
- * Whether the intrinsic can be reordered with respect to any other intrinsic,
* i.e. whether the only reodering dependencies of the intrinsic are due to the
* register reads/writes.
- */
-#define NIR_INTRINSIC_CAN_REORDER   (1 << 1)
-/*@}*/
+   /**
+    * Whether the intrinsic can be reordered with respect to any other
   * intrinsic, i.e. whether the only reordering dependencies of the
   * intrinsic are due to the register reads/writes.
   */
+   NIR_INTRINSIC_CAN_REORDER = (1 << 1),
+} nir_intrinsic_semantic_flag;
 
 #define NIR_INTRINSIC_MAX_INPUTS 4
 
@@ -793,7 +891,7 @@ typedef struct {
    unsigned num_indices;
 
    /** semantic flags for calls to this intrinsic */
-   unsigned flags;
+   nir_intrinsic_semantic_flag flags;
 } nir_intrinsic_info;
 
 extern const nir_intrinsic_info nir_intrinsic_infos[nir_num_intrinsics];
@@ -816,8 +914,13 @@ typedef enum {
    nir_tex_src_ddx,
    nir_tex_src_ddy,
    nir_tex_src_sampler_offset, /* < dynamically uniform indirect offset */
-   nir_num_texinput_types
-} nir_texinput_type;
+   nir_num_tex_src_types
+} nir_tex_src_type;
+
+typedef struct {
+   nir_src src;
+   nir_tex_src_type src_type;
+} nir_tex_src;
 
 typedef enum {
    nir_texop_tex,                /**< Regular texture look-up */
@@ -840,8 +943,7 @@ typedef struct {
 
    nir_texop op;
    nir_dest dest;
-   nir_src src[4];
-   nir_texinput_type src_type[4];
+   nir_tex_src *src;
    unsigned num_srcs, coord_components;
    bool is_array, is_shadow;
 
@@ -873,7 +975,8 @@ typedef struct {
 static inline unsigned
 nir_tex_instr_dest_size(nir_tex_instr *instr)
 {
-   if (instr->op == nir_texop_txs) {
+   switch (instr->op) {
+   case nir_texop_txs: {
       unsigned ret;
       switch (instr->sampler_dim) {
          case GLSL_SAMPLER_DIM_1D:
@@ -891,33 +994,37 @@ nir_tex_instr_dest_size(nir_tex_instr *instr)
             ret = 3;
             break;
          default:
-            assert(0);
-            break;
+            unreachable("not reached");
       }
       if (instr->is_array)
          ret++;
       return ret;
    }
 
-   if (instr->op == nir_texop_query_levels)
+   case nir_texop_lod:
       return 2;
 
-   if (instr->is_shadow && instr->is_new_style_shadow)
+   case nir_texop_query_levels:
       return 1;
 
-   return 4;
+   default:
+      if (instr->is_shadow && instr->is_new_style_shadow)
+         return 1;
+
+      return 4;
+   }
 }
 
 static inline unsigned
 nir_tex_instr_src_size(nir_tex_instr *instr, unsigned src)
 {
-   if (instr->src_type[src] == nir_tex_src_coord)
+   if (instr->src[src].src_type == nir_tex_src_coord)
       return instr->coord_components;
 
 
-   if (instr->src_type[src] == nir_tex_src_offset ||
-       instr->src_type[src] == nir_tex_src_ddx ||
-       instr->src_type[src] == nir_tex_src_ddy) {
+   if (instr->src[src].src_type == nir_tex_src_offset ||
+       instr->src[src].src_type == nir_tex_src_ddx ||
+       instr->src[src].src_type == nir_tex_src_ddy) {
       if (instr->is_array)
          return instr->coord_components - 1;
       else
@@ -928,10 +1035,10 @@ nir_tex_instr_src_size(nir_tex_instr *instr, unsigned src)
 }
 
 static inline int
-nir_tex_instr_src_index(nir_tex_instr *instr, nir_texinput_type type)
+nir_tex_instr_src_index(nir_tex_instr *instr, nir_tex_src_type type)
 {
    for (unsigned i = 0; i < instr->num_srcs; i++)
-      if (instr->src_type[i] == type)
+      if (instr->src[i].src_type == type)
          return (int) i;
 
    return -1;
@@ -980,6 +1087,9 @@ typedef struct {
    nir_src src;
 } nir_phi_src;
 
+#define nir_foreach_phi_src(phi, entry) \
+   foreach_list_typed(nir_phi_src, entry, node, &(phi)->srcs)
+
 typedef struct {
    nir_instr instr;
 
@@ -1078,15 +1188,32 @@ typedef struct nir_block {
    /* Set of nir_block's on the dominance frontier of this block */
    struct set *dom_frontier;
 
+   /*
+    * These two indices have the property that dom_{pre,post}_index for each
+    * child of this block in the dominance tree will always be between
+    * dom_pre_index and dom_post_index for this block, which makes testing if
+    * a given block is dominated by another block an O(1) operation.
+    */
+   unsigned dom_pre_index, dom_post_index;
+
    /* live in and out for this block; used for liveness analysis */
    BITSET_WORD *live_in;
    BITSET_WORD *live_out;
 } nir_block;
 
-#define nir_block_first_instr(block) \
-   exec_node_data(nir_instr, exec_list_get_head(&(block)->instr_list), node)
-#define nir_block_last_instr(block) \
-   exec_node_data(nir_instr, exec_list_get_tail(&(block)->instr_list), node)
+static inline nir_instr *
+nir_block_first_instr(nir_block *block)
+{
+   struct exec_node *head = exec_list_get_head(&block->instr_list);
+   return exec_node_data(nir_instr, head, node);
+}
+
+static inline nir_instr *
+nir_block_last_instr(nir_block *block)
+{
+   struct exec_node *tail = exec_list_get_tail(&block->instr_list);
+   return exec_node_data(nir_instr, tail, node);
+}
 
 #define nir_foreach_instr(block, instr) \
    foreach_list_typed(nir_instr, instr, node, &(block)->instr_list)
@@ -1095,7 +1222,7 @@ typedef struct nir_block {
 #define nir_foreach_instr_safe(block, instr) \
    foreach_list_typed_safe(nir_instr, instr, node, &(block)->instr_list)
 
-typedef struct {
+typedef struct nir_if {
    nir_cf_node cf_node;
    nir_src condition;
 
@@ -1103,14 +1230,33 @@ typedef struct {
    struct exec_list else_list; /** < list of nir_cf_node */
 } nir_if;
 
-#define nir_if_first_then_node(if) \
-   exec_node_data(nir_cf_node, exec_list_get_head(&(if)->then_list), node)
-#define nir_if_last_then_node(if) \
-   exec_node_data(nir_cf_node, exec_list_get_tail(&(if)->then_list), node)
-#define nir_if_first_else_node(if) \
-   exec_node_data(nir_cf_node, exec_list_get_head(&(if)->else_list), node)
-#define nir_if_last_else_node(if) \
-   exec_node_data(nir_cf_node, exec_list_get_tail(&(if)->else_list), node)
+static inline nir_cf_node *
+nir_if_first_then_node(nir_if *if_stmt)
+{
+   struct exec_node *head = exec_list_get_head(&if_stmt->then_list);
+   return exec_node_data(nir_cf_node, head, node);
+}
+
+static inline nir_cf_node *
+nir_if_last_then_node(nir_if *if_stmt)
+{
+   struct exec_node *tail = exec_list_get_tail(&if_stmt->then_list);
+   return exec_node_data(nir_cf_node, tail, node);
+}
+
+static inline nir_cf_node *
+nir_if_first_else_node(nir_if *if_stmt)
+{
+   struct exec_node *head = exec_list_get_head(&if_stmt->else_list);
+   return exec_node_data(nir_cf_node, head, node);
+}
+
+static inline nir_cf_node *
+nir_if_last_else_node(nir_if *if_stmt)
+{
+   struct exec_node *tail = exec_list_get_tail(&if_stmt->else_list);
+   return exec_node_data(nir_cf_node, tail, node);
+}
 
 typedef struct {
    nir_cf_node cf_node;
@@ -1118,10 +1264,17 @@ typedef struct {
    struct exec_list body; /** < list of nir_cf_node */
 } nir_loop;
 
-#define nir_loop_first_cf_node(loop) \
-   exec_node_data(nir_cf_node, exec_list_get_head(&(loop)->body), node)
-#define nir_loop_last_cf_node(loop) \
-   exec_node_data(nir_cf_node, exec_list_get_tail(&(loop)->body), node)
+static inline nir_cf_node *
+nir_loop_first_cf_node(nir_loop *loop)
+{
+   return exec_node_data(nir_cf_node, exec_list_get_head(&loop->body), node);
+}
+
+static inline nir_cf_node *
+nir_loop_last_cf_node(nir_loop *loop)
+{
+   return exec_node_data(nir_cf_node, exec_list_get_tail(&loop->body), node);
+}
 
 /**
  * Various bits of metadata that can may be created or required by
@@ -1169,17 +1322,37 @@ typedef struct {
    nir_metadata valid_metadata;
 } nir_function_impl;
 
-#define nir_cf_node_next(_node) \
-   exec_node_data(nir_cf_node, exec_node_get_next(&(_node)->node), node)
+static inline nir_cf_node *
+nir_cf_node_next(nir_cf_node *node)
+{
+   struct exec_node *next = exec_node_get_next(&node->node);
+   if (exec_node_is_tail_sentinel(next))
+      return NULL;
+   else
+      return exec_node_data(nir_cf_node, next, node);
+}
 
-#define nir_cf_node_prev(_node) \
-   exec_node_data(nir_cf_node, exec_node_get_prev(&(_node)->node), node)
+static inline nir_cf_node *
+nir_cf_node_prev(nir_cf_node *node)
+{
+   struct exec_node *prev = exec_node_get_prev(&node->node);
+   if (exec_node_is_head_sentinel(prev))
+      return NULL;
+   else
+      return exec_node_data(nir_cf_node, prev, node);
+}
 
-#define nir_cf_node_is_first(_node) \
-   exec_node_is_head_sentinel((_node)->node.prev)
+static inline bool
+nir_cf_node_is_first(const nir_cf_node *node)
+{
+   return exec_node_is_head_sentinel(node->node.prev);
+}
 
-#define nir_cf_node_is_last(_node) \
-   exec_node_is_tail_sentinel((_node)->node.next)
+static inline bool
+nir_cf_node_is_last(const nir_cf_node *node)
+{
+   return exec_node_is_tail_sentinel(node->node.next);
+}
 
 NIR_DEFINE_CAST(nir_cf_node_as_block, nir_cf_node, nir_block, cf_node)
 NIR_DEFINE_CAST(nir_cf_node_as_if, nir_cf_node, nir_if, cf_node)
@@ -1222,15 +1395,43 @@ typedef struct nir_function {
    exec_node_data(nir_function_overload, \
                   exec_list_get_head(&(func)->overload_list), node)
 
+typedef struct nir_shader_compiler_options {
+   bool lower_ffma;
+   bool lower_flrp;
+   bool lower_fpow;
+   bool lower_fsat;
+   bool lower_fsqrt;
+   /** lowers fneg and ineg to fsub and isub. */
+   bool lower_negate;
+   /** lowers fsub and isub to fadd+fneg and iadd+ineg. */
+   bool lower_sub;
+
+   /* lower {slt,sge,seq,sne} to {flt,fge,feq,fne} + b2f: */
+   bool lower_scmp;
+
+   /**
+    * Does the driver support real 32-bit integers?  (Otherwise, integers
+    * are simulated by floats.)
+    */
+   bool native_integers;
+} nir_shader_compiler_options;
+
 typedef struct nir_shader {
    /** hash table of name -> uniform nir_variable */
-   struct hash_table *uniforms;
+   struct exec_list uniforms;
 
    /** hash table of name -> input nir_variable */
-   struct hash_table *inputs;
+   struct exec_list inputs;
 
    /** hash table of name -> output nir_variable */
-   struct hash_table *outputs;
+   struct exec_list outputs;
+
+   /** Set of driver-specific options for the shader.
+    *
+    * The memory for the options is expected to be kept in a single static
+    * copy by the driver.
+    */
+   const struct nir_shader_compiler_options *options;
 
    /** list of global variables in the shader */
    struct exec_list globals;
@@ -1243,10 +1444,6 @@ typedef struct nir_shader {
    /** list of global register in the shader */
    struct exec_list registers;
 
-   /** structures used in this shader */
-   unsigned num_user_structures;
-   struct glsl_type **user_structures;
-
    /** next available global register index */
    unsigned reg_alloc;
 
@@ -1255,14 +1452,18 @@ typedef struct nir_shader {
     * access plus one
     */
    unsigned num_inputs, num_uniforms, num_outputs;
+
+   /** the number of uniforms that are only accessed directly */
+   unsigned num_direct_uniforms;
 } nir_shader;
 
-#define nir_foreach_overload(shader, overload) \
+#define nir_foreach_overload(shader, overload)                        \
    foreach_list_typed(nir_function, func, node, &(shader)->functions) \
       foreach_list_typed(nir_function_overload, overload, node, \
                          &(func)->overload_list)
 
-nir_shader *nir_shader_create(void *mem_ctx);
+nir_shader *nir_shader_create(void *mem_ctx,
+                              const nir_shader_compiler_options *options);
 
 /** creates a register, including assigning it an index and adding it to the list */
 nir_register *nir_global_reg_create(nir_shader *shader);
@@ -1306,26 +1507,26 @@ void nir_metadata_require(nir_function_impl *impl, nir_metadata required);
 void nir_metadata_preserve(nir_function_impl *impl, nir_metadata preserved);
 
 /** creates an instruction with default swizzle/writemask/etc. with NULL registers */
-nir_alu_instr *nir_alu_instr_create(void *mem_ctx, nir_op op);
+nir_alu_instr *nir_alu_instr_create(nir_shader *shader, nir_op op);
 
-nir_jump_instr *nir_jump_instr_create(void *mem_ctx, nir_jump_type type);
+nir_jump_instr *nir_jump_instr_create(nir_shader *shader, nir_jump_type type);
 
-nir_load_const_instr *nir_load_const_instr_create(void *mem_ctx,
+nir_load_const_instr *nir_load_const_instr_create(nir_shader *shader,
                                                   unsigned num_components);
 
-nir_intrinsic_instr *nir_intrinsic_instr_create(void *mem_ctx,
+nir_intrinsic_instr *nir_intrinsic_instr_create(nir_shader *shader,
                                                 nir_intrinsic_op op);
 
-nir_call_instr *nir_call_instr_create(void *mem_ctx,
+nir_call_instr *nir_call_instr_create(nir_shader *shader,
                                       nir_function_overload *callee);
 
-nir_tex_instr *nir_tex_instr_create(void *mem_ctx, unsigned num_srcs);
+nir_tex_instr *nir_tex_instr_create(nir_shader *shader, unsigned num_srcs);
 
-nir_phi_instr *nir_phi_instr_create(void *mem_ctx);
+nir_phi_instr *nir_phi_instr_create(nir_shader *shader);
 
-nir_parallel_copy_instr *nir_parallel_copy_instr_create(void *mem_ctx);
+nir_parallel_copy_instr *nir_parallel_copy_instr_create(nir_shader *shader);
 
-nir_ssa_undef_instr *nir_ssa_undef_instr_create(void *mem_ctx,
+nir_ssa_undef_instr *nir_ssa_undef_instr_create(nir_shader *shader,
                                                 unsigned num_components);
 
 nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
@@ -1334,6 +1535,9 @@ nir_deref_struct *nir_deref_struct_create(void *mem_ctx, unsigned field_index);
 
 nir_deref *nir_copy_deref(void *mem_ctx, nir_deref *deref);
 
+nir_load_const_instr *
+nir_deref_get_const_initializer_load(nir_shader *shader, nir_deref_var *deref);
+
 void nir_instr_insert_before(nir_instr *instr, nir_instr *before);
 void nir_instr_insert_after(nir_instr *instr, nir_instr *after);
 
@@ -1359,7 +1563,11 @@ bool nir_foreach_src(nir_instr *instr, nir_foreach_src_cb cb, void *state);
 nir_const_value *nir_src_as_const_value(nir_src src);
 bool nir_srcs_equal(nir_src src1, nir_src src2);
 void nir_instr_rewrite_src(nir_instr *instr, nir_src *src, nir_src new_src);
+void nir_instr_move_src(nir_instr *dest_instr, nir_src *dest, nir_src *src);
+void nir_if_rewrite_condition(nir_if *if_stmt, nir_src new_src);
 
+void nir_ssa_dest_init(nir_instr *instr, nir_dest *dest,
+                       unsigned num_components, const char *name);
 void nir_ssa_def_init(nir_instr *instr, nir_ssa_def *def,
                       unsigned num_components, const char *name);
 void nir_ssa_def_rewrite_uses(nir_ssa_def *def, nir_src new_src, void *mem_ctx);
@@ -1383,12 +1591,20 @@ void nir_index_ssa_defs(nir_function_impl *impl);
 void nir_index_blocks(nir_function_impl *impl);
 
 void nir_print_shader(nir_shader *shader, FILE *fp);
+void nir_print_instr(const nir_instr *instr, FILE *fp);
 
+#ifdef DEBUG
 void nir_validate_shader(nir_shader *shader);
+#else
+static inline void nir_validate_shader(nir_shader *shader) { (void) shader; }
+#endif /* DEBUG */
 
 void nir_calc_dominance_impl(nir_function_impl *impl);
 void nir_calc_dominance(nir_shader *shader);
 
+nir_block *nir_dominance_lca(nir_block *b1, nir_block *b2);
+bool nir_block_dominates(nir_block *parent, nir_block *child);
+
 void nir_dump_dom_tree_impl(nir_function_impl *impl, FILE *fp);
 void nir_dump_dom_tree(nir_shader *shader, FILE *fp);
 
@@ -1400,35 +1616,58 @@ void nir_dump_cfg(nir_shader *shader, FILE *fp);
 
 void nir_split_var_copies(nir_shader *shader);
 
+void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, void *mem_ctx);
+void nir_lower_var_copies(nir_shader *shader);
+
 void nir_lower_global_vars_to_local(nir_shader *shader);
 
 void nir_lower_locals_to_regs(nir_shader *shader);
 
+void nir_assign_var_locations_scalar(struct exec_list *var_list,
+                                     unsigned *size);
+void nir_assign_var_locations_scalar_direct_first(nir_shader *shader,
+                                                  struct exec_list *var_list,
+                                                  unsigned *direct_size,
+                                                  unsigned *size);
+
 void nir_lower_io(nir_shader *shader);
 
-void nir_lower_variables(nir_shader *shader);
+void nir_lower_vars_to_ssa(nir_shader *shader);
 
 void nir_remove_dead_variables(nir_shader *shader);
 
 void nir_lower_vec_to_movs(nir_shader *shader);
+void nir_lower_alu_to_scalar(nir_shader *shader);
+
+void nir_lower_phis_to_scalar(nir_shader *shader);
 
 void nir_lower_samplers(nir_shader *shader,
-                        struct gl_shader_program *shader_program,
-                        struct gl_program *prog);
+                        const struct gl_shader_program *shader_program,
+                        gl_shader_stage stage);
 
 void nir_lower_system_values(nir_shader *shader);
+void nir_lower_tex_projector(nir_shader *shader);
+void nir_lower_idiv(nir_shader *shader);
 
 void nir_lower_atomics(nir_shader *shader);
 void nir_lower_to_source_mods(nir_shader *shader);
 
+void nir_normalize_cubemap_coords(nir_shader *shader);
+
 void nir_live_variables_impl(nir_function_impl *impl);
 bool nir_ssa_defs_interfere(nir_ssa_def *a, nir_ssa_def *b);
 
 void nir_convert_to_ssa_impl(nir_function_impl *impl);
 void nir_convert_to_ssa(nir_shader *shader);
-void nir_convert_from_ssa(nir_shader *shader);
+
+/* If phi_webs_only is true, only convert SSA values involved in phi nodes to
+ * registers.  If false, convert all values (even those not involved in a phi
+ * node) to registers.
+ */
+void nir_convert_from_ssa(nir_shader *shader, bool phi_webs_only);
 
 bool nir_opt_algebraic(nir_shader *shader);
+bool nir_opt_algebraic_late(nir_shader *shader);
 bool nir_opt_constant_folding(nir_shader *shader);
 
 bool nir_opt_global_to_local(nir_shader *shader);
@@ -1441,9 +1680,15 @@ bool nir_opt_cse(nir_shader *shader);
 bool nir_opt_dce_impl(nir_function_impl *impl);
 bool nir_opt_dce(nir_shader *shader);
 
+void nir_opt_gcm(nir_shader *shader);
+
 bool nir_opt_peephole_select(nir_shader *shader);
 bool nir_opt_peephole_ffma(nir_shader *shader);
 
+bool nir_opt_remove_phis(nir_shader *shader);
+
+void nir_sweep(nir_shader *shader);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif