int i[16];
float f[16];
bool b[16];
+ double d[16];
};
typedef struct nir_constant {
#define nir_foreach_variable(var, var_list) \
foreach_list_typed(nir_variable, var, node, var_list)
+#define nir_foreach_variable_safe(var, var_list) \
+ foreach_list_typed_safe(nir_variable, var, node, var_list)
+
static inline bool
nir_variable_is_global(const nir_variable *var)
{
unsigned num_components; /** < number of vector components */
unsigned num_array_elems; /** < size of array (0 for no array) */
+ /* The bit-size of each channel; must be one of 8, 16, 32, or 64 */
+ uint8_t bit_size;
+
/** generic register index. */
unsigned index;
struct list_head if_uses;
uint8_t num_components;
+
+ /* The bit-size of each channel; must be one of 8, 16, 32, or 64 */
+ uint8_t bit_size;
} nir_ssa_def;
struct nir_src;
return dest;
}
+static inline unsigned
+nir_src_bit_size(nir_src src)
+{
+ return src.is_ssa ? src.ssa->bit_size : src.reg.reg->bit_size;
+}
+
+static inline unsigned
+nir_dest_bit_size(nir_dest dest)
+{
+ return dest.is_ssa ? dest.ssa.bit_size : dest.reg.reg->bit_size;
+}
+
void nir_src_copy(nir_src *dest, const nir_src *src, void *instr_or_if);
void nir_dest_copy(nir_dest *dest, const nir_dest *src, nir_instr *instr);
nir_type_float,
nir_type_int,
nir_type_uint,
- nir_type_bool
+ nir_type_bool,
+ nir_type_bool32 = 32 | nir_type_bool,
+ nir_type_int8 = 8 | nir_type_int,
+ nir_type_int16 = 16 | nir_type_int,
+ nir_type_int32 = 32 | nir_type_int,
+ nir_type_int64 = 64 | nir_type_int,
+ nir_type_uint8 = 8 | nir_type_uint,
+ nir_type_uint16 = 16 | nir_type_uint,
+ nir_type_uint32 = 32 | nir_type_uint,
+ nir_type_uint64 = 64 | nir_type_uint,
+ nir_type_float16 = 16 | nir_type_float,
+ nir_type_float32 = 32 | nir_type_float,
+ nir_type_float64 = 64 | nir_type_float,
} nir_alu_type;
+#define NIR_ALU_TYPE_SIZE_MASK 0xfffffff8
+#define NIR_ALU_TYPE_BASE_TYPE_MASK 0x00000007
+
+static inline unsigned
+nir_alu_type_get_type_size(nir_alu_type type)
+{
+ return type & NIR_ALU_TYPE_SIZE_MASK;
+}
+
+static inline unsigned
+nir_alu_type_get_base_type(nir_alu_type type)
+{
+ return type & NIR_ALU_TYPE_BASE_TYPE_MASK;
+}
+
typedef enum {
NIR_OP_IS_COMMUTATIVE = (1 << 0),
NIR_OP_IS_ASSOCIATIVE = (1 << 1),
typedef struct nir_alu_instr {
nir_instr instr;
nir_op op;
+
+ /** Indicates that this ALU instruction generates an exact value
+ *
+ * This is kind of a mixture of GLSL "precise" and "invariant" and not
+ * really equivalent to either. This indicates that the value generated by
+ * this operation is high-precision and any code transformations that touch
+ * it must ensure that the resulting value is bit-for-bit identical to the
+ * original.
+ */
+ bool exact;
+
nir_alu_dest dest;
nir_alu_src src[];
} nir_alu_instr;
typedef struct {
union {
- float f[4];
- int32_t i[4];
- uint32_t u[4];
+ float f32[4];
+ double f64[4];
+ int32_t i32[4];
+ uint32_t u32[4];
+ int64_t i64[4];
+ uint64_t u64[4];
};
} nir_const_value;
* the highest index a load_input_*, load_uniform_*, etc. intrinsic can
* access plus one
*/
- unsigned num_inputs, num_uniforms, num_outputs;
+ unsigned num_inputs, num_uniforms, num_outputs, num_shared;
/** The shader stage, such as MESA_SHADER_VERTEX. */
gl_shader_stage stage;
} nir_shader;
+static inline nir_function *
+nir_shader_get_entrypoint(nir_shader *shader)
+{
+ assert(exec_list_length(&shader->functions) == 1);
+ struct exec_node *func_node = exec_list_get_head(&shader->functions);
+ nir_function *func = exec_node_data(nir_function, func_node, node);
+ assert(func->return_type == glsl_void_type());
+ assert(func->num_params == 0);
+ return func;
+}
+
#define nir_foreach_function(shader, func) \
foreach_list_typed(nir_function, func, node, &(shader)->functions)
nir_jump_instr *nir_jump_instr_create(nir_shader *shader, nir_jump_type type);
nir_load_const_instr *nir_load_const_instr_create(nir_shader *shader,
- unsigned num_components);
+ unsigned num_components,
+ unsigned bit_size);
nir_intrinsic_instr *nir_intrinsic_instr_create(nir_shader *shader,
nir_intrinsic_op op);
nir_parallel_copy_instr *nir_parallel_copy_instr_create(nir_shader *shader);
nir_ssa_undef_instr *nir_ssa_undef_instr_create(nir_shader *shader,
- unsigned num_components);
+ unsigned num_components,
+ unsigned bit_size);
nir_deref_var *nir_deref_var_create(void *mem_ctx, nir_variable *var);
nir_deref_array *nir_deref_array_create(void *mem_ctx);
};
} nir_cursor;
+static inline nir_block *
+nir_cursor_current_block(nir_cursor cursor)
+{
+ if (cursor.option == nir_cursor_before_instr ||
+ cursor.option == nir_cursor_after_instr) {
+ return cursor.instr->block;
+ } else {
+ return cursor.block;
+ }
+}
+
+bool nir_cursors_equal(nir_cursor a, nir_cursor b);
+
static inline nir_cursor
nir_before_block(nir_block *block)
{
return nir_before_block(nir_cf_node_as_block(nir_cf_node_next(node)));
}
+static inline nir_cursor
+nir_after_cf_node_and_phis(nir_cf_node *node)
+{
+ if (node->type == nir_cf_node_block)
+ return nir_after_block(nir_cf_node_as_block(node));
+
+ nir_block *block = nir_cf_node_as_block(nir_cf_node_next(node));
+ assert(block->cf_node.type == nir_cf_node_block);
+
+ nir_foreach_instr(block, instr) {
+ if (instr->type != nir_instr_type_phi)
+ return nir_before_instr(instr);
+ }
+ return nir_after_block(block);
+}
+
static inline nir_cursor
nir_before_cf_list(struct exec_list *cf_list)
{
nir_dest new_dest);
void nir_ssa_dest_init(nir_instr *instr, nir_dest *dest,
- unsigned num_components, const char *name);
+ unsigned num_components, unsigned bit_size,
+ const char *name);
void nir_ssa_def_init(nir_instr *instr, nir_ssa_def *def,
- unsigned num_components, const char *name);
+ unsigned num_components, unsigned bit_size,
+ const char *name);
void nir_ssa_def_rewrite_uses(nir_ssa_def *def, nir_src new_src);
void nir_ssa_def_rewrite_uses_after(nir_ssa_def *def, nir_src new_src,
nir_instr *after_me);
void nir_print_shader(nir_shader *shader, FILE *fp);
void nir_print_instr(const nir_instr *instr, FILE *fp);
-nir_shader * nir_shader_clone(void *mem_ctx, const nir_shader *s);
+nir_shader *nir_shader_clone(void *mem_ctx, const nir_shader *s);
nir_function_impl *nir_function_impl_clone(const nir_function_impl *fi);
+nir_constant *nir_constant_clone(const nir_constant *c, nir_variable *var);
+nir_variable *nir_variable_clone(const nir_variable *c, nir_shader *shader);
#ifdef DEBUG
void nir_validate_shader(nir_shader *shader);
bool nir_split_var_copies(nir_shader *shader);
+bool nir_lower_returns_impl(nir_function_impl *impl);
+bool nir_lower_returns(nir_shader *shader);
+
+bool nir_inline_functions(nir_shader *shader);
+
void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, void *mem_ctx);
void nir_lower_var_copies(nir_shader *shader);
bool nir_lower_locals_to_regs(nir_shader *shader);
-void nir_lower_outputs_to_temporaries(nir_shader *shader);
+void nir_lower_outputs_to_temporaries(nir_shader *shader,
+ nir_function *entrypoint);
+void nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint);
void nir_assign_var_locations(struct exec_list *var_list,
unsigned *size,
void nir_convert_to_ssa_impl(nir_function_impl *impl);
void nir_convert_to_ssa(nir_shader *shader);
+bool nir_repair_ssa_impl(nir_function_impl *impl);
+bool nir_repair_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.