1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (c) 2017 Lima Project 3bf215546Sopenharmony_ci * Copyright (c) 2013 Connor Abbott 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 6bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 7bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 8bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 13bf215546Sopenharmony_ci * all copies or substantial portions 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 NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * 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 FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21bf215546Sopenharmony_ci * THE SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#ifndef LIMA_IR_GP_GPIR_H 26bf215546Sopenharmony_ci#define LIMA_IR_GP_GPIR_H 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "util/list.h" 29bf215546Sopenharmony_ci#include "util/u_math.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "ir/lima_ir.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci/* list of operations that a node can do. */ 34bf215546Sopenharmony_citypedef enum { 35bf215546Sopenharmony_ci gpir_op_unsupported = 0, 36bf215546Sopenharmony_ci gpir_op_mov, 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci /* mul ops */ 39bf215546Sopenharmony_ci gpir_op_mul, 40bf215546Sopenharmony_ci gpir_op_select, 41bf215546Sopenharmony_ci gpir_op_complex1, 42bf215546Sopenharmony_ci gpir_op_complex2, 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci /* add ops */ 45bf215546Sopenharmony_ci gpir_op_add, 46bf215546Sopenharmony_ci gpir_op_floor, 47bf215546Sopenharmony_ci gpir_op_sign, 48bf215546Sopenharmony_ci gpir_op_ge, 49bf215546Sopenharmony_ci gpir_op_lt, 50bf215546Sopenharmony_ci gpir_op_min, 51bf215546Sopenharmony_ci gpir_op_max, 52bf215546Sopenharmony_ci gpir_op_abs, 53bf215546Sopenharmony_ci gpir_op_not, 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci /* mul/add ops */ 56bf215546Sopenharmony_ci gpir_op_neg, 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci /* passthrough ops */ 59bf215546Sopenharmony_ci gpir_op_clamp_const, 60bf215546Sopenharmony_ci gpir_op_preexp2, 61bf215546Sopenharmony_ci gpir_op_postlog2, 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci /* complex ops */ 64bf215546Sopenharmony_ci gpir_op_exp2_impl, 65bf215546Sopenharmony_ci gpir_op_log2_impl, 66bf215546Sopenharmony_ci gpir_op_rcp_impl, 67bf215546Sopenharmony_ci gpir_op_rsqrt_impl, 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci /* load/store ops */ 70bf215546Sopenharmony_ci gpir_op_load_uniform, 71bf215546Sopenharmony_ci gpir_op_load_temp, 72bf215546Sopenharmony_ci gpir_op_load_attribute, 73bf215546Sopenharmony_ci gpir_op_load_reg, 74bf215546Sopenharmony_ci gpir_op_store_temp, 75bf215546Sopenharmony_ci gpir_op_store_reg, 76bf215546Sopenharmony_ci gpir_op_store_varying, 77bf215546Sopenharmony_ci gpir_op_store_temp_load_off0, 78bf215546Sopenharmony_ci gpir_op_store_temp_load_off1, 79bf215546Sopenharmony_ci gpir_op_store_temp_load_off2, 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci /* branch */ 82bf215546Sopenharmony_ci gpir_op_branch_cond, 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci /* const (emulated) */ 85bf215546Sopenharmony_ci gpir_op_const, 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci /* emulated ops */ 88bf215546Sopenharmony_ci gpir_op_exp2, 89bf215546Sopenharmony_ci gpir_op_log2, 90bf215546Sopenharmony_ci gpir_op_rcp, 91bf215546Sopenharmony_ci gpir_op_rsqrt, 92bf215546Sopenharmony_ci gpir_op_ceil, 93bf215546Sopenharmony_ci gpir_op_exp, 94bf215546Sopenharmony_ci gpir_op_log, 95bf215546Sopenharmony_ci gpir_op_sin, 96bf215546Sopenharmony_ci gpir_op_cos, 97bf215546Sopenharmony_ci gpir_op_tan, 98bf215546Sopenharmony_ci gpir_op_branch_uncond, 99bf215546Sopenharmony_ci gpir_op_eq, 100bf215546Sopenharmony_ci gpir_op_ne, 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci /* auxiliary ops */ 103bf215546Sopenharmony_ci gpir_op_dummy_f, 104bf215546Sopenharmony_ci gpir_op_dummy_m, 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci gpir_op_num, 107bf215546Sopenharmony_ci} gpir_op; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_citypedef enum { 110bf215546Sopenharmony_ci gpir_node_type_alu, 111bf215546Sopenharmony_ci gpir_node_type_const, 112bf215546Sopenharmony_ci gpir_node_type_load, 113bf215546Sopenharmony_ci gpir_node_type_store, 114bf215546Sopenharmony_ci gpir_node_type_branch, 115bf215546Sopenharmony_ci} gpir_node_type; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_citypedef struct { 118bf215546Sopenharmony_ci char *name; 119bf215546Sopenharmony_ci bool dest_neg; 120bf215546Sopenharmony_ci bool src_neg[4]; 121bf215546Sopenharmony_ci int *slots; 122bf215546Sopenharmony_ci gpir_node_type type; 123bf215546Sopenharmony_ci bool spillless; 124bf215546Sopenharmony_ci bool schedule_first; 125bf215546Sopenharmony_ci bool may_consume_two_slots; 126bf215546Sopenharmony_ci} gpir_op_info; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ciextern const gpir_op_info gpir_op_infos[]; 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_citypedef struct { 131bf215546Sopenharmony_ci enum { 132bf215546Sopenharmony_ci GPIR_DEP_INPUT, /* def is the input of use */ 133bf215546Sopenharmony_ci GPIR_DEP_OFFSET, /* def is the offset of use (i.e. temp store) */ 134bf215546Sopenharmony_ci GPIR_DEP_READ_AFTER_WRITE, 135bf215546Sopenharmony_ci GPIR_DEP_WRITE_AFTER_READ, 136bf215546Sopenharmony_ci } type; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci /* node execute before succ */ 139bf215546Sopenharmony_ci struct gpir_node *pred; 140bf215546Sopenharmony_ci /* node execute after pred */ 141bf215546Sopenharmony_ci struct gpir_node *succ; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci /* for node pred_list */ 144bf215546Sopenharmony_ci struct list_head pred_link; 145bf215546Sopenharmony_ci /* for ndoe succ_list */ 146bf215546Sopenharmony_ci struct list_head succ_link; 147bf215546Sopenharmony_ci} gpir_dep; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_cistruct gpir_instr; 150bf215546Sopenharmony_cistruct gpir_store_node; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_citypedef struct gpir_node { 153bf215546Sopenharmony_ci struct list_head list; 154bf215546Sopenharmony_ci gpir_op op; 155bf215546Sopenharmony_ci gpir_node_type type; 156bf215546Sopenharmony_ci int index; 157bf215546Sopenharmony_ci char name[16]; 158bf215546Sopenharmony_ci bool printed; 159bf215546Sopenharmony_ci struct gpir_block *block; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci /* for nodes relationship */ 162bf215546Sopenharmony_ci /* for node who uses this node (successor) */ 163bf215546Sopenharmony_ci struct list_head succ_list; 164bf215546Sopenharmony_ci /* for node this node uses (predecessor) */ 165bf215546Sopenharmony_ci struct list_head pred_list; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci /* for scheduler and regalloc */ 168bf215546Sopenharmony_ci int value_reg; 169bf215546Sopenharmony_ci union { 170bf215546Sopenharmony_ci struct { 171bf215546Sopenharmony_ci struct gpir_instr *instr; 172bf215546Sopenharmony_ci struct gpir_store_node *physreg_store; 173bf215546Sopenharmony_ci int pos; 174bf215546Sopenharmony_ci int dist; 175bf215546Sopenharmony_ci int index; 176bf215546Sopenharmony_ci bool ready; 177bf215546Sopenharmony_ci bool inserted; 178bf215546Sopenharmony_ci bool max_node, next_max_node; 179bf215546Sopenharmony_ci bool complex_allowed; 180bf215546Sopenharmony_ci } sched; 181bf215546Sopenharmony_ci struct { 182bf215546Sopenharmony_ci int parent_index; 183bf215546Sopenharmony_ci float reg_pressure; 184bf215546Sopenharmony_ci int est; 185bf215546Sopenharmony_ci bool scheduled; 186bf215546Sopenharmony_ci } rsched; 187bf215546Sopenharmony_ci struct { 188bf215546Sopenharmony_ci float index; 189bf215546Sopenharmony_ci struct gpir_node *last; 190bf215546Sopenharmony_ci } vreg; 191bf215546Sopenharmony_ci struct { 192bf215546Sopenharmony_ci int index; 193bf215546Sopenharmony_ci } preg; 194bf215546Sopenharmony_ci }; 195bf215546Sopenharmony_ci} gpir_node; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_citypedef struct { 198bf215546Sopenharmony_ci gpir_node node; 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci gpir_node *children[3]; 201bf215546Sopenharmony_ci bool children_negate[3]; 202bf215546Sopenharmony_ci int num_child; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci bool dest_negate; 205bf215546Sopenharmony_ci} gpir_alu_node; 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_citypedef struct { 208bf215546Sopenharmony_ci gpir_node node; 209bf215546Sopenharmony_ci union fi value; 210bf215546Sopenharmony_ci} gpir_const_node; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_citypedef struct { 213bf215546Sopenharmony_ci int index; 214bf215546Sopenharmony_ci struct list_head list; 215bf215546Sopenharmony_ci} gpir_reg; 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_citypedef struct { 218bf215546Sopenharmony_ci gpir_node node; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci unsigned index; 221bf215546Sopenharmony_ci unsigned component; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci gpir_reg *reg; 224bf215546Sopenharmony_ci struct list_head reg_link; 225bf215546Sopenharmony_ci} gpir_load_node; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_citypedef struct gpir_store_node { 228bf215546Sopenharmony_ci gpir_node node; 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci unsigned index; 231bf215546Sopenharmony_ci unsigned component; 232bf215546Sopenharmony_ci gpir_node *child; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci gpir_reg *reg; 235bf215546Sopenharmony_ci} gpir_store_node; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_cienum gpir_instr_slot { 238bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MUL0, 239bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MUL1, 240bf215546Sopenharmony_ci GPIR_INSTR_SLOT_ADD0, 241bf215546Sopenharmony_ci GPIR_INSTR_SLOT_ADD1, 242bf215546Sopenharmony_ci GPIR_INSTR_SLOT_PASS, 243bf215546Sopenharmony_ci GPIR_INSTR_SLOT_COMPLEX, 244bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG0_LOAD0, 245bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG0_LOAD1, 246bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG0_LOAD2, 247bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG0_LOAD3, 248bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG1_LOAD0, 249bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG1_LOAD1, 250bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG1_LOAD2, 251bf215546Sopenharmony_ci GPIR_INSTR_SLOT_REG1_LOAD3, 252bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MEM_LOAD0, 253bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MEM_LOAD1, 254bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MEM_LOAD2, 255bf215546Sopenharmony_ci GPIR_INSTR_SLOT_MEM_LOAD3, 256bf215546Sopenharmony_ci GPIR_INSTR_SLOT_STORE0, 257bf215546Sopenharmony_ci GPIR_INSTR_SLOT_STORE1, 258bf215546Sopenharmony_ci GPIR_INSTR_SLOT_STORE2, 259bf215546Sopenharmony_ci GPIR_INSTR_SLOT_STORE3, 260bf215546Sopenharmony_ci GPIR_INSTR_SLOT_NUM, 261bf215546Sopenharmony_ci GPIR_INSTR_SLOT_END, 262bf215546Sopenharmony_ci GPIR_INSTR_SLOT_ALU_BEGIN = GPIR_INSTR_SLOT_MUL0, 263bf215546Sopenharmony_ci GPIR_INSTR_SLOT_ALU_END = GPIR_INSTR_SLOT_COMPLEX, 264bf215546Sopenharmony_ci GPIR_INSTR_SLOT_DIST_TWO_BEGIN = GPIR_INSTR_SLOT_MUL0, 265bf215546Sopenharmony_ci GPIR_INSTR_SLOT_DIST_TWO_END = GPIR_INSTR_SLOT_PASS, 266bf215546Sopenharmony_ci}; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_citypedef struct gpir_instr { 269bf215546Sopenharmony_ci int index; 270bf215546Sopenharmony_ci struct list_head list; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci gpir_node *slots[GPIR_INSTR_SLOT_NUM]; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci /* The number of ALU slots free for moves. */ 275bf215546Sopenharmony_ci int alu_num_slot_free; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci /* The number of ALU slots free for moves, except for the complex slot. */ 278bf215546Sopenharmony_ci int alu_non_cplx_slot_free; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci /* We need to make sure that we can insert moves in the following cases: 281bf215546Sopenharmony_ci * (1) There was a use of a value two cycles ago. 282bf215546Sopenharmony_ci * (2) There were more than 5 uses of a value 1 cycle ago (or else we can't 283bf215546Sopenharmony_ci * possibly satisfy (1) for the next cycle). 284bf215546Sopenharmony_ci * (3) There is a store instruction scheduled, but not its child. 285bf215546Sopenharmony_ci * 286bf215546Sopenharmony_ci * The complex slot cannot be used for a move in case (1), since it only 287bf215546Sopenharmony_ci * has a FIFO depth of 1, but it can be used for (2) as well as (3) as long 288bf215546Sopenharmony_ci * as the uses aren't in certain slots. It turns out that we don't have to 289bf215546Sopenharmony_ci * worry about nodes that can't use the complex slot for (2), since there 290bf215546Sopenharmony_ci * are at most 4 uses 1 cycle ago that can't use the complex slot, but we 291bf215546Sopenharmony_ci * do have to worry about (3). This means tracking stores whose children 292bf215546Sopenharmony_ci * cannot be in the complex slot. In order to ensure that we have enough 293bf215546Sopenharmony_ci * space for all three, we maintain the following invariants: 294bf215546Sopenharmony_ci * 295bf215546Sopenharmony_ci * (1) alu_num_slot_free >= alu_num_slot_needed_by_store + 296bf215546Sopenharmony_ci * alu_num_slot_needed_by_max + 297bf215546Sopenharmony_ci * max(alu_num_unscheduled_next_max - alu_max_allowed_next_max, 0) 298bf215546Sopenharmony_ci * (2) alu_non_cplx_slot_free >= alu_num_slot_needed_by_max + 299bf215546Sopenharmony_ci * alu_num_slot_needed_by_non_cplx_store 300bf215546Sopenharmony_ci * 301bf215546Sopenharmony_ci * alu_max_allowed_next_max is normally 5 (since there can be at most 5 max 302bf215546Sopenharmony_ci * nodes for the next instruction) but when there is a complex1 node in 303bf215546Sopenharmony_ci * this instruction it reduces to 4 to reserve a slot for complex2 in the 304bf215546Sopenharmony_ci * next instruction. 305bf215546Sopenharmony_ci */ 306bf215546Sopenharmony_ci int alu_num_slot_needed_by_store; 307bf215546Sopenharmony_ci int alu_num_slot_needed_by_non_cplx_store; 308bf215546Sopenharmony_ci int alu_num_slot_needed_by_max; 309bf215546Sopenharmony_ci int alu_num_unscheduled_next_max; 310bf215546Sopenharmony_ci int alu_max_allowed_next_max; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci /* Used to communicate to the scheduler how many slots need to be cleared 313bf215546Sopenharmony_ci * up in order to satisfy the invariants. 314bf215546Sopenharmony_ci */ 315bf215546Sopenharmony_ci int slot_difference; 316bf215546Sopenharmony_ci int non_cplx_slot_difference; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci int reg0_use_count; 319bf215546Sopenharmony_ci bool reg0_is_attr; 320bf215546Sopenharmony_ci int reg0_index; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci int reg1_use_count; 323bf215546Sopenharmony_ci int reg1_index; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci int mem_use_count; 326bf215546Sopenharmony_ci bool mem_is_temp; 327bf215546Sopenharmony_ci int mem_index; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci enum { 330bf215546Sopenharmony_ci GPIR_INSTR_STORE_NONE, 331bf215546Sopenharmony_ci GPIR_INSTR_STORE_VARYING, 332bf215546Sopenharmony_ci GPIR_INSTR_STORE_REG, 333bf215546Sopenharmony_ci GPIR_INSTR_STORE_TEMP, 334bf215546Sopenharmony_ci } store_content[2]; 335bf215546Sopenharmony_ci int store_index[2]; 336bf215546Sopenharmony_ci} gpir_instr; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_citypedef struct gpir_block { 339bf215546Sopenharmony_ci struct list_head list; 340bf215546Sopenharmony_ci struct list_head node_list; 341bf215546Sopenharmony_ci struct list_head instr_list; 342bf215546Sopenharmony_ci struct gpir_compiler *comp; 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci struct gpir_block *successors[2]; 345bf215546Sopenharmony_ci struct list_head predecessors; 346bf215546Sopenharmony_ci struct list_head predecessors_node; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci /* for regalloc */ 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci /* The set of live registers, i.e. registers whose value may be used 351bf215546Sopenharmony_ci * eventually, at the beginning of the block. 352bf215546Sopenharmony_ci */ 353bf215546Sopenharmony_ci BITSET_WORD *live_in; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci /* Set of live registers at the end of the block. */ 356bf215546Sopenharmony_ci BITSET_WORD *live_out; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci /* Set of registers that may have a value defined at the end of the 359bf215546Sopenharmony_ci * block. 360bf215546Sopenharmony_ci */ 361bf215546Sopenharmony_ci BITSET_WORD *def_out; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci /* After register allocation, the set of live physical registers at the end 364bf215546Sopenharmony_ci * of the block. Needed for scheduling. 365bf215546Sopenharmony_ci */ 366bf215546Sopenharmony_ci uint64_t live_out_phys; 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci /* For codegen, the offset in the final program. */ 369bf215546Sopenharmony_ci unsigned instr_offset; 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci /* for scheduler */ 372bf215546Sopenharmony_ci union { 373bf215546Sopenharmony_ci struct { 374bf215546Sopenharmony_ci int instr_index; 375bf215546Sopenharmony_ci } sched; 376bf215546Sopenharmony_ci struct { 377bf215546Sopenharmony_ci int node_index; 378bf215546Sopenharmony_ci } rsched; 379bf215546Sopenharmony_ci }; 380bf215546Sopenharmony_ci} gpir_block; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_citypedef struct { 383bf215546Sopenharmony_ci gpir_node node; 384bf215546Sopenharmony_ci gpir_block *dest; 385bf215546Sopenharmony_ci gpir_node *cond; 386bf215546Sopenharmony_ci} gpir_branch_node; 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_cistruct lima_vs_compiled_shader; 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_VIEWPORT_SCALE 0 391bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_VIEWPORT_OFFSET 1 392bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_NUM 2 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_citypedef struct gpir_compiler { 395bf215546Sopenharmony_ci struct list_head block_list; 396bf215546Sopenharmony_ci int cur_index; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci /* Find the gpir node for a given NIR SSA def. */ 399bf215546Sopenharmony_ci gpir_node **node_for_ssa; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci /* Find the gpir node for a given NIR register. */ 402bf215546Sopenharmony_ci gpir_node **node_for_reg; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci /* Find the gpir register for a given NIR SSA def. */ 405bf215546Sopenharmony_ci gpir_reg **reg_for_ssa; 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci /* Find the gpir register for a given NIR register. */ 408bf215546Sopenharmony_ci gpir_reg **reg_for_reg; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci /* gpir block for NIR block. */ 411bf215546Sopenharmony_ci gpir_block **blocks; 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci /* for physical reg */ 414bf215546Sopenharmony_ci struct list_head reg_list; 415bf215546Sopenharmony_ci int cur_reg; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci /* lookup for vector ssa */ 418bf215546Sopenharmony_ci struct { 419bf215546Sopenharmony_ci int ssa; 420bf215546Sopenharmony_ci gpir_node *nodes[4]; 421bf215546Sopenharmony_ci } vector_ssa[GPIR_VECTOR_SSA_NUM]; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci struct lima_vs_compiled_shader *prog; 424bf215546Sopenharmony_ci int constant_base; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci /* shaderdb */ 427bf215546Sopenharmony_ci int num_instr; 428bf215546Sopenharmony_ci int num_loops; 429bf215546Sopenharmony_ci int num_spills; 430bf215546Sopenharmony_ci int num_fills; 431bf215546Sopenharmony_ci} gpir_compiler; 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci#define GPIR_VALUE_REG_NUM 11 434bf215546Sopenharmony_ci#define GPIR_PHYSICAL_REG_NUM 64 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_civoid *gpir_node_create(gpir_block *block, gpir_op op); 437bf215546Sopenharmony_cigpir_dep *gpir_node_add_dep(gpir_node *succ, gpir_node *pred, int type); 438bf215546Sopenharmony_civoid gpir_node_remove_dep(gpir_node *succ, gpir_node *pred); 439bf215546Sopenharmony_civoid gpir_node_replace_succ(gpir_node *dst, gpir_node *src); 440bf215546Sopenharmony_civoid gpir_node_replace_pred(gpir_dep *dep, gpir_node *new_pred); 441bf215546Sopenharmony_civoid gpir_node_replace_child(gpir_node *parent, gpir_node *old_child, gpir_node *new_child); 442bf215546Sopenharmony_civoid gpir_node_insert_child(gpir_node *parent, gpir_node *child, gpir_node *insert_child); 443bf215546Sopenharmony_civoid gpir_node_delete(gpir_node *node); 444bf215546Sopenharmony_civoid gpir_node_print_prog_dep(gpir_compiler *comp); 445bf215546Sopenharmony_civoid gpir_node_print_prog_seq(gpir_compiler *comp); 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci#define gpir_node_foreach_succ(node, dep) \ 448bf215546Sopenharmony_ci list_for_each_entry(gpir_dep, dep, &node->succ_list, succ_link) 449bf215546Sopenharmony_ci#define gpir_node_foreach_succ_safe(node, dep) \ 450bf215546Sopenharmony_ci list_for_each_entry_safe(gpir_dep, dep, &node->succ_list, succ_link) 451bf215546Sopenharmony_ci#define gpir_node_foreach_pred(node, dep) \ 452bf215546Sopenharmony_ci list_for_each_entry(gpir_dep, dep, &node->pred_list, pred_link) 453bf215546Sopenharmony_ci#define gpir_node_foreach_pred_safe(node, dep) \ 454bf215546Sopenharmony_ci list_for_each_entry_safe(gpir_dep, dep, &node->pred_list, pred_link) 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_cistatic inline bool gpir_node_is_root(gpir_node *node) 457bf215546Sopenharmony_ci{ 458bf215546Sopenharmony_ci return list_is_empty(&node->succ_list); 459bf215546Sopenharmony_ci} 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_cistatic inline bool gpir_node_is_leaf(gpir_node *node) 462bf215546Sopenharmony_ci{ 463bf215546Sopenharmony_ci return list_is_empty(&node->pred_list); 464bf215546Sopenharmony_ci} 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci#define gpir_node_to_alu(node) ((gpir_alu_node *)(node)) 467bf215546Sopenharmony_ci#define gpir_node_to_const(node) ((gpir_const_node *)(node)) 468bf215546Sopenharmony_ci#define gpir_node_to_load(node) ((gpir_load_node *)(node)) 469bf215546Sopenharmony_ci#define gpir_node_to_store(node) ((gpir_store_node *)(node)) 470bf215546Sopenharmony_ci#define gpir_node_to_branch(node) ((gpir_branch_node *)(node)) 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_cigpir_instr *gpir_instr_create(gpir_block *block); 473bf215546Sopenharmony_cibool gpir_instr_try_insert_node(gpir_instr *instr, gpir_node *node); 474bf215546Sopenharmony_civoid gpir_instr_remove_node(gpir_instr *instr, gpir_node *node); 475bf215546Sopenharmony_civoid gpir_instr_print_prog(gpir_compiler *comp); 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_cibool gpir_codegen_acc_same_op(gpir_op op1, gpir_op op2); 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_cibool gpir_optimize(gpir_compiler *comp); 480bf215546Sopenharmony_cibool gpir_pre_rsched_lower_prog(gpir_compiler *comp); 481bf215546Sopenharmony_cibool gpir_reduce_reg_pressure_schedule_prog(gpir_compiler *comp); 482bf215546Sopenharmony_cibool gpir_regalloc_prog(gpir_compiler *comp); 483bf215546Sopenharmony_cibool gpir_schedule_prog(gpir_compiler *comp); 484bf215546Sopenharmony_cibool gpir_codegen_prog(gpir_compiler *comp); 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_cigpir_reg *gpir_create_reg(gpir_compiler *comp); 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci#endif 489