1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
4 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * Rob Clark <robclark@freedesktop.org>
29 #ifndef IR3_VISITOR_H_
30 #define IR3_VISITOR_H_
33 * Visitor which follows dst to src relationships between instructions,
34 * first visiting the dst (writer) instruction, followed by src (reader)
37 * TODO maybe we want multiple different visitors to walk the
38 * graph in different ways?
43 typedef void (*ir3_visit_instr_func
)(struct ir3_visitor
*v
,
44 struct ir3_instruction
*instr
);
46 typedef void (*ir3_visit_reg_func
)(struct ir3_visitor
*v
,
47 struct ir3_instruction
*instr
, struct ir3_register
*reg
);
49 struct ir3_visitor_funcs
{
50 ir3_visit_instr_func instr
; // TODO do we need??
52 ir3_visit_reg_func dst_shader_input
;
53 ir3_visit_reg_func dst_block_input
;
54 ir3_visit_reg_func dst_fanout
;
55 ir3_visit_reg_func dst_fanin
;
56 ir3_visit_reg_func dst
;
58 ir3_visit_reg_func src_block_input
;
59 ir3_visit_reg_func src_fanout
;
60 ir3_visit_reg_func src_fanin
;
61 ir3_visit_reg_func src
;
65 const struct ir3_visitor_funcs
*funcs
;
69 #include "util/u_debug.h"
71 static void visit_instr_dst(struct ir3_visitor
*v
,
72 struct ir3_instruction
*instr
)
74 struct ir3_register
*reg
= instr
->regs
[0];
79 if (instr
->regs_count
== 1)
80 v
->funcs
->dst_shader_input(v
, instr
, reg
);
82 v
->funcs
->dst_block_input(v
, instr
, reg
);
85 v
->funcs
->dst_fanout(v
, instr
, reg
);
88 v
->funcs
->dst_fanin(v
, instr
, reg
);
96 v
->funcs
->dst(v
, instr
, reg
);
99 static void visit_instr_src(struct ir3_visitor
*v
,
100 struct ir3_instruction
*instr
, struct ir3_register
*reg
)
102 if (is_meta(instr
)) {
103 switch (instr
->opc
) {
105 /* shader-input does not have a src, only block input: */
106 debug_assert(instr
->regs_count
== 2);
107 v
->funcs
->src_block_input(v
, instr
, reg
);
110 v
->funcs
->src_fanout(v
, instr
, reg
);
113 v
->funcs
->src_fanin(v
, instr
, reg
);
121 v
->funcs
->src(v
, instr
, reg
);
124 static void ir3_visit_instr(struct ir3_visitor
*v
,
125 struct ir3_instruction
*instr
)
127 struct ir3_instruction
*n
;
129 /* visit instruction that assigns value: */
130 if (instr
->regs_count
> 0)
131 visit_instr_dst(v
, instr
);
133 /* and of any following instructions which read that value: */
135 while (n
&& !v
->error
) {
138 for (i
= 1; i
< n
->regs_count
; i
++) {
139 struct ir3_register
*reg
= n
->regs
[i
];
140 if ((reg
->flags
& IR3_REG_SSA
) && (reg
->instr
== instr
))
141 visit_instr_src(v
, n
, reg
);
148 static void ir3_visit_reg(struct ir3_visitor
*v
,
149 struct ir3_instruction
*instr
, struct ir3_register
*reg
)
154 #endif /* IR3_VISITOR_H_ */