#include "brw_eu.h"
#include "brw_wm.h"
#include "brw_shader.h"
+#include "intel_asm_printer.h"
}
#include "gen8_generator.h"
#include "glsl/glsl_types.h"
fs_reg dst;
fs_reg src[3];
- /** @{
- * Annotation for the generated IR. One of the two can be set.
- */
- const void *ir;
- const char *annotation;
- /** @} */
-
uint32_t texture_offset; /**< Texture offset bitfield */
uint32_t offset; /* spill/unspill offset */
unsigned *assembly_size);
private:
- void generate_code(exec_list *instructions);
+ void generate_code(exec_list *instructions,
+ struct annotation_info *annotation);
void generate_fb_write(fs_inst *inst);
void generate_blorp_fb_write(fs_inst *inst);
void generate_pixel_xy(struct brw_reg dst, bool is_x);
unsigned *assembly_size);
private:
- void generate_code(exec_list *instructions);
+ void generate_code(exec_list *instructions,
+ struct annotation_info *annotation);
void generate_fb_write(fs_inst *inst);
void generate_linterp(fs_inst *inst, struct brw_reg dst,
struct brw_reg *src);
}
void
-fs_generator::generate_code(exec_list *instructions)
+fs_generator::generate_code(exec_list *instructions,
+ struct annotation_info *annotation)
{
- int last_native_insn_offset = p->next_insn_offset;
- const char *last_annotation_string = NULL;
- const void *last_annotation_ir = NULL;
-
if (unlikely(debug_flag)) {
if (prog) {
fprintf(stderr,
fs_inst *inst = (fs_inst *)node;
struct brw_reg src[3], dst;
- if (unlikely(debug_flag)) {
- foreach_list(node, &cfg->block_list) {
- bblock_link *link = (bblock_link *)node;
- bblock_t *block = link->block;
-
- if (block->start == inst) {
- fprintf(stderr, " START B%d", block->block_num);
- foreach_list(predecessor_node, &block->parents) {
- bblock_link *predecessor_link =
- (bblock_link *)predecessor_node;
- bblock_t *predecessor_block = predecessor_link->block;
- fprintf(stderr, " <-B%d", predecessor_block->block_num);
- }
- fprintf(stderr, "\n");
- }
- }
-
- if (last_annotation_ir != inst->ir) {
- last_annotation_ir = inst->ir;
- if (last_annotation_ir) {
- fprintf(stderr, " ");
- if (prog)
- ((ir_instruction *)inst->ir)->fprint(stderr);
- else {
- const prog_instruction *fpi;
- fpi = (const prog_instruction *)inst->ir;
- fprintf(stderr, "%d: ",
- (int)(fpi - (fp ? fp->Base.Instructions : 0)));
- _mesa_fprint_instruction_opt(stderr,
- fpi,
- 0, PROG_PRINT_DEBUG, NULL);
- }
- fprintf(stderr, "\n");
- }
- }
- if (last_annotation_string != inst->annotation) {
- last_annotation_string = inst->annotation;
- if (last_annotation_string)
- fprintf(stderr, " %s\n", last_annotation_string);
- }
- }
+ if (unlikely(debug_flag))
+ annotate(brw, annotation, cfg, inst, p->next_insn_offset);
for (unsigned int i = 0; i < 3; i++) {
src[i] = brw_reg_from_fs_reg(&inst->src[i]);
/* This is the place where the final HALT needs to be inserted if
* we've emitted any discards. If not, this will emit no code.
*/
- patch_discard_jumps_to_fb_writes();
+ if (!patch_discard_jumps_to_fb_writes()) {
+ annotation->ann_count--;
+ }
break;
default:
}
abort();
}
-
- if (unlikely(debug_flag)) {
- brw_disassemble(brw, p->store, last_native_insn_offset, p->next_insn_offset, stderr);
-
- foreach_list(node, &cfg->block_list) {
- bblock_link *link = (bblock_link *)node;
- bblock_t *block = link->block;
-
- if (block->end == inst) {
- fprintf(stderr, " END B%d", block->block_num);
- foreach_list(successor_node, &block->children) {
- bblock_link *successor_link =
- (bblock_link *)successor_node;
- bblock_t *successor_block = successor_link->block;
- fprintf(stderr, " ->B%d", successor_block->block_num);
- }
- fprintf(stderr, "\n");
- }
- }
- }
-
- last_native_insn_offset = p->next_insn_offset;
- }
-
- if (unlikely(debug_flag)) {
- fprintf(stderr, "\n");
}
brw_set_uip_jip(p);
-
- /* OK, while the INTEL_DEBUG=wm above is very nice for debugging FS
- * emit issues, it doesn't get the jump distances into the output,
- * which is often something we want to debug. So this is here in
- * case you're doing that.
- */
- if (0) {
- brw_disassemble(brw, p->store, 0, p->next_insn_offset, stderr);
- }
+ annotation_finalize(annotation, p->next_insn_offset);
}
const unsigned *
{
assert(simd8_instructions || simd16_instructions);
+ const struct gl_program *prog = fp ? &fp->Base : NULL;
+
if (simd8_instructions) {
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
dispatch_width = 8;
- generate_code(simd8_instructions);
- brw_compact_instructions(p, 0, 0, NULL);
+ generate_code(simd8_instructions, &annotation);
+ brw_compact_instructions(p, 0, annotation.ann_count, annotation.ann);
+
+ if (unlikely(debug_flag)) {
+ dump_assembly(p->store, annotation.ann_count, annotation.ann,
+ brw, prog, brw_disassemble);
+ ralloc_free(annotation.ann);
+ }
}
if (simd16_instructions) {
brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
dispatch_width = 16;
- generate_code(simd16_instructions);
- brw_compact_instructions(p, prog_data->prog_offset_16, 0, NULL);
+ generate_code(simd16_instructions, &annotation);
+ brw_compact_instructions(p, prog_data->prog_offset_16,
+ annotation.ann_count, annotation.ann);
+
+ if (unlikely(debug_flag)) {
+ dump_assembly(p->store, annotation.ann_count, annotation.ann,
+ brw, prog, brw_disassemble);
+ ralloc_free(annotation.ann);
+ }
}
return brw_get_program(p, assembly_size);
#include "brw_vs.h"
#include "brw_vec4_gs.h"
#include "brw_fs.h"
+#include "brw_cfg.h"
#include "glsl/ir_optimization.h"
#include "glsl/glsl_parser_extras.h"
#include "main/shaderapi.h"
/* prog_data->base.binding_table.size will be set by brw_mark_surface_used. */
}
+
+void annotate(struct brw_context *brw,
+ struct annotation_info *annotation, cfg_t *cfg,
+ backend_instruction *inst, unsigned offset)
+{
+ if (annotation->ann_size <= annotation->ann_count) {
+ annotation->ann_size = MAX2(1024, annotation->ann_size * 2);
+ annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
+ struct annotation, annotation->ann_size);
+ if (!annotation->ann)
+ return;
+ }
+
+ struct annotation *ann = &annotation->ann[annotation->ann_count++];
+ ann->offset = offset;
+ ann->ir = inst->ir;
+ ann->annotation = inst->annotation;
+
+ if (cfg->blocks[annotation->cur_block]->start == inst) {
+ ann->block_start = cfg->blocks[annotation->cur_block];
+ }
+
+ /* There is no hardware DO instruction on Gen6+, so since DO always
+ * starts a basic block, we need to set the .block_start of the next
+ * instruction's annotation with a pointer to the bblock started by
+ * the DO.
+ *
+ * There's also only complication from emitting an annotation without
+ * a corresponding hardware instruction to disassemble.
+ */
+ if (brw->gen >= 6 && inst->opcode == BRW_OPCODE_DO) {
+ annotation->ann_count--;
+ }
+
+ if (cfg->blocks[annotation->cur_block]->end == inst) {
+ ann->block_end = cfg->blocks[annotation->cur_block];
+ annotation->cur_block++;
+ }
+}
+
+void
+annotation_finalize(struct annotation_info *annotation,
+ unsigned next_inst_offset)
+{
+ if (!annotation->ann_count)
+ return;
+
+ if (annotation->ann_count == annotation->ann_size) {
+ annotation->ann = reralloc(annotation->mem_ctx, annotation->ann,
+ struct annotation, annotation->ann_size + 1);
+ }
+ annotation->ann[annotation->ann_count].offset = next_inst_offset;
+}
#include "brw_defines.h"
#include "main/compiler.h"
#include "glsl/ir.h"
+#include "intel_asm_printer.h"
#pragma once
#ifdef __cplusplus
+class cfg_t;
+
class backend_instruction : public exec_node {
public:
bool is_tex() const;
uint8_t predicate;
bool predicate_inverse;
bool writes_accumulator; /**< instruction implicitly writes accumulator */
+
+ /** @{
+ * Annotation for the generated IR. One of the two can be set.
+ */
+ const void *ir;
+ const char *annotation;
+ /** @} */
};
enum instruction_scheduler_mode {
uint32_t brw_texture_offset(struct gl_context *ctx, ir_constant *offset);
+void annotate(struct brw_context *brw,
+ struct annotation_info *annotation, cfg_t *cfg,
+ backend_instruction *inst, unsigned offset);
+void annotation_finalize(struct annotation_info *annotation, unsigned offset);
+
#endif /* __cplusplus */
int brw_type_for_base_type(const struct glsl_type *type);
#include "brw_context.h"
#include "brw_eu.h"
+#include "intel_asm_printer.h"
#ifdef __cplusplus
}; /* extern "C" */
int base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */
uint32_t offset; /* spill/unspill offset */
- /** @{
- * Annotation for the generated IR. One of the two can be set.
- */
- const void *ir;
- const char *annotation;
- /** @} */
bool is_send_from_grf();
bool can_reswizzle_dst(int dst_writemask, int swizzle, int swizzle_mask);
const unsigned *generate_assembly(exec_list *insts, unsigned *asm_size);
private:
- void generate_code(exec_list *instructions);
+ void generate_code(exec_list *instructions,
+ struct annotation_info *annotation);
void generate_vec4_instruction(vec4_instruction *inst,
struct brw_reg dst,
struct brw_reg *src);
const unsigned *generate_assembly(exec_list *insts, unsigned *asm_size);
private:
- void generate_code(exec_list *instructions);
+ void generate_code(exec_list *instructions,
+ struct annotation_info *annotation);
void generate_vec4_instruction(vec4_instruction *inst,
struct brw_reg dst,
struct brw_reg *src);
*/
#include "brw_vec4.h"
+#include "brw_cfg.h"
extern "C" {
#include "brw_eu.h"
}
void
-vec4_generator::generate_code(exec_list *instructions)
+vec4_generator::generate_code(exec_list *instructions,
+ struct annotation_info *annotation)
{
- int last_native_insn_offset = 0;
- const char *last_annotation_string = NULL;
- const void *last_annotation_ir = NULL;
-
if (unlikely(debug_flag)) {
if (shader_prog) {
fprintf(stderr, "Native code for %s vertex shader %d:\n",
}
}
+ cfg_t *cfg = NULL;
+ if (unlikely(debug_flag))
+ cfg = new(mem_ctx) cfg_t(instructions);
+
foreach_list(node, instructions) {
vec4_instruction *inst = (vec4_instruction *)node;
struct brw_reg src[3], dst;
- if (unlikely(debug_flag)) {
- if (last_annotation_ir != inst->ir) {
- last_annotation_ir = inst->ir;
- if (last_annotation_ir) {
- fprintf(stderr, " ");
- if (shader_prog) {
- ((ir_instruction *) last_annotation_ir)->fprint(stderr);
- } else {
- const prog_instruction *vpi;
- vpi = (const prog_instruction *) inst->ir;
- fprintf(stderr, "%d: ", (int)(vpi - prog->Instructions));
- _mesa_fprint_instruction_opt(stderr, vpi, 0,
- PROG_PRINT_DEBUG, NULL);
- }
- fprintf(stderr, "\n");
- }
- }
- if (last_annotation_string != inst->annotation) {
- last_annotation_string = inst->annotation;
- if (last_annotation_string)
- fprintf(stderr, " %s\n", last_annotation_string);
- }
- }
+ if (unlikely(debug_flag))
+ annotate(brw, annotation, cfg, inst, p->next_insn_offset);
for (unsigned int i = 0; i < 3; i++) {
src[i] = inst->get_src(this->prog_data, i);
if (inst->no_dd_check)
last->header.dependency_control |= BRW_DEPENDENCY_NOTCHECKED;
}
-
- if (unlikely(debug_flag)) {
- brw_disassemble(brw, p->store,
- last_native_insn_offset, p->next_insn_offset, stderr);
- }
-
- last_native_insn_offset = p->next_insn_offset;
- }
-
- if (unlikely(debug_flag)) {
- fprintf(stderr, "\n");
}
brw_set_uip_jip(p);
-
- /* OK, while the INTEL_DEBUG=vs above is very nice for debugging VS
- * emit issues, it doesn't get the jump distances into the output,
- * which is often something we want to debug. So this is here in
- * case you're doing that.
- */
- if (0 && unlikely(debug_flag)) {
- brw_disassemble(brw, p->store, 0, p->next_insn_offset, stderr);
- }
+ annotation_finalize(annotation, p->next_insn_offset);
}
const unsigned *
vec4_generator::generate_assembly(exec_list *instructions,
unsigned *assembly_size)
{
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
brw_set_access_mode(p, BRW_ALIGN_16);
- generate_code(instructions);
- brw_compact_instructions(p, 0, 0, NULL);
+ generate_code(instructions, &annotation);
+ brw_compact_instructions(p, 0, annotation.ann_count, annotation.ann);
+
+ if (unlikely(debug_flag)) {
+ dump_assembly(p->store, annotation.ann_count, annotation.ann,
+ brw, prog, brw_disassemble);
+ ralloc_free(annotation.ann);
+ }
+
return brw_get_program(p, assembly_size);
}
}
void
-gen8_fs_generator::generate_code(exec_list *instructions)
+gen8_fs_generator::generate_code(exec_list *instructions,
+ struct annotation_info *annotation)
{
- int last_native_inst_offset = next_inst_offset;
- const char *last_annotation_string = NULL;
- const void *last_annotation_ir = NULL;
-
if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
if (prog) {
fprintf(stderr,
fs_inst *ir = (fs_inst *) node;
struct brw_reg src[3], dst;
- if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
- foreach_list(node, &cfg->block_list) {
- bblock_link *link = (bblock_link *)node;
- bblock_t *block = link->block;
-
- if (block->start == ir) {
- fprintf(stderr, " START B%d", block->block_num);
- foreach_list(predecessor_node, &block->parents) {
- bblock_link *predecessor_link =
- (bblock_link *)predecessor_node;
- bblock_t *predecessor_block = predecessor_link->block;
- fprintf(stderr, " <-B%d", predecessor_block->block_num);
- }
- fprintf(stderr, "\n");
- }
- }
-
- if (last_annotation_ir != ir->ir) {
- last_annotation_ir = ir->ir;
- if (last_annotation_ir) {
- fprintf(stderr, " ");
- if (prog) {
- ((ir_instruction *) ir->ir)->fprint(stderr);
- } else if (prog) {
- const prog_instruction *fpi;
- fpi = (const prog_instruction *) ir->ir;
- fprintf(stderr, "%d: ", (int)(fpi - prog->Instructions));
- _mesa_fprint_instruction_opt(stderr,
- fpi,
- 0, PROG_PRINT_DEBUG, NULL);
- }
- fprintf(stderr, "\n");
- }
- }
- if (last_annotation_string != ir->annotation) {
- last_annotation_string = ir->annotation;
- if (last_annotation_string)
- fprintf(stderr, " %s\n", last_annotation_string);
- }
- }
+ if (unlikely(INTEL_DEBUG & DEBUG_WM))
+ annotate(brw, annotation, cfg, ir, next_inst_offset);
for (unsigned int i = 0; i < 3; i++) {
src[i] = brw_reg_from_fs_reg(&ir->src[i]);
}
abort();
}
-
- if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
- gen8_disassemble(brw, store, last_native_inst_offset, next_inst_offset, stderr);
-
- foreach_list(node, &cfg->block_list) {
- bblock_link *link = (bblock_link *)node;
- bblock_t *block = link->block;
-
- if (block->end == ir) {
- fprintf(stderr, " END B%d", block->block_num);
- foreach_list(successor_node, &block->children) {
- bblock_link *successor_link =
- (bblock_link *)successor_node;
- bblock_t *successor_block = successor_link->block;
- fprintf(stderr, " ->B%d", successor_block->block_num);
- }
- fprintf(stderr, "\n");
- }
- }
- }
-
- last_native_inst_offset = next_inst_offset;
- }
-
- if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
- fprintf(stderr, "\n");
}
patch_jump_targets();
-
- /* OK, while the INTEL_DEBUG=fs above is very nice for debugging FS
- * emit issues, it doesn't get the jump distances into the output,
- * which is often something we want to debug. So this is here in
- * case you're doing that.
- */
- if (0 && unlikely(INTEL_DEBUG & DEBUG_WM)) {
- gen8_disassemble(brw, store, 0, next_inst_offset, stderr);
- }
+ annotation_finalize(annotation, next_inst_offset);
}
const unsigned *
assert(simd8_instructions || simd16_instructions);
if (simd8_instructions) {
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
dispatch_width = 8;
- generate_code(simd8_instructions);
+ generate_code(simd8_instructions, &annotation);
+
+ if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+ dump_assembly(store, annotation.ann_count, annotation.ann, brw, prog,
+ gen8_disassemble);
+ ralloc_free(annotation.ann);
+ }
}
if (simd16_instructions) {
/* Save off the start of this SIMD16 program */
prog_data->prog_offset_16 = nr_inst * sizeof(gen8_instruction);
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
dispatch_width = 16;
- generate_code(simd16_instructions);
+ generate_code(simd16_instructions, &annotation);
+
+ if (unlikely(INTEL_DEBUG & DEBUG_WM)) {
+ dump_assembly(store, annotation.ann_count, annotation.ann,
+ brw, prog, gen8_disassemble);
+ ralloc_free(annotation.ann);
+ }
}
*assembly_size = next_inst_offset;
*/
#include "brw_vec4.h"
+#include "brw_cfg.h"
extern "C" {
#include "brw_eu.h"
}
void
-gen8_vec4_generator::generate_code(exec_list *instructions)
+gen8_vec4_generator::generate_code(exec_list *instructions,
+ struct annotation_info *annotation)
{
- int last_native_inst_offset = 0;
- const char *last_annotation_string = NULL;
- const void *last_annotation_ir = NULL;
-
if (unlikely(debug_flag)) {
if (shader_prog) {
fprintf(stderr, "Native code for %s vertex shader %d:\n",
}
}
+ cfg_t *cfg = NULL;
+ if (unlikely(debug_flag))
+ cfg = new(mem_ctx) cfg_t(instructions);
+
foreach_list(node, instructions) {
vec4_instruction *ir = (vec4_instruction *) node;
struct brw_reg src[3], dst;
- if (unlikely(debug_flag)) {
- if (last_annotation_ir != ir->ir) {
- last_annotation_ir = ir->ir;
- if (last_annotation_ir) {
- fprintf(stderr, " ");
- if (shader_prog) {
- ((ir_instruction *) last_annotation_ir)->fprint(stderr);
- } else {
- const prog_instruction *vpi;
- vpi = (const prog_instruction *) ir->ir;
- fprintf(stderr, "%d: ", (int)(vpi - prog->Instructions));
- _mesa_fprint_instruction_opt(stderr, vpi, 0,
- PROG_PRINT_DEBUG, NULL);
- }
- fprintf(stderr, "\n");
- }
- }
- if (last_annotation_string != ir->annotation) {
- last_annotation_string = ir->annotation;
- if (last_annotation_string)
- fprintf(stderr, " %s\n", last_annotation_string);
- }
- }
+ if (unlikely(debug_flag))
+ annotate(brw, annotation, cfg, ir, next_inst_offset);
for (unsigned int i = 0; i < 3; i++) {
src[i] = ir->get_src(prog_data, i);
gen8_set_no_dd_clear(last, ir->no_dd_clear);
gen8_set_no_dd_check(last, ir->no_dd_check);
}
-
- if (unlikely(debug_flag)) {
- gen8_disassemble(brw, store, last_native_inst_offset, next_inst_offset, stderr);
- }
-
- last_native_inst_offset = next_inst_offset;
- }
-
- if (unlikely(debug_flag)) {
- fprintf(stderr, "\n");
}
patch_jump_targets();
-
- /* OK, while the INTEL_DEBUG=vs above is very nice for debugging VS
- * emit issues, it doesn't get the jump distances into the output,
- * which is often something we want to debug. So this is here in
- * case you're doing that.
- */
- if (0 && unlikely(debug_flag)) {
- gen8_disassemble(brw, store, 0, next_inst_offset, stderr);
- }
+ annotation_finalize(annotation, next_inst_offset);
}
const unsigned *
gen8_vec4_generator::generate_assembly(exec_list *instructions,
unsigned *assembly_size)
{
+ struct annotation_info annotation;
+ memset(&annotation, 0, sizeof(annotation));
+
default_state.access_mode = BRW_ALIGN_16;
default_state.exec_size = BRW_EXECUTE_8;
- generate_code(instructions);
+ generate_code(instructions, &annotation);
+
+ if (unlikely(debug_flag)) {
+ dump_assembly(store, annotation.ann_count, annotation.ann,
+ brw, prog, gen8_disassemble);
+ ralloc_free(annotation.ann);
+ }
+
*assembly_size = next_inst_offset;
return (const unsigned *) store;
}
#ifndef _INTEL_ASM_ANNOTATION_H
#define _INTEL_ASM_ANNOTATION_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct bblock_t;
struct brw_context;
struct gl_program;
const char *annotation;
};
+struct annotation_info {
+ void *mem_ctx;
+ struct annotation *ann;
+ int ann_count;
+ int ann_size;
+
+ /** Block index in the cfg. */
+ int cur_block;
+};
+
typedef void (*disassemble_func)(struct brw_context *brw, void *assembly,
int start, int end, FILE *out);
struct brw_context *brw, const struct gl_program *prog,
disassemble_func disassemble);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
#endif /* _INTEL_ASM_ANNOTATION_H */