From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 96452 invoked by alias); 30 Jun 2015 13:19:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 96436 invoked by uid 89); 30 Jun 2015 13:19:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Tue, 30 Jun 2015 13:19:11 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 30B01ABC6 for ; Tue, 30 Jun 2015 13:19:07 +0000 (UTC) Message-ID: <5592974A.5020904@suse.cz> Date: Tue, 30 Jun 2015 13:20:00 -0000 From: =?UTF-8?B?TWFydGluIExpxaFrYQ==?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: GCC Patches CC: Michael Matz Subject: [hsa] HSA: add support for function declaration emission and, fix RA. Content-Type: multipart/mixed; boundary="------------040108050001020409090104" X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg02212.txt.bz2 This is a multi-part message in MIME format. --------------040108050001020409090104 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 246 Hello. Following patch implements emission of function declarations and removes hsa_call_block_insn. The insn is replaced with a new hsa_arg_block_insn, which will make insn iteration flat and much easier for register allocator. Thanks, Martin --------------040108050001020409090104 Content-Type: text/x-patch; name="0001-HSA-add-support-for-function-declaration-emission-an.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-HSA-add-support-for-function-declaration-emission-an.pa"; filename*1="tch" Content-length: 47489 >From abb5eb3cf4f8569d2e003aabc5f078fcd17348a6 Mon Sep 17 00:00:00 2001 From: mliska Date: Mon, 22 Jun 2015 17:51:11 +0200 Subject: [PATCH 1/2] HSA: add support for function declaration emission and fix RA. gcc/ChangeLog: 2015-06-23 Martin Liska * hsa-brig.c (emit_directive_variable): Remove assert that is no longer valid. (emit_function_directives): Change the function that it accepts a hsa_function_representation and is used both for definitions and declarations. (emit_function_declaration): New function. (emit_arg_block): Remove. (emit_arg_block_insn): New function. (emit_insn): Add support for newly added hsa_insn_arg_block insn. (emit_call_insn): Use offsets of called functions because these function declaration are already emitted. (hsa_brig_emit_function): Emit function declarations for all called functions that haven't been seen yet. (hsa_output_brig): Do not process pseudo-linkage. * hsa-dump.c (dump_hsa_insn): Change argument type. (dump_hsa_bb): Fix indentation for hsa_arg_block_insn. * hsa-gen.c (hsa_deinit_data_for_cfun): Use newly added function release. (hsa_function_representation::hsa_function_representation): Add construction for newly added members. (hsa_function_representation::~hsa_function_representation): Add destruction for newly added members. (hsa_insn_arg_block::hsa_insn_arg_block): New function. (hsa_insn_arg_block::operator new): New function. (get_symbol_for_decl): Use new function. (gen_hsa_insns_for_direct_call): Save all called functions. (gen_hsa_insns_for_known_library_call): Use newly added function get_declaration_name. (get_function_arg_count): New. (gen_function_decl_parameters): Likewise. (gen_function_def_parameters): Add an optional argument and rename from: (gen_function_parameters): Removed. (hsa_generate_function_declaration): New. (generate_hsa): Fill up declaration for a hsa_function_representation. (hsa_init_data_for_cfun): Replace hsa_insn_call_block with hsa_insn_arg_block as template argument. * hsa-regalloc.c (naive_process_phi): Add assert. (hsa_num_def_ops): Change # of operands for call insn. (visit_insn): Remove. (remove_def_in_insn): Likewise. (merge_live_range_for_insn): Likewise. (linear_scan_regalloc): Simplify. * hsa.c (get_declaration_name): New function. (hsa_free_decl_kernel_mapping): Add guard. * hsa.h (struct hsa_function_representation): Add new struct fields. (hsa_function_representation::release): New. Fix call_block_insn and fix RA. Fix RA and related stuff. --- gcc/hsa-brig.c | 240 ++++++++++++++++++++++++++--------------------------- gcc/hsa-dump.c | 41 ++++----- gcc/hsa-gen.c | 224 ++++++++++++++++++++++++++++++++----------------- gcc/hsa-regalloc.c | 136 +++++++++--------------------- gcc/hsa.c | 20 ++++- gcc/hsa.h | 45 ++++++---- 6 files changed, 372 insertions(+), 334 deletions(-) diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c index d06fe42..ff697ee 100644 --- a/gcc/hsa-brig.c +++ b/gcc/hsa-brig.c @@ -128,10 +128,6 @@ struct function_linkage_pair unsigned int offset; }; -/* Vector of function calls where we need to resolve function offsets. */ - -static auto_vec function_call_linkage; - /* Add a new chunk, allocate data for it and initialize it. */ void @@ -511,7 +507,6 @@ emit_directive_variable (struct hsa_symbol *symbol) dirvar.type = htole16 (symbol->type); dirvar.segment = symbol->segment; dirvar.align = get_alignment (dirvar.type); - gcc_assert (symbol->linkage); dirvar.linkage = symbol->linkage; dirvar.dim.lo = (uint32_t) symbol->dim; dirvar.dim.hi = (uint32_t) ((unsigned long long) symbol->dim >> 32); @@ -522,11 +517,11 @@ emit_directive_variable (struct hsa_symbol *symbol) return symbol->directive_offset; } -/* Emit directives describing the function, for example its input and output - arguments, local variables etc. */ +/* Emit directives describing either a function declaration or + definition F. */ static BrigDirectiveExecutable * -emit_function_directives (void) +emit_function_directives (hsa_function_representation *f) { struct BrigDirectiveExecutable fndir; unsigned name_offset, inarg_off, scoped_off, next_toplev_off; @@ -534,38 +529,43 @@ emit_function_directives (void) BrigDirectiveExecutable *ptr_to_fndir; hsa_symbol *sym; - name_offset = brig_emit_string (hsa_cfun->name, '&'); + name_offset = brig_emit_string (f->name, '&'); inarg_off = brig_code.total_size + sizeof(fndir) - + (hsa_cfun->output_arg ? sizeof (struct BrigDirectiveVariable) : 0); + + (f->output_arg ? sizeof (struct BrigDirectiveVariable) : 0); scoped_off = inarg_off - + hsa_cfun->input_args_count * sizeof (struct BrigDirectiveVariable); - for (hash_table ::iterator iter - = hsa_cfun->local_symbols->begin (); - iter != hsa_cfun->local_symbols->end (); - ++iter) - if (TREE_CODE ((*iter)->decl) == VAR_DECL) - count++; - count += hsa_cfun->spill_symbols.length (); + + f->input_args_count * sizeof (struct BrigDirectiveVariable); + + if (!f->declaration_p) + { + for (hash_table ::iterator iter + = f->local_symbols->begin (); + iter != f->local_symbols->end (); + ++iter) + if (TREE_CODE ((*iter)->decl) == VAR_DECL) + count++; + count += f->spill_symbols.length (); + } next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveVariable); memset (&fndir, 0, sizeof (fndir)); fndir.base.byteCount = htole16 (sizeof (fndir)); - fndir.base.kind = htole16 (hsa_cfun->kern_p ? BRIG_KIND_DIRECTIVE_KERNEL + fndir.base.kind = htole16 (f->kern_p ? BRIG_KIND_DIRECTIVE_KERNEL : BRIG_KIND_DIRECTIVE_FUNCTION); fndir.name = htole32 (name_offset); - fndir.inArgCount = htole16 (hsa_cfun->input_args_count); - fndir.outArgCount = htole16 (hsa_cfun->output_arg ? 1 : 0); + fndir.inArgCount = htole16 (f->input_args_count); + fndir.outArgCount = htole16 (f->output_arg ? 1 : 0); fndir.firstInArg = htole32 (inarg_off); fndir.firstCodeBlockEntry = htole32 (scoped_off); fndir.nextModuleEntry = htole32 (next_toplev_off); - fndir.linkage = BRIG_LINKAGE_PROGRAM; - fndir.modifier.allBits |= BRIG_EXECUTABLE_DEFINITION; + fndir.linkage = f->kern_p || TREE_PUBLIC (f->decl) ? BRIG_LINKAGE_PROGRAM : + BRIG_LINKAGE_MODULE; + + if (!f->declaration_p) + fndir.modifier.allBits |= BRIG_EXECUTABLE_DEFINITION; memset (&fndir.reserved, 0, sizeof (fndir.reserved)); - if (!function_offsets) - function_offsets = new hash_map (); - function_offsets->put (cfun->decl, brig_code.total_size); + function_offsets->put (f->decl, brig_code.total_size); brig_code.add (&fndir, sizeof (fndir)); /* XXX terrible hack: we need to set instCount after we emit all @@ -579,23 +579,27 @@ emit_function_directives (void) + brig_code.cur_chunk->size - sizeof (fndir)); - if (hsa_cfun->output_arg) - emit_directive_variable(hsa_cfun->output_arg); - for (int i = 0; i < hsa_cfun->input_args_count; i++) - emit_directive_variable(&hsa_cfun->input_args[i]); - for (hash_table ::iterator iter - = hsa_cfun->local_symbols->begin (); - iter != hsa_cfun->local_symbols->end (); - ++iter) - { - if (TREE_CODE ((*iter)->decl) == VAR_DECL) - brig_insn_count++; - emit_directive_variable(*iter); - } - for (int i = 0; hsa_cfun->spill_symbols.iterate (i, &sym); i++) + if (f->output_arg) + emit_directive_variable (f->output_arg); + for (unsigned i = 0; i < f->input_args_count; i++) + emit_directive_variable (&f->input_args[i]); + + if (!f->declaration_p) { - emit_directive_variable (sym); - brig_insn_count++; + for (hash_table ::iterator iter + = f->local_symbols->begin (); + iter != f->local_symbols->end (); + ++iter) + { + if (TREE_CODE ((*iter)->decl) == VAR_DECL) + brig_insn_count++; + emit_directive_variable (*iter); + } + for (int i = 0; f->spill_symbols.iterate (i, &sym); i++) + { + emit_directive_variable (sym); + brig_insn_count++; + } } return ptr_to_fndir; @@ -1003,6 +1007,19 @@ emit_queued_operands (void) } } +/* Emit directives describing the function that is used for +a function declaration. */ +static void +emit_function_declaration (tree decl) +{ + hsa_function_representation *f = hsa_generate_function_declaration (decl); + + emit_function_directives (f); + emit_queued_operands (); + + delete f; +} + /* Emit an HSA memory instruction and all necessary directives, schedule necessary operands for writing . */ @@ -1299,29 +1316,6 @@ emit_cvt_insn (hsa_insn_basic *insn) brig_insn_count++; } -/* Emit arg block to code segment. */ - -static void -emit_arg_block (bool is_start) -{ - if (is_start) - { - struct BrigDirectiveArgBlockStart repr; - repr.base.byteCount = htole16 (sizeof (repr)); - repr.base.kind = htole16 (BRIG_KIND_DIRECTIVE_ARG_BLOCK_START); - brig_code.add (&repr, sizeof (repr)); - brig_insn_count++; - } - else - { - struct BrigDirectiveArgBlockEnd repr; - repr.base.byteCount = htole16 (sizeof (repr)); - repr.base.kind = htole16 (BRIG_KIND_DIRECTIVE_ARG_BLOCK_END); - brig_code.add (&repr, sizeof (repr)); - brig_insn_count++; - } -} - /* Emit call instruction INSN, where this instruction must be closed within a call block instruction. */ @@ -1343,13 +1337,12 @@ emit_call_insn (hsa_insn_basic *insn) operand_offsets[0] = htole32 (enqueue_op (call->result_code_list)); /* Operand 1: func */ - /* XXX: we have to save offset to operand section and - called function offset is filled up after all functions are visited. */ + BrigCodeOffset32_t *func_offset = function_offsets->get + (call->called_function); + gcc_assert (func_offset != NULL); + call->func.directive_offset = *func_offset; unsigned int offset = enqueue_op (&call->func); - function_call_linkage.safe_push - (function_linkage_pair (call->called_function, offset)); - operand_offsets[1] = htole32 (offset); /* Operand 2: in-args. */ operand_offsets[2] = htole32 (enqueue_op (call->args_code_list)); @@ -1366,40 +1359,49 @@ emit_call_insn (hsa_insn_basic *insn) brig_insn_count++; } -/* Emit call block instruction. This super instruction encapsulate all - instructions needed for argument load/store and corresponding - instruction. */ +/* Emit argument block directive. */ static void -emit_call_block_insn (hsa_insn_call_block *insn) +emit_arg_block_insn (hsa_insn_arg_block *insn) { - /* Argument scope start. */ - emit_arg_block (true); - - for (unsigned i = 0; i < insn->input_args.length (); i++) + switch (insn->kind) { - insn->call_insn->args_code_list->offsets[i] = htole32 - (emit_directive_variable (insn->input_args[i])); - brig_insn_count++; - } + case BRIG_KIND_DIRECTIVE_ARG_BLOCK_START: + { + struct BrigDirectiveArgBlockStart repr; + repr.base.byteCount = htole16 (sizeof (repr)); + repr.base.kind = htole16 (insn->kind); + brig_code.add (&repr, sizeof (repr)); + + for (unsigned i = 0; i < insn->call_insn->input_args.length (); i++) + { + insn->call_insn->args_code_list->offsets[i] = htole32 + (emit_directive_variable (insn->call_insn->input_args[i])); + brig_insn_count++; + } + + if (insn->call_insn->result_symbol) + { + insn->call_insn->result_code_list->offsets[0] = htole32 + (emit_directive_variable (insn->call_insn->output_arg)); + brig_insn_count++; + } - if (insn->call_insn->result_symbol) - { - insn->call_insn->result_code_list->offsets[0] = htole32 - (emit_directive_variable (insn->output_arg)); - brig_insn_count++; + break; + } + case BRIG_KIND_DIRECTIVE_ARG_BLOCK_END: + { + struct BrigDirectiveArgBlockEnd repr; + repr.base.byteCount = htole16 (sizeof (repr)); + repr.base.kind = htole16 (insn->kind); + brig_code.add (&repr, sizeof (repr)); + break; + } + default: + gcc_unreachable (); } - for (unsigned i = 0; i < insn->input_arg_insns.length (); i++) - emit_memory_insn (insn->input_arg_insns[i]); - - emit_call_insn (insn->call_insn); - - if (insn->output_arg_insn) - emit_memory_insn (insn->output_arg_insn); - - /* Argument scope end. */ - emit_arg_block (false); + brig_insn_count++; } /* Emit a basic HSA instruction and all necessary directives, schedule @@ -1512,9 +1514,9 @@ emit_insn (hsa_insn_basic *insn) emit_branch_insn (br); return; } - if (hsa_insn_call_block *call_block = dyn_cast (insn)) + if (hsa_insn_arg_block *arg_block = dyn_cast (insn)) { - emit_call_block_insn (call_block); + emit_arg_block_insn (arg_block); return; } if (hsa_insn_call *call = dyn_cast (insn)) @@ -1589,7 +1591,21 @@ hsa_brig_emit_function (void) memset (&op_queue, 0, sizeof (op_queue)); op_queue.projected_size = brig_operand.total_size; - ptr_to_fndir = emit_function_directives (); + if (!function_offsets) + function_offsets = new hash_map (); + + for (unsigned i = 0; i < hsa_cfun->called_functions.length (); i++) + { + tree called = hsa_cfun->called_functions[i]; + + if (function_offsets->get (called) == NULL) + { + emit_function_declaration (called); + gcc_assert (function_offsets->get (called) != NULL); + } + } + + ptr_to_fndir = emit_function_directives (hsa_cfun); for (insn = hsa_bb_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun))->first_insn; insn; insn = insn->next) @@ -1803,30 +1819,6 @@ hsa_output_brig (void) if (!brig_initialized) return; - for (unsigned i = 0; i < function_call_linkage.length (); i++) - { - function_linkage_pair p = function_call_linkage[i]; - - if (!function_offsets) - { - sorry ("Missing offset to a HSA function in call instruction"); - return; - } - BrigCodeOffset32_t *func_offset = function_offsets->get (p.function_decl); - if (*func_offset) - { - BrigOperandCodeRef *code_ref = (BrigOperandCodeRef *) - (brig_operand.get_ptr_by_offset (p.offset)); - gcc_assert (code_ref->base.kind == BRIG_KIND_OPERAND_CODE_REF); - code_ref->ref = htole32 (*func_offset); - } - else - { - sorry ("Missing offset to a HSA function in call instruction"); - return; - } - } - saved_section = in_section; switch_to_section (get_section (BRIG_ELF_SECTION_NAME, SECTION_NOTYPE, NULL)); diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c index 2519765..e1adcbc 100644 --- a/gcc/hsa-dump.c +++ b/gcc/hsa-dump.c @@ -706,10 +706,10 @@ static void indent_stream (FILE *f, int indent) /* Dump textual representation of HSA IL instruction INSN to file F. */ static void -dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int indent) +dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent) { gcc_checking_assert (insn); - indent_stream (f, indent); + indent_stream (f, *indent); if (insn->number) fprintf (f, "%5d: ", insn->number); @@ -849,37 +849,38 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int indent) } fprintf (f, "BB %i\n", hsa_bb_for_bb (target)->index); } - else if (is_a (insn)) + else if (is_a (insn)) { - hsa_insn_call_block *call_block = as_a (insn); + hsa_insn_arg_block *arg_block = as_a (insn); + bool start_p = arg_block->kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_START; + char c = start_p ? '{' : '}'; - fprintf (f, "{\n"); - - for (unsigned i = 0; i < call_block->input_arg_insns.length (); i++) - dump_hsa_insn (f, call_block->input_arg_insns[i], indent + 2); - - dump_hsa_insn (f, call_block->call_insn, indent + 2); + if (start_p) + { + *indent += 2; + indent_stream (f, 2); + } - if (call_block->output_arg_insn) - dump_hsa_insn (f, call_block->output_arg_insn, indent + 2); + if (!start_p) + *indent -= 2; - indent_stream (f, indent); - fprintf (f, "}\n"); + fprintf (f, "%c\n", c); } else if (is_a (insn)) { hsa_insn_call *call = as_a (insn); - const char *name = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (call->called_function))); + const char *name = get_declaration_name (call->called_function); fprintf (f, "call &%s", name); if (call->result_symbol) - fprintf (f, "(%%%s) ", call->result_symbol->name); + fprintf (f, "(%%res) "); fprintf (f, "("); for (unsigned i = 0; i < call->args_symbols.length (); i++) { - fprintf (f, "%%%s", call->args_symbols[i]->name); + fprintf (f, "%%__arg_%u", i); + if (i != call->args_symbols.length () - 1) fprintf (f, ", "); } @@ -929,10 +930,12 @@ dump_hsa_bb (FILE *f, hsa_bb *hbb) /* FIXME: Dump a label or something instead. */ fprintf (f, "BB %i:\n", hbb->index); + int indent = 2; for (insn = hbb->first_phi; insn; insn = insn->next) - dump_hsa_insn (f, insn, 2); + dump_hsa_insn (f, insn, &indent); + for (insn = hbb->first_insn; insn; insn = insn->next) - dump_hsa_insn (f, insn, 2); + dump_hsa_insn (f, insn, &indent); FOR_EACH_EDGE (e, ei, hbb->bb->succs) if (e->flags & EDGE_TRUE_VALUE) diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index fab0191..bd75cf0 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -86,7 +86,7 @@ static pool_allocator *hsa_allocp_inst_seg; static pool_allocator *hsa_allocp_inst_cmp; static pool_allocator *hsa_allocp_inst_br; static pool_allocator *hsa_allocp_inst_call; -static pool_allocator *hsa_allocp_inst_call_block; +static pool_allocator *hsa_allocp_inst_arg_block; static pool_allocator *hsa_allocp_bb; static pool_allocator *hsa_allocp_symbols; @@ -115,6 +115,8 @@ hsa_function_representation::hsa_function_representation () hbb_count = 1; /* 0 is for prologue. */ in_ssa = true; /* We start in SSA. */ kern_p = false; + declaration_p = false; + called_functions = vNULL; } /* Destructor of class holding function/kernel-wide informaton and state. */ @@ -129,6 +131,7 @@ hsa_function_representation::~hsa_function_representation () if (!kern_p) free (name); spill_symbols.release (); + called_functions.release (); } /* Allocate HSA structures that we need only while generating with this. */ @@ -164,8 +167,8 @@ hsa_init_data_for_cfun () = new pool_allocator ("HSA branching instructions", 16); hsa_allocp_inst_call = new pool_allocator ("HSA call instructions", 16); - hsa_allocp_inst_call_block - = new pool_allocator ("HSA call block instructions", + hsa_allocp_inst_arg_block + = new pool_allocator ("HSA arg block instructions", 16); hsa_allocp_bb = new pool_allocator ("HSA basic blocks", 8); @@ -220,10 +223,9 @@ hsa_deinit_data_for_cfun (void) delete hsa_allocp_inst_cmp; delete hsa_allocp_inst_br; delete hsa_allocp_inst_call; - delete hsa_allocp_inst_call_block; + delete hsa_allocp_inst_arg_block; delete hsa_allocp_bb; delete hsa_allocp_symbols; - delete hsa_cfun; } @@ -528,10 +530,7 @@ get_symbol_for_decl (tree decl) } fillup_sym_for_decl (decl, sym); - if (!DECL_NAME (decl)) - sorry ("Support for HSA does not implement anonymous declarations"); - else - sym->name = IDENTIFIER_POINTER (DECL_NAME (decl)); + sym->name = get_declaration_name (decl); *slot = sym; return sym; } @@ -682,17 +681,17 @@ hsa_op_code_list::operator new (size_t) /* Lookup or create a HSA pseudo register for a given gimple SSA name. */ static hsa_op_reg * -hsa_reg_for_gimple_ssa (tree ssa, vec ssa_map) +hsa_reg_for_gimple_ssa (tree ssa, vec *ssa_map) { hsa_op_reg *hreg; gcc_checking_assert (TREE_CODE (ssa) == SSA_NAME); - if (ssa_map[SSA_NAME_VERSION (ssa)]) - return ssa_map[SSA_NAME_VERSION (ssa)]; + if ((*ssa_map)[SSA_NAME_VERSION (ssa)]) + return (*ssa_map)[SSA_NAME_VERSION (ssa)]; hreg = new hsa_op_reg (hsa_type_for_scalar_tree_type (TREE_TYPE (ssa), true)); hreg->gimple_ssa = ssa; - ssa_map[SSA_NAME_VERSION (ssa)] = hreg; + (*ssa_map)[SSA_NAME_VERSION (ssa)] = hreg; return hreg; } @@ -902,21 +901,20 @@ hsa_insn_call::operator new (size_t) return hsa_allocp_inst_call->allocate (); } -/* Constructor of class representing the block required to invoke a call in - HSAIL. */ -hsa_insn_call_block::hsa_insn_call_block () - : hsa_insn_basic (0, HSA_OPCODE_CALL_BLOCK) +/* Constructor of class representing the argument block required to invoke + a call in HSAIL. */ +hsa_insn_arg_block::hsa_insn_arg_block (BrigKind brig_kind, + hsa_insn_call * call) + : hsa_insn_basic (0, HSA_OPCODE_ARG_BLOCK), kind (brig_kind), + call_insn (call) { - output_arg = NULL; - output_arg_insn = NULL; - call_insn = NULL; } -/* New operator for classes representing HSAIL call blocks. */ +/* New operator for classes representing HSAIL argument blocks. */ void * -hsa_insn_call_block::operator new (size_t) +hsa_insn_arg_block::operator new (size_t) { - return hsa_allocp_inst_call_block->allocate (); + return hsa_allocp_inst_arg_block->allocate (); } /* Append HSA instruction INSN to basic block HBB. */ @@ -977,7 +975,7 @@ hsa_append_insn_after (hsa_insn_basic *new_insn, hsa_insn_basic *old_insn) SSA names to HSA registers. Append an new conversion statements to HBB. */ static hsa_op_reg * -hsa_reg_for_gimple_ssa_reqtype (tree ssa, vec ssa_map, +hsa_reg_for_gimple_ssa_reqtype (tree ssa, vec *ssa_map, hsa_bb *hbb, BrigType16_t reqtype) { hsa_op_reg *reg = hsa_reg_for_gimple_ssa (ssa, ssa_map); @@ -1004,7 +1002,7 @@ hsa_reg_for_gimple_ssa_reqtype (tree ssa, vec ssa_map, uses. */ static hsa_op_with_type * -gen_address_calculation (tree exp, hsa_bb *hbb, vec ssa_map, +gen_address_calculation (tree exp, hsa_bb *hbb, vec *ssa_map, BrigType16_t addrtype, hsa_insn_basic *new_use) { int opcode; @@ -1095,7 +1093,7 @@ add_addr_regs_if_needed (hsa_op_reg *r1, hsa_op_reg *r2, hsa_bb *hbb) static void process_mem_base (tree base, hsa_symbol **symbol, BrigType16_t *addrtype, hsa_op_reg **reg, offset_int *offset, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { if (TREE_CODE (base) == SSA_NAME) { @@ -1123,7 +1121,7 @@ process_mem_base (tree base, hsa_symbol **symbol, BrigType16_t *addrtype, pseudo-registers. */ static hsa_op_address * -gen_hsa_addr (tree ref, hsa_bb *hbb, vec ssa_map) +gen_hsa_addr (tree ref, hsa_bb *hbb, vec *ssa_map) { hsa_symbol *symbol = NULL; hsa_op_reg *reg = NULL; @@ -1298,7 +1296,7 @@ gen_hsa_addr_for_arg (tree tree_type, int index) static void gen_hsa_addr_insns (tree val, hsa_op_reg *dest, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { hsa_op_address *addr; hsa_insn_basic *insn = new hsa_insn_basic (2, BRIG_OPCODE_LDA); @@ -1347,7 +1345,7 @@ gen_hsa_addr_insns (tree val, hsa_op_reg *dest, hsa_bb *hbb, static hsa_op_with_type * hsa_reg_or_immed_for_gimple_op (tree op, hsa_bb *hbb, - vec ssa_map, + vec *ssa_map, hsa_insn_basic *new_use) { hsa_op_reg *tmp; @@ -1394,7 +1392,7 @@ hsa_build_append_simple_mov (hsa_op_reg *dest, hsa_op_base *src, hsa_bb *hbb) static void gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { /* The destination SSA name will give us the type. */ if (TREE_CODE (rhs) == VIEW_CONVERT_EXPR) @@ -1453,7 +1451,7 @@ gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb, static void gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { BrigType16_t mtype; mtype = mem_type_for_type (hsa_type_for_scalar_tree_type (TREE_TYPE (lhs), @@ -1509,7 +1507,7 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb, static void gen_hsa_insns_for_single_assignment (gimple assign, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { tree lhs = gimple_assign_lhs (assign); tree rhs = gimple_assign_rhs1 (assign); @@ -1616,7 +1614,7 @@ hsa_spill_out (hsa_insn_basic *insn, hsa_op_reg *spill_reg, hsa_op_reg **ptmp2) static void gen_hsa_cmp_insn_from_gimple (enum tree_code code, tree lhs, tree rhs, hsa_op_reg *dest, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { BrigCompareOperation8_t compare; @@ -1660,7 +1658,7 @@ gen_hsa_cmp_insn_from_gimple (enum tree_code code, tree lhs, tree rhs, static void gen_hsa_insns_for_operation_assignment (gimple assign, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { int opcode; @@ -1846,7 +1844,7 @@ gen_hsa_insns_for_operation_assignment (gimple assign, hsa_bb *hbb, static void gen_hsa_insns_for_cond_stmt (gimple cond, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { hsa_op_reg *ctrl = new hsa_op_reg (BRIG_TYPE_B1); hsa_insn_br *cbr; @@ -1867,10 +1865,15 @@ gen_hsa_insns_for_cond_stmt (gimple cond, hsa_bb *hbb, static void gen_hsa_insns_for_direct_call (gimple stmt, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { hsa_insn_call *call_insn = new hsa_insn_call (gimple_call_fndecl (stmt)); - hsa_insn_call_block *call_block_insn = new hsa_insn_call_block (); + hsa_cfun->called_functions.safe_push (call_insn->called_function); + + /* Argument block start. */ + hsa_insn_arg_block *arg_start = new hsa_insn_arg_block + (BRIG_KIND_DIRECTIVE_ARG_BLOCK_START, call_insn); + hsa_append_insn (hbb, arg_start); /* Preparation of arguments that will be passed to function. */ const unsigned args = gimple_call_num_args (stmt); @@ -1887,13 +1890,14 @@ gen_hsa_insns_for_direct_call (gimple stmt, hsa_bb *hbb, mem->operands[0] = src; mem->operands[1] = addr; - call_block_insn->input_args.safe_push (addr->symbol); - call_block_insn->input_arg_insns.safe_push (mem); + call_insn->input_args.safe_push (addr->symbol); + hsa_append_insn (hbb, mem); call_insn->args_symbols.safe_push (addr->symbol); } call_insn->args_code_list = new hsa_op_code_list (args); + hsa_append_insn (hbb, call_insn); tree result_type = TREE_TYPE (TREE_TYPE (gimple_call_fndecl (stmt))); @@ -1916,22 +1920,20 @@ gen_hsa_insns_for_direct_call (gimple stmt, hsa_bb *hbb, result_insn->operands[1] = addr; set_reg_def (dst, result_insn); - call_block_insn->output_arg_insn = result_insn; + hsa_append_insn (hbb, result_insn); } - call_block_insn->output_arg = addr->symbol; + call_insn->output_arg = addr->symbol; call_insn->result_symbol = addr->symbol; call_insn->result_code_list = new hsa_op_code_list (1); } else call_insn->result_code_list = new hsa_op_code_list (0); - call_block_insn->call_insn = call_insn; - - if (result_insn) - call_block_insn->output_arg_insn = result_insn; - - hsa_append_insn (hbb, call_block_insn); + /* Argument block start. */ + hsa_insn_arg_block *arg_end = new hsa_insn_arg_block + (BRIG_KIND_DIRECTIVE_ARG_BLOCK_END, call_insn); + hsa_append_insn (hbb, arg_end); } /* Generate HSA instructions for a return value instruction. @@ -1941,7 +1943,7 @@ gen_hsa_insns_for_direct_call (gimple stmt, hsa_bb *hbb, static void gen_hsa_insns_for_return (greturn *stmt, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { tree retval = gimple_return_retval (stmt); if (retval) @@ -1969,11 +1971,10 @@ gen_hsa_insns_for_return (greturn *stmt, hsa_bb *hbb, static bool gen_hsa_insns_for_known_library_call (gimple stmt, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { tree decl = gimple_call_fndecl (stmt); - gcc_checking_assert (DECL_NAME (decl)); - const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); + const char *name = get_declaration_name (decl); if (!strcmp (name, "omp_is_initial_device") || strcmp (name, "omp_is_initial_device")) @@ -1997,7 +1998,7 @@ gen_hsa_insns_for_known_library_call (gimple stmt, hsa_bb *hbb, static void gen_hsa_insns_for_call (gimple stmt, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { tree lhs = gimple_call_lhs (stmt); hsa_op_reg *dest; @@ -2143,7 +2144,7 @@ specialop: static void gen_hsa_insns_for_gimple_stmt (gimple stmt, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { switch (gimple_code (stmt)) { @@ -2185,7 +2186,7 @@ gen_hsa_insns_for_gimple_stmt (gimple stmt, hsa_bb *hbb, static void gen_hsa_phi_from_gimple_phi (gimple gphi, hsa_bb *hbb, - vec ssa_map) + vec *ssa_map) { hsa_insn_phi *hphi; unsigned count = gimple_phi_num_args (gphi); @@ -2287,7 +2288,7 @@ hsa_init_new_bb (basic_block bb) maps gimple SSA names to HSA pseudo registers. */ static void -gen_body_from_gimple (vec ssa_map) +gen_body_from_gimple (vec *ssa_map) { basic_block bb; @@ -2321,12 +2322,64 @@ gen_body_from_gimple (vec ssa_map) } } +/* For a function DECL, get number of arguments. */ + +static unsigned +get_function_arg_count (tree decl) +{ + unsigned count = 0; + + for (tree parm = TYPE_ARG_TYPES (TREE_TYPE (decl)); parm; + parm = TREE_CHAIN (parm)) + count++; + + /* Return type is the last element of tree list. */ + return count - 1; +} + +static void +gen_function_decl_parameters (hsa_function_representation *f, + tree decl) +{ + tree parm; + unsigned i; + + f->input_args_count = get_function_arg_count (decl); + f->input_args = XCNEWVEC (hsa_symbol, f->input_args_count); + for (parm = TYPE_ARG_TYPES (TREE_TYPE (decl)), i = 0; + parm; + parm = TREE_CHAIN (parm), i++) + { + /* Result type if last in the tree list. */ + if (i == f->input_args_count) + break; + + tree v = TREE_VALUE (parm); + f->input_args[i].type = hsa_type_for_tree_type (v, &f->input_args[i].dim); + f->input_args[i].segment = BRIG_SEGMENT_ARG; + f->input_args[i].linkage = BRIG_LINKAGE_NONE; + f->input_args[i].name_number = i; + } + + tree result_type = TREE_TYPE (TREE_TYPE (decl)); + if (!VOID_TYPE_P (result_type)) + { + f->output_arg = XCNEW (hsa_symbol); + f->output_arg->type = hsa_type_for_tree_type (result_type, + &f->output_arg->dim); + f->output_arg->segment = BRIG_SEGMENT_ARG; + f->output_arg->linkage = BRIG_LINKAGE_NONE; + f->output_arg->name = "res"; + } +} + /* Generate the vector of parameters of the HSA representation of the current function. This also includes the output parameter representing the result. */ static void -gen_function_parameters (vec ssa_map) +gen_function_def_parameters (hsa_function_representation *f, + vec *ssa_map) { tree parm; int i, count = 0; @@ -2334,30 +2387,33 @@ gen_function_parameters (vec ssa_map) for (parm = DECL_ARGUMENTS (cfun->decl); parm; parm = DECL_CHAIN (parm)) count++; - hsa_cfun->input_args_count = count; - hsa_cfun->input_args = XCNEWVEC (hsa_symbol, count); + ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux = &f->prologue; + f->prologue.bb = ENTRY_BLOCK_PTR_FOR_FN (cfun); + + f->input_args_count = count; + f->input_args = XCNEWVEC (hsa_symbol, f->input_args_count); for (parm = DECL_ARGUMENTS (cfun->decl), i = 0; parm; parm = DECL_CHAIN (parm), i++) { struct hsa_symbol **slot; - fillup_sym_for_decl (parm, &hsa_cfun->input_args[i]); - hsa_cfun->input_args[i].segment = hsa_cfun->kern_p ? BRIG_SEGMENT_KERNARG : + fillup_sym_for_decl (parm, &f->input_args[i]); + f->input_args[i].segment = f->kern_p ? BRIG_SEGMENT_KERNARG : BRIG_SEGMENT_ARG; - hsa_cfun->input_args[i].linkage = BRIG_LINKAGE_FUNCTION; + f->input_args[i].linkage = BRIG_LINKAGE_FUNCTION; if (!DECL_NAME (parm)) { /* FIXME: Just generate some UID. */ sorry ("Support for HSA does not implement anonymous C++ parameters"); return; } - hsa_cfun->input_args[i].name = IDENTIFIER_POINTER (DECL_NAME (parm)); - slot = hsa_cfun->local_symbols->find_slot (&hsa_cfun->input_args[i], + f->input_args[i].name = IDENTIFIER_POINTER (DECL_NAME (parm)); + slot = f->local_symbols->find_slot (&f->input_args[i], INSERT); gcc_assert (!*slot); - *slot = &hsa_cfun->input_args[i]; + *slot = &f->input_args[i]; if (is_gimple_reg (parm)) { @@ -2375,7 +2431,7 @@ gen_function_parameters (vec ssa_map) mem->operands[1] = addr; set_reg_def (dest, mem); gcc_assert (!addr->reg); - hsa_append_insn (&hsa_cfun->prologue, mem); + hsa_append_insn (&f->prologue, mem); } } } @@ -2384,17 +2440,34 @@ gen_function_parameters (vec ssa_map) { struct hsa_symbol **slot; - hsa_cfun->output_arg = XCNEW (hsa_symbol); - fillup_sym_for_decl (DECL_RESULT (cfun->decl), hsa_cfun->output_arg); - hsa_cfun->output_arg->segment = BRIG_SEGMENT_ARG; - hsa_cfun->output_arg->linkage = BRIG_LINKAGE_FUNCTION; - hsa_cfun->output_arg->name = "res"; - slot = hsa_cfun->local_symbols->find_slot (hsa_cfun->output_arg, INSERT); + f->output_arg = XCNEW (hsa_symbol); + fillup_sym_for_decl (DECL_RESULT (cfun->decl), f->output_arg); + f->output_arg->segment = BRIG_SEGMENT_ARG; + f->output_arg->linkage = BRIG_LINKAGE_FUNCTION; + f->output_arg->name = "res"; + slot = f->local_symbols->find_slot (f->output_arg, INSERT); gcc_assert (!*slot); - *slot = hsa_cfun->output_arg; + *slot = f->output_arg; } } +/* Generate function representation that corresponds to + a function declaration. */ + +hsa_function_representation * +hsa_generate_function_declaration (tree decl) +{ + hsa_function_representation *fun = XCNEW (hsa_function_representation); + + fun->declaration_p = true; + fun->decl = decl; + fun->name = xstrdup (get_declaration_name (decl)); + + gen_function_decl_parameters (fun, decl); + + return fun; +} + /* Generate HSAIL representation of the current function and write into a special section of the output file. If KERNEL is set, the function will be considered an HSA kernel callable from the host, otherwise it will be @@ -2406,20 +2479,21 @@ generate_hsa (bool kernel) vec ssa_map = vNULL; hsa_init_data_for_cfun (); + hsa_cfun->decl = cfun->decl; hsa_cfun->kern_p = kernel; ssa_map.safe_grow_cleared (SSANAMES (cfun)->length ()); hsa_cfun->name - = xstrdup (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); + = xstrdup (get_declaration_name (current_function_decl)); hsa_sanitize_name (hsa_cfun->name); if (hsa_cfun->kern_p) hsa_add_kern_decl_mapping (current_function_decl, hsa_cfun->name); - gen_function_parameters (ssa_map); + gen_function_def_parameters (hsa_cfun, &ssa_map); if (seen_error ()) goto fail; - gen_body_from_gimple (ssa_map); + gen_body_from_gimple (&ssa_map); if (seen_error ()) goto fail; diff --git a/gcc/hsa-regalloc.c b/gcc/hsa-regalloc.c index 5e34f9c..2521b16 100644 --- a/gcc/hsa-regalloc.c +++ b/gcc/hsa-regalloc.c @@ -58,6 +58,7 @@ naive_process_phi (hsa_insn_phi *phi) unsigned count = phi->operands.length (); for (unsigned i = 0; i < count; i++) { + gcc_checking_assert (phi->operands[i]); hsa_op_base *op = phi->operands[i]; hsa_bb *hbb; edge e; @@ -247,7 +248,6 @@ hsa_num_def_ops (hsa_insn_basic *insn) return 1; case BRIG_OPCODE_NOP: - case HSA_OPCODE_CALL_BLOCK: return 0; case BRIG_OPCODE_EXPAND: @@ -311,7 +311,7 @@ hsa_num_def_ops (hsa_insn_basic *insn) case BRIG_OPCODE_CALL: case BRIG_OPCODE_SCALL: case BRIG_OPCODE_ICALL: - return 1; /* ??? */ + return 0; case BRIG_OPCODE_RET: return 0; @@ -341,6 +341,9 @@ hsa_num_def_ops (hsa_insn_basic *insn) case BRIG_OPCODE_GROUPBASEPTR: case BRIG_OPCODE_KERNARGBASEPTR: return 1; /* ??? */ + + case HSA_OPCODE_ARG_BLOCK: + return 0; } } @@ -508,72 +511,6 @@ spill_at_interval (hsa_op_reg *reg, vec *active) cand->spill_sym->name_number = cand->order; } -/* Visit instruction INSN and fill in vector IND2REG if the instruction - contains a register (in memory). Number all insns by a global counter, - passed by INSN_ORDER argument. */ - -static void -visit_insn (hsa_insn_basic *insn, vec &ind2reg, int &insn_order) -{ - unsigned opi; - unsigned count = insn->operands.length (); - insn->number = insn_order++; - for (opi = 0; opi < count; opi++) - { - gcc_checking_assert (insn->operands[opi]); - hsa_op_reg **regaddr = insn_reg_addr (insn, opi); - if (regaddr) - ind2reg[(*regaddr)->order] = *regaddr; - } -} - -/* Remove definition in INSN according to bitmap WORK list. */ - -static void -remove_def_in_insn (bitmap &work, hsa_insn_basic *insn) -{ - unsigned opi; - unsigned ndefs = hsa_num_def_ops (insn); - for (opi = 0; opi < ndefs && insn->operands[opi]; opi++) - { - gcc_checking_assert (insn->operands[opi]); - hsa_op_reg **regaddr = insn_reg_addr (insn, opi); - if (regaddr) - bitmap_clear_bit (work, (*regaddr)->order); - } - unsigned count = insn->operands.length (); - for (; opi < count; opi++) - { - gcc_checking_assert (insn->operands[opi]); - hsa_op_reg **regaddr = insn_reg_addr (insn, opi); - if (regaddr) - bitmap_set_bit (work, (*regaddr)->order); - } -} - -/* Merge live range for an instruction INSN. */ - -static void -merge_live_range_for_insn (hsa_insn_basic *insn) -{ - unsigned opi; - unsigned ndefs = hsa_num_def_ops (insn); - unsigned count = insn->operands.length (); - for (opi = 0; opi < count; opi++) - { - gcc_checking_assert (insn->operands[opi]); - hsa_op_reg **regaddr = insn_reg_addr (insn, opi); - if (regaddr) - { - hsa_op_reg *reg = *regaddr; - if (opi < ndefs) - note_lr_begin (reg, insn->number); - else - note_lr_end (reg, insn->number); - } - } -} - /* Given the global register state CLASSES allocate all HSA virtual registers either to hardregs or to a spill symbol. */ @@ -606,16 +543,14 @@ linear_scan_regalloc (struct reg_class_desc *classes) hsa_insn_basic *insn; for (insn = hbb->first_insn; insn; insn = insn->next) { - visit_insn (insn, ind2reg, insn_order); - - if (is_a (insn)) + unsigned opi; + insn->number = insn_order++; + for (opi = 0; opi < insn->operands.length (); opi++) { - /* HSA call block insn contains insns that are used for passing - arguments and getting a return value, if returned. */ - hsa_insn_call_block *call = dyn_cast - (insn); - for (unsigned j = 0; j < call->input_arg_insns.length (); j++) - visit_insn (call->input_arg_insns[j], ind2reg, insn_order); + gcc_checking_assert (insn->operands[opi]); + hsa_op_reg **regaddr = insn_reg_addr (insn, opi); + if (regaddr) + ind2reg[(*regaddr)->order] = *regaddr; } } } @@ -661,17 +596,21 @@ linear_scan_regalloc (struct reg_class_desc *classes) hsa_insn_basic *insn; for (insn = hbb->last_insn; insn; insn = insn->prev) { - remove_def_in_insn (work, insn); - if (is_a (insn)) + unsigned opi; + unsigned ndefs = hsa_num_def_ops (insn); + for (opi = 0; opi < ndefs && insn->operands[opi]; opi++) + { + gcc_checking_assert (insn->operands[opi]); + hsa_op_reg **regaddr = insn_reg_addr (insn, opi); + if (regaddr) + bitmap_clear_bit (work, (*regaddr)->order); + } + for (; opi < insn->operands.length (); opi++) { - /* HSA call block insn contains insns that are used for - passing arguments and getting a return value, - if returned. */ - hsa_insn_call_block *call = dyn_cast - (insn); - - for (int j = call->input_arg_insns.length () - 1; j >= 0; j--) - remove_def_in_insn (work, call->input_arg_insns[j]); + gcc_checking_assert (insn->operands[opi]); + hsa_op_reg **regaddr = insn_reg_addr (insn, opi); + if (regaddr) + bitmap_set_bit (work, (*regaddr)->order); } } @@ -705,17 +644,20 @@ linear_scan_regalloc (struct reg_class_desc *classes) for (insn = hbb->last_insn; insn; insn = insn->prev) { - merge_live_range_for_insn (insn); - - if (is_a (insn)) + unsigned opi; + unsigned ndefs = hsa_num_def_ops (insn); + for (opi = 0; opi < insn->operands.length (); opi++) { - /* HSA call block insn contains insns that are used for passing - arguments and getting a return value, if returned. */ - hsa_insn_call_block *call = dyn_cast - (insn); - - for (int j = call->input_arg_insns.length () - 1; j >= 0; j--) - merge_live_range_for_insn (call->input_arg_insns[j]); + gcc_checking_assert (insn->operands[opi]); + hsa_op_reg **regaddr = insn_reg_addr (insn, opi); + if (regaddr) + { + hsa_op_reg *reg = *regaddr; + if (opi < ndefs) + note_lr_begin (reg, insn->number); + else + note_lr_end (reg, insn->number); + } } } if (hbb->first_insn) diff --git a/gcc/hsa.c b/gcc/hsa.c index fbf7370..730236b 100644 --- a/gcc/hsa.c +++ b/gcc/hsa.c @@ -303,9 +303,9 @@ hsa_destroy_insn (hsa_insn_basic *insn) call->~hsa_insn_call (); return; } - if (hsa_insn_call_block *block = dyn_cast (insn)) + if (hsa_insn_arg_block *block = dyn_cast (insn)) { - block->~hsa_insn_call_block (); + block->~hsa_insn_arg_block (); return; } insn->~hsa_insn_basic (); @@ -352,6 +352,9 @@ hsa_get_decl_kernel_mapping_name (unsigned i) void hsa_free_decl_kernel_mapping (void) { + if (hsa_decl_kernel_mapping == NULL) + return; + for (unsigned i = 0; i < hsa_decl_kernel_mapping->length (); ++i) free ((*hsa_decl_kernel_mapping)[i].name); ggc_free (hsa_decl_kernel_mapping); @@ -367,4 +370,17 @@ hsa_sanitize_name (char *p) *p = '_'; } +/* Return declaration name if exists. */ + +const char * +get_declaration_name (tree decl) +{ + if (!DECL_NAME (decl)) + sorry ("Support for HSA does not implement anonymous declarations"); + else + return IDENTIFIER_POINTER (DECL_NAME (decl)); + + return NULL; +} + #include "gt-hsa.h" diff --git a/gcc/hsa.h b/gcc/hsa.h index 1cff6db..b43a991 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -277,7 +277,7 @@ is_a_helper ::test (hsa_op_base *p) represent it nevertheless. */ #define HSA_OPCODE_PHI (-1) -#define HSA_OPCODE_CALL_BLOCK (-2) +#define HSA_OPCODE_ARG_BLOCK (-2) /* The number of operand pointers we can directly in an instruction. */ #define HSA_BRIG_INT_STORAGE_OPERANDS 5 @@ -530,6 +530,15 @@ public: /* Called function */ tree called_function; + /* Input formal arguments. */ + auto_vec input_args; + + /* Input arguments store instructions. */ + auto_vec input_arg_insns; + + /* Output argument, can be NULL for void functions. */ + hsa_symbol *output_arg; + /* Called function code reference. */ hsa_op_code_ref func; @@ -568,23 +577,14 @@ is_a_helper ::test (hsa_insn_basic *p) Emission of the instruction will produce multiple HSAIL instructions. */ -class hsa_insn_call_block : public hsa_insn_basic +class hsa_insn_arg_block : public hsa_insn_basic { public: - hsa_insn_call_block (); + hsa_insn_arg_block (BrigKind brig_kind, hsa_insn_call * call); void *operator new (size_t); - /* Input formal arguments. */ - auto_vec input_args; - - /* Input arguments store instructions. */ - auto_vec input_arg_insns; - - /* Output argument, can be NULL for void functions. */ - hsa_symbol *output_arg; - - /* Output argument load instruction. */ - hsa_insn_mem *output_arg_insn; + /* Kind of argument block. */ + BrigKind kind; /* Call instruction. */ hsa_insn_call *call_insn; @@ -599,9 +599,9 @@ private: template <> template <> inline bool -is_a_helper ::test (hsa_insn_basic *p) +is_a_helper ::test (hsa_insn_basic *p) { - return (p->opcode == HSA_OPCODE_CALL_BLOCK); + return (p->opcode == HSA_OPCODE_ARG_BLOCK); } /* Basic block of HSA instructions. */ @@ -713,7 +713,7 @@ public: /* Input arguments of the function. */ /* FIXME: Normally we'd use a vector, however our C++ vectors seem to have problems with derived classes, so for now we'll use a simple array. */ - int input_args_count; + unsigned input_args_count; /* Number of allocated register structures. */ int reg_count; @@ -726,6 +726,9 @@ public: /* Vector of pointers to spill symbols. */ vec spill_symbols; + /* Vector of called function declarations. */ + vec called_functions; + /* Instructions to be executed before the first BB from gimple. It's label is zero and must not be referenced, of course there are no PHIs. */ hsa_bb prologue; @@ -738,6 +741,12 @@ public: /* True if the function is kernel function. */ bool kern_p; + + /* True if the function representation is a declaration. */ + bool declaration_p; + + /* Function declaration tree. */ + tree decl; }; /* in hsa.c */ @@ -758,6 +767,7 @@ tree hsa_get_decl_kernel_mapping_decl (unsigned i); char *hsa_get_decl_kernel_mapping_name (unsigned i); void hsa_free_decl_kernel_mapping (void); void hsa_sanitize_name (char *p); +const char *get_declaration_name (tree decl); /* In hsa-gen.c. */ void hsa_build_append_simple_mov (hsa_op_reg *, hsa_op_base *, hsa_bb *); @@ -765,6 +775,7 @@ hsa_symbol *hsa_get_spill_symbol (BrigType16_t); hsa_op_reg *hsa_spill_in (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **); hsa_op_reg *hsa_spill_out (hsa_insn_basic *, hsa_op_reg *, hsa_op_reg **); hsa_bb *hsa_init_new_bb (basic_block); +hsa_function_representation *hsa_generate_function_declaration (tree decl); /* In hsa-regalloc.c. */ void hsa_regalloc (void); -- 2.1.4 --------------040108050001020409090104--