1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (c) 2017 Lima Project
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
12bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
13bf215546Sopenharmony_ci * of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "util/u_math.h"
26bf215546Sopenharmony_ci#include "util/ralloc.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "gpir.h"
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ciconst gpir_op_info gpir_op_infos[] = {
31bf215546Sopenharmony_ci   [gpir_op_unsupported] = {
32bf215546Sopenharmony_ci      .name = "unsupported",
33bf215546Sopenharmony_ci   },
34bf215546Sopenharmony_ci   [gpir_op_mov] = {
35bf215546Sopenharmony_ci      .name = "mov",
36bf215546Sopenharmony_ci      .slots = (int []) {
37bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_MUL1,
38bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_MUL0,
39bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_PASS, GPIR_INSTR_SLOT_COMPLEX,
40bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
41bf215546Sopenharmony_ci      },
42bf215546Sopenharmony_ci   },
43bf215546Sopenharmony_ci   [gpir_op_mul] = {
44bf215546Sopenharmony_ci      .name = "mul",
45bf215546Sopenharmony_ci      .dest_neg = true,
46bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_MUL1, GPIR_INSTR_SLOT_MUL0, GPIR_INSTR_SLOT_END },
47bf215546Sopenharmony_ci   },
48bf215546Sopenharmony_ci   [gpir_op_select] = {
49bf215546Sopenharmony_ci      .name = "select",
50bf215546Sopenharmony_ci      .dest_neg = true,
51bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_MUL0, GPIR_INSTR_SLOT_END },
52bf215546Sopenharmony_ci      .may_consume_two_slots = true,
53bf215546Sopenharmony_ci   },
54bf215546Sopenharmony_ci   [gpir_op_complex1] = {
55bf215546Sopenharmony_ci      .name = "complex1",
56bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_MUL0, GPIR_INSTR_SLOT_END },
57bf215546Sopenharmony_ci      .spillless = true,
58bf215546Sopenharmony_ci      .may_consume_two_slots = true,
59bf215546Sopenharmony_ci   },
60bf215546Sopenharmony_ci   [gpir_op_complex2] = {
61bf215546Sopenharmony_ci      .name = "complex2",
62bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_MUL0, GPIR_INSTR_SLOT_END },
63bf215546Sopenharmony_ci      .spillless = true,
64bf215546Sopenharmony_ci      .schedule_first = true,
65bf215546Sopenharmony_ci   },
66bf215546Sopenharmony_ci   [gpir_op_add] = {
67bf215546Sopenharmony_ci      .name = "add",
68bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
69bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
70bf215546Sopenharmony_ci   },
71bf215546Sopenharmony_ci   [gpir_op_floor] = {
72bf215546Sopenharmony_ci      .name = "floor",
73bf215546Sopenharmony_ci      .src_neg = {true, false, false, false},
74bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
75bf215546Sopenharmony_ci      .spillless = true,
76bf215546Sopenharmony_ci      .may_consume_two_slots = true,
77bf215546Sopenharmony_ci   },
78bf215546Sopenharmony_ci   [gpir_op_sign] = {
79bf215546Sopenharmony_ci      .name = "sign",
80bf215546Sopenharmony_ci      .src_neg = {true, false, false, false},
81bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
82bf215546Sopenharmony_ci      .spillless = true,
83bf215546Sopenharmony_ci      .may_consume_two_slots = true,
84bf215546Sopenharmony_ci   },
85bf215546Sopenharmony_ci   [gpir_op_ge] = {
86bf215546Sopenharmony_ci      .name = "ge",
87bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
88bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
89bf215546Sopenharmony_ci      .spillless = true,
90bf215546Sopenharmony_ci      .may_consume_two_slots = true,
91bf215546Sopenharmony_ci   },
92bf215546Sopenharmony_ci   [gpir_op_lt] = {
93bf215546Sopenharmony_ci      .name = "lt",
94bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
95bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
96bf215546Sopenharmony_ci      .spillless = true,
97bf215546Sopenharmony_ci      .may_consume_two_slots = true,
98bf215546Sopenharmony_ci   },
99bf215546Sopenharmony_ci   [gpir_op_min] = {
100bf215546Sopenharmony_ci      .name = "min",
101bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
102bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
103bf215546Sopenharmony_ci      .spillless = true,
104bf215546Sopenharmony_ci      .may_consume_two_slots = true,
105bf215546Sopenharmony_ci   },
106bf215546Sopenharmony_ci   [gpir_op_max] = {
107bf215546Sopenharmony_ci      .name = "max",
108bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
109bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
110bf215546Sopenharmony_ci      .spillless = true,
111bf215546Sopenharmony_ci      .may_consume_two_slots = true,
112bf215546Sopenharmony_ci   },
113bf215546Sopenharmony_ci   [gpir_op_abs] = {
114bf215546Sopenharmony_ci      .name = "abs",
115bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
116bf215546Sopenharmony_ci   },
117bf215546Sopenharmony_ci   [gpir_op_neg] = {
118bf215546Sopenharmony_ci      .name = "neg",
119bf215546Sopenharmony_ci      .slots = (int []) {
120bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_MUL1,
121bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_MUL0,
122bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
123bf215546Sopenharmony_ci      },
124bf215546Sopenharmony_ci   },
125bf215546Sopenharmony_ci   [gpir_op_not] = {
126bf215546Sopenharmony_ci      .name = "not",
127bf215546Sopenharmony_ci      .src_neg = {true, true, false, false},
128bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END },
129bf215546Sopenharmony_ci   },
130bf215546Sopenharmony_ci   [gpir_op_eq] = {
131bf215546Sopenharmony_ci      .name = "eq",
132bf215546Sopenharmony_ci      .slots = (int []) {
133bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END
134bf215546Sopenharmony_ci      },
135bf215546Sopenharmony_ci   },
136bf215546Sopenharmony_ci   [gpir_op_ne] = {
137bf215546Sopenharmony_ci      .name = "ne",
138bf215546Sopenharmony_ci      .slots = (int []) {
139bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_ADD0, GPIR_INSTR_SLOT_ADD1, GPIR_INSTR_SLOT_END
140bf215546Sopenharmony_ci      },
141bf215546Sopenharmony_ci   },
142bf215546Sopenharmony_ci   [gpir_op_clamp_const] = {
143bf215546Sopenharmony_ci      .name = "clamp_const",
144bf215546Sopenharmony_ci   },
145bf215546Sopenharmony_ci   [gpir_op_preexp2] = {
146bf215546Sopenharmony_ci      .name = "preexp2",
147bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_PASS, GPIR_INSTR_SLOT_END },
148bf215546Sopenharmony_ci      .spillless = true,
149bf215546Sopenharmony_ci      .schedule_first = true,
150bf215546Sopenharmony_ci   },
151bf215546Sopenharmony_ci   [gpir_op_postlog2] = {
152bf215546Sopenharmony_ci      .name = "postlog2",
153bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_PASS, GPIR_INSTR_SLOT_END },
154bf215546Sopenharmony_ci   },
155bf215546Sopenharmony_ci   [gpir_op_exp2_impl] = {
156bf215546Sopenharmony_ci      .name = "exp2_impl",
157bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_COMPLEX, GPIR_INSTR_SLOT_END },
158bf215546Sopenharmony_ci      .spillless = true,
159bf215546Sopenharmony_ci      .schedule_first = true,
160bf215546Sopenharmony_ci   },
161bf215546Sopenharmony_ci   [gpir_op_log2_impl] = {
162bf215546Sopenharmony_ci      .name = "log2_impl",
163bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_COMPLEX, GPIR_INSTR_SLOT_END },
164bf215546Sopenharmony_ci      .spillless = true,
165bf215546Sopenharmony_ci      .schedule_first = true,
166bf215546Sopenharmony_ci   },
167bf215546Sopenharmony_ci   [gpir_op_rcp_impl] = {
168bf215546Sopenharmony_ci      .name = "rcp_impl",
169bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_COMPLEX, GPIR_INSTR_SLOT_END },
170bf215546Sopenharmony_ci      .spillless = true,
171bf215546Sopenharmony_ci      .schedule_first = true,
172bf215546Sopenharmony_ci   },
173bf215546Sopenharmony_ci   [gpir_op_rsqrt_impl] = {
174bf215546Sopenharmony_ci      .name = "rsqrt_impl",
175bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_COMPLEX, GPIR_INSTR_SLOT_END },
176bf215546Sopenharmony_ci      .spillless = true,
177bf215546Sopenharmony_ci      .schedule_first = true,
178bf215546Sopenharmony_ci   },
179bf215546Sopenharmony_ci   [gpir_op_load_uniform] = {
180bf215546Sopenharmony_ci      .name = "ld_uni",
181bf215546Sopenharmony_ci      .slots = (int []) {
182bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_MEM_LOAD0, GPIR_INSTR_SLOT_MEM_LOAD1,
183bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_MEM_LOAD2, GPIR_INSTR_SLOT_MEM_LOAD3,
184bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
185bf215546Sopenharmony_ci      },
186bf215546Sopenharmony_ci      .type = gpir_node_type_load,
187bf215546Sopenharmony_ci   },
188bf215546Sopenharmony_ci   [gpir_op_load_temp] = {
189bf215546Sopenharmony_ci      .name = "ld_tmp",
190bf215546Sopenharmony_ci      .type = gpir_node_type_load,
191bf215546Sopenharmony_ci   },
192bf215546Sopenharmony_ci   [gpir_op_load_attribute] = {
193bf215546Sopenharmony_ci      .name = "ld_att",
194bf215546Sopenharmony_ci      .slots = (int []) {
195bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG0_LOAD0, GPIR_INSTR_SLOT_REG0_LOAD1,
196bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG0_LOAD2, GPIR_INSTR_SLOT_REG0_LOAD3,
197bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
198bf215546Sopenharmony_ci      },
199bf215546Sopenharmony_ci      .type = gpir_node_type_load,
200bf215546Sopenharmony_ci   },
201bf215546Sopenharmony_ci   [gpir_op_load_reg] = {
202bf215546Sopenharmony_ci      .name = "ld_reg",
203bf215546Sopenharmony_ci      .slots = (int []) {
204bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG1_LOAD0, GPIR_INSTR_SLOT_REG1_LOAD1,
205bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG1_LOAD2, GPIR_INSTR_SLOT_REG1_LOAD3,
206bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG0_LOAD0, GPIR_INSTR_SLOT_REG0_LOAD1,
207bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_REG0_LOAD2, GPIR_INSTR_SLOT_REG0_LOAD3,
208bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
209bf215546Sopenharmony_ci      },
210bf215546Sopenharmony_ci      .type = gpir_node_type_load,
211bf215546Sopenharmony_ci      .spillless = true,
212bf215546Sopenharmony_ci   },
213bf215546Sopenharmony_ci   [gpir_op_store_temp] = {
214bf215546Sopenharmony_ci      .name = "st_tmp",
215bf215546Sopenharmony_ci      .type = gpir_node_type_store,
216bf215546Sopenharmony_ci   },
217bf215546Sopenharmony_ci   [gpir_op_store_reg] = {
218bf215546Sopenharmony_ci      .name = "st_reg",
219bf215546Sopenharmony_ci      .slots = (int []) {
220bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_STORE0, GPIR_INSTR_SLOT_STORE1,
221bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_STORE2, GPIR_INSTR_SLOT_STORE3,
222bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
223bf215546Sopenharmony_ci      },
224bf215546Sopenharmony_ci      .type = gpir_node_type_store,
225bf215546Sopenharmony_ci      .spillless = true,
226bf215546Sopenharmony_ci   },
227bf215546Sopenharmony_ci   [gpir_op_store_varying] = {
228bf215546Sopenharmony_ci      .name = "st_var",
229bf215546Sopenharmony_ci      .slots = (int []) {
230bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_STORE0, GPIR_INSTR_SLOT_STORE1,
231bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_STORE2, GPIR_INSTR_SLOT_STORE3,
232bf215546Sopenharmony_ci         GPIR_INSTR_SLOT_END
233bf215546Sopenharmony_ci      },
234bf215546Sopenharmony_ci      .type = gpir_node_type_store,
235bf215546Sopenharmony_ci      .spillless = true,
236bf215546Sopenharmony_ci   },
237bf215546Sopenharmony_ci   [gpir_op_store_temp_load_off0] = {
238bf215546Sopenharmony_ci      .name = "st_of0",
239bf215546Sopenharmony_ci      .type = gpir_node_type_store,
240bf215546Sopenharmony_ci   },
241bf215546Sopenharmony_ci   [gpir_op_store_temp_load_off1] = {
242bf215546Sopenharmony_ci      .name = "st_of1",
243bf215546Sopenharmony_ci      .type = gpir_node_type_store,
244bf215546Sopenharmony_ci   },
245bf215546Sopenharmony_ci   [gpir_op_store_temp_load_off2] = {
246bf215546Sopenharmony_ci      .name = "st_of2",
247bf215546Sopenharmony_ci      .type = gpir_node_type_store,
248bf215546Sopenharmony_ci   },
249bf215546Sopenharmony_ci   [gpir_op_branch_cond] = {
250bf215546Sopenharmony_ci      .name = "branch_cond",
251bf215546Sopenharmony_ci      .type = gpir_node_type_branch,
252bf215546Sopenharmony_ci      .schedule_first = true,
253bf215546Sopenharmony_ci      .slots = (int []) { GPIR_INSTR_SLOT_PASS, GPIR_INSTR_SLOT_END },
254bf215546Sopenharmony_ci   },
255bf215546Sopenharmony_ci   [gpir_op_const] = {
256bf215546Sopenharmony_ci      .name = "const",
257bf215546Sopenharmony_ci      .type = gpir_node_type_const,
258bf215546Sopenharmony_ci   },
259bf215546Sopenharmony_ci   [gpir_op_exp2] = {
260bf215546Sopenharmony_ci      .name = "exp2",
261bf215546Sopenharmony_ci   },
262bf215546Sopenharmony_ci   [gpir_op_log2] = {
263bf215546Sopenharmony_ci      .name = "log2",
264bf215546Sopenharmony_ci   },
265bf215546Sopenharmony_ci   [gpir_op_rcp] = {
266bf215546Sopenharmony_ci      .name = "rcp",
267bf215546Sopenharmony_ci   },
268bf215546Sopenharmony_ci   [gpir_op_rsqrt] = {
269bf215546Sopenharmony_ci      .name = "rsqrt",
270bf215546Sopenharmony_ci   },
271bf215546Sopenharmony_ci   [gpir_op_ceil] = {
272bf215546Sopenharmony_ci      .name = "ceil",
273bf215546Sopenharmony_ci   },
274bf215546Sopenharmony_ci   [gpir_op_exp] = {
275bf215546Sopenharmony_ci      .name = "exp",
276bf215546Sopenharmony_ci   },
277bf215546Sopenharmony_ci   [gpir_op_log] = {
278bf215546Sopenharmony_ci      .name = "log",
279bf215546Sopenharmony_ci   },
280bf215546Sopenharmony_ci   [gpir_op_sin] = {
281bf215546Sopenharmony_ci      .name = "sin",
282bf215546Sopenharmony_ci   },
283bf215546Sopenharmony_ci   [gpir_op_cos] = {
284bf215546Sopenharmony_ci      .name = "cos",
285bf215546Sopenharmony_ci   },
286bf215546Sopenharmony_ci   [gpir_op_tan] = {
287bf215546Sopenharmony_ci      .name = "tan",
288bf215546Sopenharmony_ci   },
289bf215546Sopenharmony_ci   [gpir_op_dummy_f] = {
290bf215546Sopenharmony_ci      .name = "dummy_f",
291bf215546Sopenharmony_ci      .type = gpir_node_type_alu,
292bf215546Sopenharmony_ci      .spillless = true,
293bf215546Sopenharmony_ci   },
294bf215546Sopenharmony_ci   [gpir_op_dummy_m] = {
295bf215546Sopenharmony_ci      .name = "dummy_m",
296bf215546Sopenharmony_ci      .type = gpir_node_type_alu,
297bf215546Sopenharmony_ci   },
298bf215546Sopenharmony_ci   [gpir_op_branch_uncond] = {
299bf215546Sopenharmony_ci      .name = "branch_uncond",
300bf215546Sopenharmony_ci      .type = gpir_node_type_branch,
301bf215546Sopenharmony_ci   },
302bf215546Sopenharmony_ci};
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_civoid *gpir_node_create(gpir_block *block, gpir_op op)
305bf215546Sopenharmony_ci{
306bf215546Sopenharmony_ci   static const int node_size[] = {
307bf215546Sopenharmony_ci      [gpir_node_type_alu] = sizeof(gpir_alu_node),
308bf215546Sopenharmony_ci      [gpir_node_type_const] = sizeof(gpir_const_node),
309bf215546Sopenharmony_ci      [gpir_node_type_load] = sizeof(gpir_load_node),
310bf215546Sopenharmony_ci      [gpir_node_type_store] = sizeof(gpir_store_node),
311bf215546Sopenharmony_ci      [gpir_node_type_branch] = sizeof(gpir_branch_node),
312bf215546Sopenharmony_ci   };
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci   gpir_node_type type = gpir_op_infos[op].type;
315bf215546Sopenharmony_ci   int size = node_size[type];
316bf215546Sopenharmony_ci   gpir_node *node = rzalloc_size(block, size);
317bf215546Sopenharmony_ci   if (unlikely(!node))
318bf215546Sopenharmony_ci      return NULL;
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci   snprintf(node->name, sizeof(node->name), "new");
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ci   list_inithead(&node->succ_list);
323bf215546Sopenharmony_ci   list_inithead(&node->pred_list);
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ci   node->op = op;
326bf215546Sopenharmony_ci   node->type = type;
327bf215546Sopenharmony_ci   node->index = block->comp->cur_index++;
328bf215546Sopenharmony_ci   node->block = block;
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci   return node;
331bf215546Sopenharmony_ci}
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_cigpir_dep *gpir_node_add_dep(gpir_node *succ, gpir_node *pred, int type)
334bf215546Sopenharmony_ci{
335bf215546Sopenharmony_ci   /* don't add dep for two nodes from different block */
336bf215546Sopenharmony_ci   if (succ->block != pred->block)
337bf215546Sopenharmony_ci      return NULL;
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   /* don't add self loop dep */
340bf215546Sopenharmony_ci   if (succ == pred)
341bf215546Sopenharmony_ci      return NULL;
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_ci   /* don't add duplicated dep */
344bf215546Sopenharmony_ci   gpir_node_foreach_pred(succ, dep) {
345bf215546Sopenharmony_ci      if (dep->pred == pred) {
346bf215546Sopenharmony_ci         /* use stronger dependency */
347bf215546Sopenharmony_ci         if (dep->type > type)
348bf215546Sopenharmony_ci            dep->type = type;
349bf215546Sopenharmony_ci         return dep;
350bf215546Sopenharmony_ci      }
351bf215546Sopenharmony_ci   }
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci   gpir_dep *dep = ralloc(succ, gpir_dep);
354bf215546Sopenharmony_ci   dep->type = type;
355bf215546Sopenharmony_ci   dep->pred = pred;
356bf215546Sopenharmony_ci   dep->succ = succ;
357bf215546Sopenharmony_ci   list_addtail(&dep->pred_link, &succ->pred_list);
358bf215546Sopenharmony_ci   list_addtail(&dep->succ_link, &pred->succ_list);
359bf215546Sopenharmony_ci   return dep;
360bf215546Sopenharmony_ci}
361bf215546Sopenharmony_ci
362bf215546Sopenharmony_civoid gpir_node_remove_dep(gpir_node *succ, gpir_node *pred)
363bf215546Sopenharmony_ci{
364bf215546Sopenharmony_ci   gpir_node_foreach_pred(succ, dep) {
365bf215546Sopenharmony_ci      if (dep->pred == pred) {
366bf215546Sopenharmony_ci         list_del(&dep->succ_link);
367bf215546Sopenharmony_ci         list_del(&dep->pred_link);
368bf215546Sopenharmony_ci         ralloc_free(dep);
369bf215546Sopenharmony_ci         return;
370bf215546Sopenharmony_ci      }
371bf215546Sopenharmony_ci   }
372bf215546Sopenharmony_ci}
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_civoid gpir_node_replace_child(gpir_node *parent, gpir_node *old_child,
375bf215546Sopenharmony_ci                             gpir_node *new_child)
376bf215546Sopenharmony_ci{
377bf215546Sopenharmony_ci   if (parent->type == gpir_node_type_alu) {
378bf215546Sopenharmony_ci      gpir_alu_node *alu = gpir_node_to_alu(parent);
379bf215546Sopenharmony_ci      for (int i = 0; i < alu->num_child; i++) {
380bf215546Sopenharmony_ci         if (alu->children[i] == old_child)
381bf215546Sopenharmony_ci            alu->children[i] = new_child;
382bf215546Sopenharmony_ci      }
383bf215546Sopenharmony_ci   }
384bf215546Sopenharmony_ci   else if (parent->type == gpir_node_type_store) {
385bf215546Sopenharmony_ci      gpir_store_node *store = gpir_node_to_store(parent);
386bf215546Sopenharmony_ci      if (store->child == old_child)
387bf215546Sopenharmony_ci         store->child = new_child;
388bf215546Sopenharmony_ci   } else if (parent->type == gpir_node_type_branch) {
389bf215546Sopenharmony_ci      gpir_branch_node *branch = gpir_node_to_branch(parent);
390bf215546Sopenharmony_ci      if (branch->cond == old_child)
391bf215546Sopenharmony_ci         branch->cond = new_child;
392bf215546Sopenharmony_ci   }
393bf215546Sopenharmony_ci}
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_civoid gpir_node_replace_pred(gpir_dep *dep, gpir_node *new_pred)
396bf215546Sopenharmony_ci{
397bf215546Sopenharmony_ci   list_del(&dep->succ_link);
398bf215546Sopenharmony_ci   dep->pred = new_pred;
399bf215546Sopenharmony_ci   list_addtail(&dep->succ_link, &new_pred->succ_list);
400bf215546Sopenharmony_ci}
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_civoid gpir_node_replace_succ(gpir_node *dst, gpir_node *src)
403bf215546Sopenharmony_ci{
404bf215546Sopenharmony_ci   gpir_node_foreach_succ_safe(src, dep) {
405bf215546Sopenharmony_ci      if (dep->type != GPIR_DEP_INPUT)
406bf215546Sopenharmony_ci         continue;
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci      gpir_node_replace_pred(dep, dst);
409bf215546Sopenharmony_ci      gpir_node_replace_child(dep->succ, src, dst);
410bf215546Sopenharmony_ci   }
411bf215546Sopenharmony_ci}
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_civoid gpir_node_insert_child(gpir_node *parent, gpir_node *child,
414bf215546Sopenharmony_ci                            gpir_node *insert_child)
415bf215546Sopenharmony_ci{
416bf215546Sopenharmony_ci   gpir_node_foreach_pred(parent, dep) {
417bf215546Sopenharmony_ci      if (dep->pred == child) {
418bf215546Sopenharmony_ci         gpir_node_replace_pred(dep, insert_child);
419bf215546Sopenharmony_ci         gpir_node_replace_child(parent, child, insert_child);
420bf215546Sopenharmony_ci         break;
421bf215546Sopenharmony_ci      }
422bf215546Sopenharmony_ci   }
423bf215546Sopenharmony_ci}
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_civoid gpir_node_delete(gpir_node *node)
426bf215546Sopenharmony_ci{
427bf215546Sopenharmony_ci   gpir_node_foreach_succ_safe(node, dep) {
428bf215546Sopenharmony_ci      list_del(&dep->succ_link);
429bf215546Sopenharmony_ci      list_del(&dep->pred_link);
430bf215546Sopenharmony_ci      ralloc_free(dep);
431bf215546Sopenharmony_ci   }
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci   gpir_node_foreach_pred_safe(node, dep) {
434bf215546Sopenharmony_ci      list_del(&dep->succ_link);
435bf215546Sopenharmony_ci      list_del(&dep->pred_link);
436bf215546Sopenharmony_ci      ralloc_free(dep);
437bf215546Sopenharmony_ci   }
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   list_del(&node->list);
440bf215546Sopenharmony_ci   ralloc_free(node);
441bf215546Sopenharmony_ci}
442bf215546Sopenharmony_ci
443bf215546Sopenharmony_cistatic void gpir_node_print_node(gpir_node *node, int type, int space)
444bf215546Sopenharmony_ci{
445bf215546Sopenharmony_ci   static char *dep_name[] = {
446bf215546Sopenharmony_ci      [GPIR_DEP_INPUT] = "input",
447bf215546Sopenharmony_ci      [GPIR_DEP_OFFSET] = "offset",
448bf215546Sopenharmony_ci      [GPIR_DEP_READ_AFTER_WRITE] = "RaW",
449bf215546Sopenharmony_ci      [GPIR_DEP_WRITE_AFTER_READ] = "WaR",
450bf215546Sopenharmony_ci   };
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci   for (int i = 0; i < space; i++)
453bf215546Sopenharmony_ci      printf(" ");
454bf215546Sopenharmony_ci   printf("%s%s %d %s %s\n", node->printed && !gpir_node_is_leaf(node) ? "+" : "",
455bf215546Sopenharmony_ci          gpir_op_infos[node->op].name, node->index, node->name, dep_name[type]);
456bf215546Sopenharmony_ci
457bf215546Sopenharmony_ci   if (!node->printed) {
458bf215546Sopenharmony_ci      gpir_node_foreach_pred(node, dep) {
459bf215546Sopenharmony_ci         gpir_node_print_node(dep->pred, dep->type, space + 2);
460bf215546Sopenharmony_ci      }
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci      node->printed = true;
463bf215546Sopenharmony_ci   }
464bf215546Sopenharmony_ci}
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_civoid gpir_node_print_prog_dep(gpir_compiler *comp)
467bf215546Sopenharmony_ci{
468bf215546Sopenharmony_ci   if (!(lima_debug & LIMA_DEBUG_GP))
469bf215546Sopenharmony_ci      return;
470bf215546Sopenharmony_ci
471bf215546Sopenharmony_ci   list_for_each_entry(gpir_block, block, &comp->block_list, list) {
472bf215546Sopenharmony_ci      list_for_each_entry(gpir_node, node, &block->node_list, list) {
473bf215546Sopenharmony_ci         node->printed = false;
474bf215546Sopenharmony_ci      }
475bf215546Sopenharmony_ci   }
476bf215546Sopenharmony_ci
477bf215546Sopenharmony_ci   printf("======== node prog dep ========\n");
478bf215546Sopenharmony_ci   list_for_each_entry(gpir_block, block, &comp->block_list, list) {
479bf215546Sopenharmony_ci      list_for_each_entry(gpir_node, node, &block->node_list, list) {
480bf215546Sopenharmony_ci         if (gpir_node_is_root(node))
481bf215546Sopenharmony_ci            gpir_node_print_node(node, GPIR_DEP_INPUT, 0);
482bf215546Sopenharmony_ci      }
483bf215546Sopenharmony_ci      printf("----------------------------\n");
484bf215546Sopenharmony_ci   }
485bf215546Sopenharmony_ci}
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_civoid gpir_node_print_prog_seq(gpir_compiler *comp)
488bf215546Sopenharmony_ci{
489bf215546Sopenharmony_ci   if (!(lima_debug & LIMA_DEBUG_GP))
490bf215546Sopenharmony_ci      return;
491bf215546Sopenharmony_ci
492bf215546Sopenharmony_ci   int index = 0;
493bf215546Sopenharmony_ci   printf("======== node prog seq ========\n");
494bf215546Sopenharmony_ci   list_for_each_entry(gpir_block, block, &comp->block_list, list) {
495bf215546Sopenharmony_ci      list_for_each_entry(gpir_node, node, &block->node_list, list) {
496bf215546Sopenharmony_ci         printf("%03d: %s %d %s pred", index++, gpir_op_infos[node->op].name,
497bf215546Sopenharmony_ci                node->index, node->name);
498bf215546Sopenharmony_ci         gpir_node_foreach_pred(node, dep) {
499bf215546Sopenharmony_ci            printf(" %d", dep->pred->index);
500bf215546Sopenharmony_ci         }
501bf215546Sopenharmony_ci         printf(" succ");
502bf215546Sopenharmony_ci         gpir_node_foreach_succ(node, dep) {
503bf215546Sopenharmony_ci            printf(" %d", dep->succ->index);
504bf215546Sopenharmony_ci         }
505bf215546Sopenharmony_ci         printf("\n");
506bf215546Sopenharmony_ci      }
507bf215546Sopenharmony_ci      printf("----------------------------\n");
508bf215546Sopenharmony_ci   }
509bf215546Sopenharmony_ci}
510