diff --git a/src/intel/compiler/brw_asm.c b/src/intel/compiler/brw_asm.c index 4a5e3e76516..239ff5fb205 100644 --- a/src/intel/compiler/brw_asm.c +++ b/src/intel/compiler/brw_asm.c @@ -6,89 +6,100 @@ #include "brw_asm.h" #include "brw_asm_internal.h" #include "brw_disasm_info.h" +#include "util/hash_table.h" +#include "util/u_dynarray.h" /* TODO: Check if we can use bison/flex without globals. */ extern FILE *yyin; -struct list_head instr_labels; -struct list_head target_labels; struct brw_codegen *p; const char *input_filename; int errors; bool compaction_warning_given; -static bool -i965_postprocess_labels() +/* + * Label tracking. + */ +static struct hash_table *brw_asm_labels; + +typedef struct { + char *name; + int offset; /* -1 for unset */ + struct util_dynarray jip_uses; + struct util_dynarray uip_uses; +} brw_asm_label; + +static brw_asm_label * +brw_asm_label_lookup(const char *name) { + uint32_t h = _mesa_hash_string(name); + struct hash_entry *entry = + _mesa_hash_table_search_pre_hashed(brw_asm_labels, h, name); + if (!entry) { + void *mem_ctx = brw_asm_labels; + brw_asm_label *label = rzalloc(mem_ctx, brw_asm_label); + label->name = ralloc_strdup(mem_ctx, name); + label->offset = -1; + util_dynarray_init(&label->jip_uses, mem_ctx); + util_dynarray_init(&label->uip_uses, mem_ctx); + entry = _mesa_hash_table_insert_pre_hashed(brw_asm_labels, + h, name, label); + } + assert(entry); + return entry->data; +} + +void +brw_asm_label_set(const char *name) +{ + brw_asm_label *label = brw_asm_label_lookup(name); + label->offset = p->next_insn_offset; +} + +void +brw_asm_label_use_jip(const char *name) +{ + brw_asm_label *label = brw_asm_label_lookup(name); + int offset = p->next_insn_offset - sizeof(brw_eu_inst); + util_dynarray_append(&label->jip_uses, int, offset); +} + +void +brw_asm_label_use_uip(const char *name) +{ + brw_asm_label *label = brw_asm_label_lookup(name); + int offset = p->next_insn_offset - sizeof(brw_eu_inst); + util_dynarray_append(&label->uip_uses, int, offset); +} + +static bool +brw_postprocess_labels() +{ + unsigned unknown = 0; void *store = p->store; - struct target_label *tlabel; - struct instr_label *ilabel, *s; + hash_table_foreach(brw_asm_labels, entry) { + brw_asm_label *label = entry->data; - const unsigned to_bytes_scale = brw_jump_scale(p->devinfo); + if (label->offset == -1) { + fprintf(stderr, "Unknown label '%s'\n", label->name); + unknown++; + continue; + } - LIST_FOR_EACH_ENTRY(tlabel, &target_labels, link) { - LIST_FOR_EACH_ENTRY_SAFE(ilabel, s, &instr_labels, link) { - if (!strcmp(tlabel->name, ilabel->name)) { - brw_eu_inst *inst = store + ilabel->offset; + util_dynarray_foreach(&label->jip_uses, int, use_offset) { + brw_eu_inst *inst = store + *use_offset; + brw_eu_inst_set_jip(p->devinfo, inst, label->offset - *use_offset); + } - int relative_offset = (tlabel->offset - ilabel->offset) / sizeof(brw_eu_inst); - relative_offset *= to_bytes_scale; - - unsigned opcode = brw_eu_inst_opcode(p->isa, inst); - - if (ilabel->type == INSTR_LABEL_JIP) { - switch (opcode) { - case BRW_OPCODE_IF: - case BRW_OPCODE_ELSE: - case BRW_OPCODE_ENDIF: - case BRW_OPCODE_WHILE: - case BRW_OPCODE_GOTO: - case BRW_OPCODE_JOIN: - brw_eu_inst_set_jip(p->devinfo, inst, relative_offset); - break; - case BRW_OPCODE_BREAK: - case BRW_OPCODE_HALT: - case BRW_OPCODE_CONTINUE: - brw_eu_inst_set_jip(p->devinfo, inst, relative_offset); - break; - default: - fprintf(stderr, "Unknown opcode %d with JIP label\n", opcode); - return false; - } - } else { - switch (opcode) { - case BRW_OPCODE_IF: - case BRW_OPCODE_ELSE: - case BRW_OPCODE_GOTO: - brw_eu_inst_set_uip(p->devinfo, inst, relative_offset); - break; - case BRW_OPCODE_WHILE: - case BRW_OPCODE_ENDIF: - fprintf(stderr, "WHILE/ENDIF cannot have UIP offset\n"); - return false; - case BRW_OPCODE_BREAK: - case BRW_OPCODE_CONTINUE: - case BRW_OPCODE_HALT: - brw_eu_inst_set_uip(p->devinfo, inst, relative_offset); - break; - default: - fprintf(stderr, "Unknown opcode %d with UIP label\n", opcode); - return false; - } - } - - list_del(&ilabel->link); - } + util_dynarray_foreach(&label->uip_uses, int, use_offset) { + brw_eu_inst *inst = store + *use_offset; + brw_eu_inst_set_uip(p->devinfo, inst, label->offset - *use_offset); } } - LIST_FOR_EACH_ENTRY(ilabel, &instr_labels, link) { - fprintf(stderr, "Unknown label '%s'\n", ilabel->name); - } - - return list_is_empty(&instr_labels); + return unknown == 0; } /* TODO: Would be nice to make this operate on string instead on a FILE. */ @@ -99,8 +110,8 @@ brw_assemble(void *mem_ctx, const struct intel_device_info *devinfo, { brw_assemble_result result = {0}; - list_inithead(&instr_labels); - list_inithead(&target_labels); + void *tmp_ctx = ralloc_context(mem_ctx); + brw_asm_labels = _mesa_string_hash_table_create(tmp_ctx); struct brw_isa_info isa; brw_init_isa_info(&isa, devinfo); @@ -116,7 +127,7 @@ brw_assemble(void *mem_ctx, const struct intel_device_info *devinfo, if (err || errors) goto end; - if (!i965_postprocess_labels()) + if (!brw_postprocess_labels()) goto end; struct disasm_info *disasm_info = disasm_initialize(p->isa, NULL); @@ -154,8 +165,9 @@ end: yyin = NULL; input_filename = NULL; p = NULL; - list_inithead(&instr_labels); - list_inithead(&target_labels); + brw_asm_labels = NULL; + + ralloc_free(tmp_ctx); return result; } diff --git a/src/intel/compiler/brw_asm_internal.h b/src/intel/compiler/brw_asm_internal.h index 84477102a46..e4ddd503a2d 100644 --- a/src/intel/compiler/brw_asm_internal.h +++ b/src/intel/compiler/brw_asm_internal.h @@ -31,9 +31,6 @@ extern int errors; extern bool compaction_warning_given; extern const char *input_filename; -extern struct list_head instr_labels; -extern struct list_head target_labels; - struct condition { unsigned cond_modifier:4; unsigned flag_reg_nr:1; @@ -83,22 +80,6 @@ struct msgdesc { unsigned src1_len:5; }; -enum instr_label_type { - INSTR_LABEL_JIP, - INSTR_LABEL_UIP, -}; - -struct instr_label { - struct list_head link; - - char *name; - int offset; - enum instr_label_type type; -}; - -struct target_label { - struct list_head link; - - char *name; - int offset; -}; +void brw_asm_label_set(const char *name); +void brw_asm_label_use_jip(const char *name); +void brw_asm_label_use_uip(const char *name); diff --git a/src/intel/compiler/brw_gram.y b/src/intel/compiler/brw_gram.y index 5ced965dffa..74e8523e45c 100644 --- a/src/intel/compiler/brw_gram.y +++ b/src/intel/compiler/brw_gram.y @@ -313,22 +313,6 @@ i965_asm_set_instruction_options(struct brw_codegen *p, options.compaction); } -static void -add_label(struct brw_codegen *p, const char* label_name, enum instr_label_type type) -{ - if (!label_name) { - return; - } - - struct instr_label *label = rzalloc(p->mem_ctx, struct instr_label); - - label->name = ralloc_strdup(p->mem_ctx, label_name); - label->offset = p->next_insn_offset; - label->type = type; - - list_addtail(&label->link, &instr_labels); -} - %} %locations @@ -1101,9 +1085,8 @@ jumpinstruction: branchinstruction: predicate ENDIF execsize JIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); i965_asm_set_instruction_options(p, $6); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1113,10 +1096,9 @@ branchinstruction: } | ELSE execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $4, INSTR_LABEL_JIP); - add_label(p, $6, INSTR_LABEL_UIP); - brw_next_insn(p, $1); + brw_asm_label_use_jip($4); + brw_asm_label_use_uip($6); i965_asm_set_instruction_options(p, $7); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $2); @@ -1126,11 +1108,10 @@ branchinstruction: } | predicate IF execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - add_label(p, $7, INSTR_LABEL_UIP); - brw_next_insn(p, $2); i965_asm_set_instruction_options(p, $8); + brw_asm_label_use_jip($5); + brw_asm_label_use_uip($7); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); brw_set_dest(p, brw_last_inst, vec1(retype(brw_null_reg(), BRW_TYPE_D))); @@ -1141,10 +1122,9 @@ branchinstruction: } | predicate GOTO execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - add_label(p, $7, INSTR_LABEL_UIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); + brw_asm_label_use_uip($7); i965_asm_set_instruction_options(p, $8); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1155,9 +1135,8 @@ branchinstruction: joininstruction: predicate JOIN execsize JIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); i965_asm_set_instruction_options(p, $6); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1169,10 +1148,10 @@ joininstruction: breakinstruction: predicate BREAK execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - add_label(p, $7, INSTR_LABEL_UIP); brw_next_insn(p, $2); + brw_asm_label_use_jip($5); + brw_asm_label_use_uip($7); i965_asm_set_instruction_options(p, $8); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1183,10 +1162,9 @@ breakinstruction: } | predicate HALT execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - add_label(p, $7, INSTR_LABEL_UIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); + brw_asm_label_use_uip($7); i965_asm_set_instruction_options(p, $8); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1200,10 +1178,9 @@ breakinstruction: } | predicate CONT execsize JIP JUMP_LABEL UIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - add_label(p, $7, INSTR_LABEL_UIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); + brw_asm_label_use_uip($7); i965_asm_set_instruction_options(p, $8); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); brw_set_dest(p, brw_last_inst, brw_ip_reg()); @@ -1218,9 +1195,8 @@ breakinstruction: loopinstruction: predicate WHILE execsize JIP JUMP_LABEL instoptions { - add_label(p, $5, INSTR_LABEL_JIP); - brw_next_insn(p, $2); + brw_asm_label_use_jip($5); i965_asm_set_instruction_options(p, $6); brw_eu_inst_set_exec_size(p->devinfo, brw_last_inst, $3); @@ -1292,12 +1268,7 @@ relativelocation2: jumplabeltarget: JUMP_LABEL_TARGET { - struct target_label *label = rzalloc(p->mem_ctx, struct target_label); - - label->name = ralloc_strdup(p->mem_ctx, $1); - label->offset = p->next_insn_offset; - - list_addtail(&label->link, &target_labels); + brw_asm_label_set($1); } ;