summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/freedreno/Makefile.sources2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.h1
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.h10
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_cmdline.c3
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler.c34
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c32
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_dump.c456
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_print.c210
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_ra.c4
10 files changed, 228 insertions, 525 deletions
diff --git a/src/gallium/drivers/freedreno/Makefile.sources b/src/gallium/drivers/freedreno/Makefile.sources
index a565a9c4e4d..809d1a0f8f5 100644
--- a/src/gallium/drivers/freedreno/Makefile.sources
+++ b/src/gallium/drivers/freedreno/Makefile.sources
@@ -125,13 +125,13 @@ ir3_SOURCES := \
ir3/ir3_compiler.h \
ir3/ir3_cp.c \
ir3/ir3_depth.c \
- ir3/ir3_dump.c \
ir3/ir3_flatten.c \
ir3/ir3_group.c \
ir3/ir3.h \
ir3/ir3_legalize.c \
ir3/ir3_nir.h \
ir3/ir3_nir_lower_if_else.c \
+ ir3/ir3_print.c \
ir3/ir3_ra.c \
ir3/ir3_sched.c \
ir3/ir3_shader.c \
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 6a5748c73ca..00b9471095e 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -68,7 +68,6 @@ static const struct debug_named_value debug_options[] = {
{"fraghalf", FD_DBG_FRAGHALF, "Use half-precision in fragment shader"},
{"nobin", FD_DBG_NOBIN, "Disable hw binning"},
{"optmsgs", FD_DBG_OPTMSGS,"Enable optimizer debug messages"},
- {"optdump", FD_DBG_OPTDUMP,"Dump shader DAG to .dot files"},
{"glsl120", FD_DBG_GLSL120,"Temporary flag to force GLSL 120 (rather than 130) on a3xx+"},
{"nocp", FD_DBG_NOCP, "Disable copy-propagation"},
{"nir", FD_DBG_NIR, "Enable experimental NIR compiler"},
diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h
index 2735ae41315..aec09ab6616 100644
--- a/src/gallium/drivers/freedreno/freedreno_util.h
+++ b/src/gallium/drivers/freedreno/freedreno_util.h
@@ -63,7 +63,6 @@ enum adreno_stencil_op fd_stencil_op(unsigned op);
#define FD_DBG_FRAGHALF 0x0080
#define FD_DBG_NOBIN 0x0100
#define FD_DBG_OPTMSGS 0x0400
-#define FD_DBG_OPTDUMP 0x0800
#define FD_DBG_GLSL120 0x1000
#define FD_DBG_NOCP 0x2000
#define FD_DBG_NIR 0x4000
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index a7fd1814ff5..f37dfab3341 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -747,12 +747,8 @@ static inline struct ir3_instruction * __ssa_src_n(struct ir3_instruction *instr
/* dump: */
-#include <stdio.h>
-void ir3_dump(struct ir3 *shader, const char *name,
- struct ir3_block *block /* XXX maybe 'block' ptr should move to ir3? */,
- FILE *f);
-void ir3_dump_instr_single(struct ir3_instruction *instr);
-void ir3_dump_instr_list(struct ir3_instruction *instr);
+void ir3_print(struct ir3 *ir);
+void ir3_print_instr(struct ir3_instruction *instr);
/* flatten if/else: */
int ir3_block_flatten(struct ir3_block *block);
@@ -765,7 +761,7 @@ void ir3_block_depth(struct ir3_block *block);
/* copy-propagate: */
void ir3_block_cp(struct ir3_block *block);
-/* group neightbors and insert mov's to resolve conflicts: */
+/* group neighbors and insert mov's to resolve conflicts: */
void ir3_block_group(struct ir3_block *block);
/* scheduling: */
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
index 0b16cc1eb54..e42afeaeb21 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c
@@ -30,6 +30,7 @@
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
+#include <stdio.h>
#include <err.h>
#include "tgsi/tgsi_parse.h"
@@ -243,7 +244,7 @@ int main(int argc, char **argv)
while (n < argc) {
if (!strcmp(argv[n], "--verbose")) {
- fd_mesa_debug |= FD_DBG_OPTDUMP | FD_DBG_MSGS | FD_DBG_OPTMSGS;
+ fd_mesa_debug |= FD_DBG_MSGS | FD_DBG_OPTMSGS;
n++;
continue;
}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
index cc049d3fdfd..25af9f91d3f 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c
@@ -3515,22 +3515,6 @@ compile_instructions(struct ir3_compile_context *ctx)
}
}
-static void
-compile_dump(struct ir3_compile_context *ctx)
-{
- const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag";
- static unsigned n = 0;
- char fname[16];
- FILE *f;
- snprintf(fname, sizeof(fname), "%s-%04u.dot", name, n++);
- f = fopen(fname, "w");
- if (!f)
- return;
- ir3_block_depth(ctx->block);
- ir3_dump(ctx->ir, name, ctx->block, f);
- fclose(f);
-}
-
int
ir3_compile_shader(struct ir3_shader_variant *so,
const struct tgsi_token *tokens, struct ir3_shader_key key,
@@ -3613,20 +3597,15 @@ ir3_compile_shader(struct ir3_shader_variant *so,
block->outputs[block->noutputs++] = ctx.kill[i];
}
- if (fd_mesa_debug & FD_DBG_OPTDUMP)
- compile_dump(&ctx);
-
ret = ir3_block_flatten(block);
if (ret < 0) {
DBG("FLATTEN failed!");
goto out;
}
- if ((ret > 0) && (fd_mesa_debug & FD_DBG_OPTDUMP))
- compile_dump(&ctx);
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("BEFORE CP:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ir3_block_depth(block);
@@ -3641,7 +3620,7 @@ ir3_compile_shader(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("BEFORE GROUPING:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
/* Group left/right neighbors, inserting mov's where needed to
@@ -3649,14 +3628,11 @@ ir3_compile_shader(struct ir3_shader_variant *so,
*/
ir3_block_group(block);
- if (fd_mesa_debug & FD_DBG_OPTDUMP)
- compile_dump(&ctx);
-
ir3_block_depth(block);
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER DEPTH:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ret = ir3_block_sched(block);
@@ -3667,7 +3643,7 @@ ir3_compile_shader(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER SCHED:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ret = ir3_block_ra(block, so->type, so->frag_coord, so->frag_face);
@@ -3678,7 +3654,7 @@ ir3_compile_shader(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER RA:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ir3_block_legalize(block, &so->has_samp, &max_bary);
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
index 2cf25ea6e0a..8d382e5cf3e 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
@@ -1908,22 +1908,6 @@ fixup_frag_inputs(struct ir3_compile *ctx)
block->inputs = inputs;
}
-static void
-compile_dump(struct ir3_compile *ctx)
-{
- const char *name = (ctx->so->type == SHADER_VERTEX) ? "vert" : "frag";
- static unsigned n = 0;
- char fname[16];
- FILE *f;
- snprintf(fname, sizeof(fname), "%s-%04u.dot", name, n++);
- f = fopen(fname, "w");
- if (!f)
- return;
- ir3_block_depth(ctx->block);
- ir3_dump(ctx->ir, name, ctx->block, f);
- fclose(f);
-}
-
int
ir3_compile_shader_nir(struct ir3_shader_variant *so,
const struct tgsi_token *tokens, struct ir3_shader_key key)
@@ -2008,12 +1992,9 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
block->outputs[block->noutputs++] = ctx->kill[i];
}
- if (fd_mesa_debug & FD_DBG_OPTDUMP)
- compile_dump(ctx);
-
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("BEFORE CP:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ir3_block_depth(block);
@@ -2022,7 +2003,7 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("BEFORE GROUPING:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
/* Group left/right neighbors, inserting mov's where needed to
@@ -2030,14 +2011,11 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
*/
ir3_block_group(block);
- if (fd_mesa_debug & FD_DBG_OPTDUMP)
- compile_dump(ctx);
-
ir3_block_depth(block);
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER DEPTH:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ret = ir3_block_sched(block);
@@ -2048,7 +2026,7 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER SCHED:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ret = ir3_block_ra(block, so->type, so->frag_coord, so->frag_face);
@@ -2059,7 +2037,7 @@ ir3_compile_shader_nir(struct ir3_shader_variant *so,
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
printf("AFTER RA:\n");
- ir3_dump_instr_list(block->head);
+ ir3_print(so->ir);
}
ir3_block_legalize(block, &so->has_samp, &max_bary);
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_dump.c b/src/gallium/drivers/freedreno/ir3/ir3_dump.c
deleted file mode 100644
index 1614d637b13..00000000000
--- a/src/gallium/drivers/freedreno/ir3/ir3_dump.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
-
-/*
- * Copyright (C) 2014 Rob Clark <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Rob Clark <[email protected]>
- */
-
-#include <stdarg.h>
-
-#include "ir3.h"
-
-#define PTRID(x) ((unsigned long)(x))
-
-struct ir3_dump_ctx {
- FILE *f;
- bool verbose;
-};
-
-static void dump_instr_name(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr)
-{
- /* for debugging: */
- if (ctx->verbose) {
-#ifdef DEBUG
- fprintf(ctx->f, "%04u:", instr->serialno);
-#endif
- fprintf(ctx->f, "%03u: ", instr->depth);
- }
-
- if (instr->flags & IR3_INSTR_SY)
- fprintf(ctx->f, "(sy)");
- if (instr->flags & IR3_INSTR_SS)
- fprintf(ctx->f, "(ss)");
-
- if (is_meta(instr)) {
- switch(instr->opc) {
- case OPC_META_PHI:
- fprintf(ctx->f, "&#934;");
- break;
- default:
- /* shouldn't hit here.. just for debugging: */
- switch (instr->opc) {
- case OPC_META_INPUT: fprintf(ctx->f, "_meta:in"); break;
- case OPC_META_OUTPUT: fprintf(ctx->f, "_meta:out"); break;
- case OPC_META_FO: fprintf(ctx->f, "_meta:fo"); break;
- case OPC_META_FI: fprintf(ctx->f, "_meta:fi"); break;
- case OPC_META_FLOW: fprintf(ctx->f, "_meta:flow"); break;
-
- default: fprintf(ctx->f, "_meta:%d", instr->opc); break;
- }
- break;
- }
- } else if (instr->category == 1) {
- static const char *type[] = {
- [TYPE_F16] = "f16",
- [TYPE_F32] = "f32",
- [TYPE_U16] = "u16",
- [TYPE_U32] = "u32",
- [TYPE_S16] = "s16",
- [TYPE_S32] = "s32",
- [TYPE_U8] = "u8",
- [TYPE_S8] = "s8",
- };
- if (instr->cat1.src_type == instr->cat1.dst_type)
- fprintf(ctx->f, "mov");
- else
- fprintf(ctx->f, "cov");
- fprintf(ctx->f, ".%s%s", type[instr->cat1.src_type], type[instr->cat1.dst_type]);
- } else {
- fprintf(ctx->f, "%s", ir3_instr_name(instr));
- if (instr->flags & IR3_INSTR_3D)
- fprintf(ctx->f, ".3d");
- if (instr->flags & IR3_INSTR_A)
- fprintf(ctx->f, ".a");
- if (instr->flags & IR3_INSTR_O)
- fprintf(ctx->f, ".o");
- if (instr->flags & IR3_INSTR_P)
- fprintf(ctx->f, ".p");
- if (instr->flags & IR3_INSTR_S)
- fprintf(ctx->f, ".s");
- if (instr->flags & IR3_INSTR_S2EN)
- fprintf(ctx->f, ".s2en");
- }
-}
-
-static void dump_reg_name(struct ir3_dump_ctx *ctx,
- struct ir3_register *reg, bool followssa)
-{
- if ((reg->flags & (IR3_REG_FABS | IR3_REG_SABS)) &&
- (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT)))
- fprintf(ctx->f, "(absneg)");
- else if (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT))
- fprintf(ctx->f, "(neg)");
- else if (reg->flags & (IR3_REG_FABS | IR3_REG_SABS))
- fprintf(ctx->f, "(abs)");
-
- if (reg->flags & IR3_REG_IMMED) {
- fprintf(ctx->f, "imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
- } else if (reg->flags & IR3_REG_SSA) {
- if (ctx->verbose) {
- fprintf(ctx->f, "_");
- if (followssa) {
- fprintf(ctx->f, "[");
- dump_instr_name(ctx, reg->instr);
- fprintf(ctx->f, "]");
- }
- }
- } else if (reg->flags & IR3_REG_RELATIV) {
- if (reg->flags & IR3_REG_HALF)
- fprintf(ctx->f, "h");
- if (reg->flags & IR3_REG_CONST)
- fprintf(ctx->f, "c<a0.x + %u>", reg->num);
- else
- fprintf(ctx->f, "\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->num, reg->size);
- } else {
- if (reg->flags & IR3_REG_HALF)
- fprintf(ctx->f, "h");
- if (reg->flags & IR3_REG_CONST)
- fprintf(ctx->f, "c%u.%c", reg_num(reg), "xyzw"[reg_comp(reg)]);
- else
- fprintf(ctx->f, "\x1b[0;31mr%u.%c\x1b[0m", reg_num(reg), "xyzw"[reg_comp(reg)]);
- }
-}
-
-static void ir3_instr_dump(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr);
-static void ir3_block_dump(struct ir3_dump_ctx *ctx,
- struct ir3_block *block, const char *name);
-
-static void dump_instr(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr)
-{
- /* if we've already visited this instruction, bail now: */
- if (ir3_instr_check_mark(instr))
- return;
-
- /* some meta-instructions need to be handled specially: */
- if (is_meta(instr)) {
- if ((instr->opc == OPC_META_FO) ||
- (instr->opc == OPC_META_FI)) {
- struct ir3_instruction *src;
- foreach_ssa_src(src, instr)
- dump_instr(ctx, src);
- } else if (instr->opc == OPC_META_FLOW) {
- struct ir3_register *reg = instr->regs[1];
- ir3_block_dump(ctx, instr->flow.if_block, "if");
- if (instr->flow.else_block)
- ir3_block_dump(ctx, instr->flow.else_block, "else");
- if (reg->flags & IR3_REG_SSA)
- dump_instr(ctx, reg->instr);
- } else if (instr->opc == OPC_META_PHI) {
- /* treat like a normal instruction: */
- ir3_instr_dump(ctx, instr);
- }
- } else {
- ir3_instr_dump(ctx, instr);
- }
-}
-
-/* arrarraggh! if link is to something outside of the current block, we
- * need to defer emitting the link until the end of the block, since the
- * edge triggers pre-creation of the node it links to inside the cluster,
- * even though it is meant to be outside..
- */
-static struct {
- char buf[40960];
- unsigned n;
-} edge_buf;
-
-/* helper to print or defer: */
-static void printdef(struct ir3_dump_ctx *ctx,
- bool defer, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- if (defer) {
- unsigned n = edge_buf.n;
- n += vsnprintf(&edge_buf.buf[n], sizeof(edge_buf.buf) - n,
- fmt, ap);
- edge_buf.n = n;
- } else {
- vfprintf(ctx->f, fmt, ap);
- }
- va_end(ap);
-}
-
-static void dump_link2(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr, const char *target, bool defer)
-{
- /* some meta-instructions need to be handled specially: */
- if (is_meta(instr)) {
- if (instr->opc == OPC_META_INPUT) {
- printdef(ctx, defer, "input%lx:<in%u>:w -> %s",
- PTRID(instr->inout.block),
- instr->regs[0]->num, target);
- } else if (instr->opc == OPC_META_FO) {
- struct ir3_register *reg = instr->regs[1];
- dump_link2(ctx, reg->instr, target, defer);
- printdef(ctx, defer, "[label=\".%c\"]",
- "xyzw"[instr->fo.off & 0x3]);
- } else if (instr->opc == OPC_META_FI) {
- struct ir3_instruction *src;
-
- foreach_ssa_src_n(src, i, instr) {
- dump_link2(ctx, src, target, defer);
- printdef(ctx, defer, "[label=\".%c\"]",
- "xyzw"[i & 0x3]);
- }
- } else if (instr->opc == OPC_META_OUTPUT) {
- printdef(ctx, defer, "output%lx:<out%u>:w -> %s",
- PTRID(instr->inout.block),
- instr->regs[0]->num, target);
- } else if (instr->opc == OPC_META_PHI) {
- /* treat like a normal instruction: */
- printdef(ctx, defer, "instr%lx:<dst0> -> %s", PTRID(instr), target);
- }
- } else {
- printdef(ctx, defer, "instr%lx:<dst0> -> %s", PTRID(instr), target);
- }
-}
-
-static void dump_link(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr,
- struct ir3_block *block, const char *target)
-{
- bool defer = instr->block != block;
- dump_link2(ctx, instr, target, defer);
- printdef(ctx, defer, "\n");
-}
-
-static struct ir3_register *follow_flow(struct ir3_register *reg)
-{
- if (reg->flags & IR3_REG_SSA) {
- struct ir3_instruction *instr = reg->instr;
- /* go with the flow.. */
- if (is_meta(instr) && (instr->opc == OPC_META_FLOW))
- return instr->regs[1];
- }
- return reg;
-}
-
-static void ir3_instr_dump(struct ir3_dump_ctx *ctx,
- struct ir3_instruction *instr)
-{
- struct ir3_register *src;
-
- fprintf(ctx->f, "instr%lx [shape=record,style=filled,fillcolor=lightgrey,label=\"{",
- PTRID(instr));
- dump_instr_name(ctx, instr);
-
- /* destination register: */
- fprintf(ctx->f, "|<dst0>");
-
- /* source register(s): */
- foreach_src_n(src, i, instr) {
- struct ir3_register *reg = follow_flow(src);
-
- fprintf(ctx->f, "|");
-
- if (reg->flags & IR3_REG_SSA)
- fprintf(ctx->f, "<src%u> ", i);
-
- dump_reg_name(ctx, reg, true);
- }
-
- fprintf(ctx->f, "}\"];\n");
-
- /* and recursively dump dependent instructions: */
- foreach_src_n(src, i, instr) {
- struct ir3_register *reg = follow_flow(src);
- char target[32]; /* link target */
-
- if (!(reg->flags & IR3_REG_SSA))
- continue;
-
- snprintf(target, sizeof(target), "instr%lx:<src%u>",
- PTRID(instr), i);
-
- dump_instr(ctx, reg->instr);
- dump_link(ctx, reg->instr, instr->block, target);
- }
-}
-
-static void ir3_block_dump(struct ir3_dump_ctx *ctx,
- struct ir3_block *block, const char *name)
-{
- unsigned i, n;
-
- n = edge_buf.n;
-
- fprintf(ctx->f, "subgraph cluster%lx {\n", PTRID(block));
- fprintf(ctx->f, "label=\"%s\";\n", name);
-
- /* draw inputs: */
- fprintf(ctx->f, "input%lx [shape=record,label=\"inputs", PTRID(block));
- for (i = 0; i < block->ninputs; i++)
- if (block->inputs[i])
- fprintf(ctx->f, "|<in%u> i%u.%c", i, (i >> 2), "xyzw"[i & 0x3]);
- fprintf(ctx->f, "\"];\n");
-
- /* draw instruction graph: */
- for (i = 0; i < block->noutputs; i++)
- if (block->outputs[i])
- dump_instr(ctx, block->outputs[i]);
-
- /* draw outputs: */
- fprintf(ctx->f, "output%lx [shape=record,label=\"outputs", PTRID(block));
- for (i = 0; i < block->noutputs; i++)
- fprintf(ctx->f, "|<out%u> o%u.%c", i, (i >> 2), "xyzw"[i & 0x3]);
- fprintf(ctx->f, "\"];\n");
-
- /* and links to outputs: */
- for (i = 0; i < block->noutputs; i++) {
- char target[32]; /* link target */
-
- /* NOTE: there could be outputs that are never assigned,
- * so skip them
- */
- if (!block->outputs[i])
- continue;
-
- snprintf(target, sizeof(target), "output%lx:<out%u>:e",
- PTRID(block), i);
-
- dump_link(ctx, block->outputs[i], block, target);
- }
-
- fprintf(ctx->f, "}\n");
-
- /* and links to inputs: */
- if (block->parent) {
- for (i = 0; i < block->ninputs; i++) {
- char target[32]; /* link target */
-
- if (!block->inputs[i])
- continue;
-
- dump_instr(ctx, block->inputs[i]);
-
- snprintf(target, sizeof(target), "input%lx:<in%u>:e",
- PTRID(block), i);
-
- dump_link(ctx, block->inputs[i], block, target);
- }
- }
-
- /* dump deferred edges: */
- if (edge_buf.n > n) {
- fprintf(ctx->f, "%*s", edge_buf.n - n, &edge_buf.buf[n]);
- edge_buf.n = n;
- }
-}
-
-void ir3_dump(struct ir3 *shader, const char *name,
- struct ir3_block *block /* XXX maybe 'block' ptr should move to ir3? */,
- FILE *f)
-{
- struct ir3_dump_ctx ctx = {
- .f = f,
- };
- ir3_clear_mark(shader);
- fprintf(ctx.f, "digraph G {\n");
- fprintf(ctx.f, "rankdir=RL;\n");
- fprintf(ctx.f, "nodesep=0.25;\n");
- fprintf(ctx.f, "ranksep=1.5;\n");
- ir3_block_dump(&ctx, block, name);
- fprintf(ctx.f, "}\n");
-}
-
-/*
- * For Debugging:
- */
-
-void
-ir3_dump_instr_single(struct ir3_instruction *instr)
-{
- struct ir3_dump_ctx ctx = {
- .f = stdout,
- .verbose = true,
- };
- unsigned i;
-
- dump_instr_name(&ctx, instr);
- for (i = 0; i < instr->regs_count; i++) {
- struct ir3_register *reg = instr->regs[i];
- printf(i ? ", " : " ");
- dump_reg_name(&ctx, reg, !!i);
- }
-
- if (instr->address) {
- fprintf(ctx.f, ", address=_");
- fprintf(ctx.f, "[");
- dump_instr_name(&ctx, instr->address);
- fprintf(ctx.f, "]");
- }
-
- if (instr->fanin) {
- fprintf(ctx.f, ", fanin=_");
- fprintf(ctx.f, "[");
- dump_instr_name(&ctx, instr->fanin);
- fprintf(ctx.f, "]");
- }
-
- if (is_meta(instr)) {
- if (instr->opc == OPC_META_FO) {
- printf(", off=%d", instr->fo.off);
- } else if ((instr->opc == OPC_META_FI) && instr->fi.aid) {
- printf(", aid=%d", instr->fi.aid);
- }
- }
-
- printf("\n");
-}
-
-void
-ir3_dump_instr_list(struct ir3_instruction *instr)
-{
- struct ir3_block *block = instr->block;
- unsigned n = 0;
-
- while (instr) {
- ir3_dump_instr_single(instr);
- if (!is_meta(instr))
- n++;
- instr = instr->next;
- }
- printf("%u instructions\n", n);
-
- for (n = 0; n < block->noutputs; n++) {
- if (!block->outputs[n])
- continue;
- printf("out%d: ", n);
- ir3_dump_instr_single(block->outputs[n]);
- }
-}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_print.c b/src/gallium/drivers/freedreno/ir3/ir3_print.c
new file mode 100644
index 00000000000..a5c5d3c8efa
--- /dev/null
+++ b/src/gallium/drivers/freedreno/ir3/ir3_print.c
@@ -0,0 +1,210 @@
+/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
+
+/*
+ * Copyright (C) 2014 Rob Clark <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Rob Clark <[email protected]>
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "ir3.h"
+
+#define PTRID(x) ((unsigned long)(x))
+
+static void print_instr_name(struct ir3_instruction *instr)
+{
+#ifdef DEBUG
+ printf("%04u:", instr->serialno);
+#endif
+ printf("%03u: ", instr->depth);
+
+ if (instr->flags & IR3_INSTR_SY)
+ printf("(sy)");
+ if (instr->flags & IR3_INSTR_SS)
+ printf("(ss)");
+
+ if (is_meta(instr)) {
+ switch(instr->opc) {
+ case OPC_META_PHI:
+ printf("&#934;");
+ break;
+ default:
+ /* shouldn't hit here.. just for debugging: */
+ switch (instr->opc) {
+ case OPC_META_INPUT: printf("_meta:in"); break;
+ case OPC_META_OUTPUT: printf("_meta:out"); break;
+ case OPC_META_FO: printf("_meta:fo"); break;
+ case OPC_META_FI: printf("_meta:fi"); break;
+ case OPC_META_FLOW: printf("_meta:flow"); break;
+
+ default: printf("_meta:%d", instr->opc); break;
+ }
+ break;
+ }
+ } else if (instr->category == 1) {
+ static const char *type[] = {
+ [TYPE_F16] = "f16",
+ [TYPE_F32] = "f32",
+ [TYPE_U16] = "u16",
+ [TYPE_U32] = "u32",
+ [TYPE_S16] = "s16",
+ [TYPE_S32] = "s32",
+ [TYPE_U8] = "u8",
+ [TYPE_S8] = "s8",
+ };
+ if (instr->cat1.src_type == instr->cat1.dst_type)
+ printf("mov");
+ else
+ printf("cov");
+ printf(".%s%s", type[instr->cat1.src_type], type[instr->cat1.dst_type]);
+ } else {
+ printf("%s", ir3_instr_name(instr));
+ if (instr->flags & IR3_INSTR_3D)
+ printf(".3d");
+ if (instr->flags & IR3_INSTR_A)
+ printf(".a");
+ if (instr->flags & IR3_INSTR_O)
+ printf(".o");
+ if (instr->flags & IR3_INSTR_P)
+ printf(".p");
+ if (instr->flags & IR3_INSTR_S)
+ printf(".s");
+ if (instr->flags & IR3_INSTR_S2EN)
+ printf(".s2en");
+ }
+}
+
+static void print_reg_name(struct ir3_register *reg, bool followssa)
+{
+ if ((reg->flags & (IR3_REG_FABS | IR3_REG_SABS)) &&
+ (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT)))
+ printf("(absneg)");
+ else if (reg->flags & (IR3_REG_FNEG | IR3_REG_SNEG | IR3_REG_BNOT))
+ printf("(neg)");
+ else if (reg->flags & (IR3_REG_FABS | IR3_REG_SABS))
+ printf("(abs)");
+
+ if (reg->flags & IR3_REG_IMMED) {
+ printf("imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val);
+ } else if (reg->flags & IR3_REG_SSA) {
+ printf("_");
+ if (followssa) {
+ printf("[");
+ print_instr_name(reg->instr);
+ printf("]");
+ }
+ } else if (reg->flags & IR3_REG_RELATIV) {
+ if (reg->flags & IR3_REG_HALF)
+ printf("h");
+ if (reg->flags & IR3_REG_CONST)
+ printf("c<a0.x + %u>", reg->num);
+ else
+ printf("\x1b[0;31mr<a0.x + %u>\x1b[0m (%u)", reg->num, reg->size);
+ } else {
+ if (reg->flags & IR3_REG_HALF)
+ printf("h");
+ if (reg->flags & IR3_REG_CONST)
+ printf("c%u.%c", reg_num(reg), "xyzw"[reg_comp(reg)]);
+ else
+ printf("\x1b[0;31mr%u.%c\x1b[0m", reg_num(reg), "xyzw"[reg_comp(reg)]);
+ }
+}
+
+static void
+tab(int lvl)
+{
+ for (int i = 0; i < lvl; i++)
+ printf("\t");
+}
+
+static void
+print_instr(struct ir3_instruction *instr, int lvl)
+{
+ unsigned i;
+
+ tab(lvl);
+
+ print_instr_name(instr);
+ for (i = 0; i < instr->regs_count; i++) {
+ struct ir3_register *reg = instr->regs[i];
+ printf(i ? ", " : " ");
+ print_reg_name(reg, !!i);
+ }
+
+ if (instr->address) {
+ printf(", address=_");
+ printf("[");
+ print_instr_name(instr->address);
+ printf("]");
+ }
+
+ if (instr->fanin) {
+ printf(", fanin=_");
+ printf("[");
+ print_instr_name(instr->fanin);
+ printf("]");
+ }
+
+ if (is_meta(instr)) {
+ if (instr->opc == OPC_META_FO) {
+ printf(", off=%d", instr->fo.off);
+ } else if ((instr->opc == OPC_META_FI) && instr->fi.aid) {
+ printf(", aid=%d", instr->fi.aid);
+ }
+ }
+
+ printf("\n");
+}
+
+void ir3_print_instr(struct ir3_instruction *instr)
+{
+ print_instr(instr, 0);
+}
+
+static void
+print_block(struct ir3_block *block, int lvl)
+{
+ struct ir3_instruction *instr;
+ tab(lvl); printf("block {\n");
+ for (instr = block->head; instr; instr = instr->next) {
+ print_instr(instr, lvl+1);
+ }
+ tab(lvl); printf("}\n");
+}
+
+void
+ir3_print(struct ir3 *ir)
+{
+ struct ir3_block *block = ir->block;
+
+ print_block(block, 0);
+
+ for (unsigned i = 0; i < block->noutputs; i++) {
+ if (!block->outputs[i])
+ continue;
+ printf("out%d: ", i);
+ print_instr(block->outputs[i], 0);
+ }
+}
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_ra.c b/src/gallium/drivers/freedreno/ir3/ir3_ra.c
index a4235a77a15..501352515b5 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_ra.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_ra.c
@@ -78,14 +78,14 @@ struct ir3_ra_ctx {
#define ra_dump_list(msg, n) do { \
if (ra_debug) { \
debug_printf("-- " msg); \
- ir3_dump_instr_list(n); \
+ ir3_print(n->block->shader); \
} \
} while (0)
#define ra_dump_instr(msg, n) do { \
if (ra_debug) { \
debug_printf(">> " msg); \
- ir3_dump_instr_single(n); \
+ ir3_print_instr(n); \
} \
} while (0)