* [hsa] HSA: add support for function declaration emission and, fix RA.
@ 2015-06-30 13:20 Martin Liška
2015-06-30 13:33 ` Michael Matz
0 siblings, 1 reply; 3+ messages in thread
From: Martin Liška @ 2015-06-30 13:20 UTC (permalink / raw)
To: GCC Patches; +Cc: Michael Matz
[-- Attachment #1: Type: text/plain, Size: 246 bytes --]
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
[-- Attachment #2: 0001-HSA-add-support-for-function-declaration-emission-an.patch --]
[-- Type: text/x-patch, Size: 47488 bytes --]
From abb5eb3cf4f8569d2e003aabc5f078fcd17348a6 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
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 <mliska@suse.cz>
* 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_linkage_pair> 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 <hsa_noop_symbol_hasher>::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 <hsa_noop_symbol_hasher>::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<tree, BrigCodeOffset32_t> ();
- 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 <hsa_noop_symbol_hasher>::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 <hsa_noop_symbol_hasher>::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 <hsa_insn_call_block *> (insn))
+ if (hsa_insn_arg_block *arg_block = dyn_cast <hsa_insn_arg_block *> (insn))
{
- emit_call_block_insn (call_block);
+ emit_arg_block_insn (arg_block);
return;
}
if (hsa_insn_call *call = dyn_cast <hsa_insn_call *> (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<tree, BrigCodeOffset32_t> ();
+
+ 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 <hsa_insn_call_block *> (insn))
+ else if (is_a <hsa_insn_arg_block *> (insn))
{
- hsa_insn_call_block *call_block = as_a <hsa_insn_call_block *> (insn);
+ hsa_insn_arg_block *arg_block = as_a <hsa_insn_arg_block *> (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 <hsa_insn_call *> (insn))
{
hsa_insn_call *call = as_a <hsa_insn_call *> (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_insn_seg> *hsa_allocp_inst_seg;
static pool_allocator<hsa_insn_cmp> *hsa_allocp_inst_cmp;
static pool_allocator<hsa_insn_br> *hsa_allocp_inst_br;
static pool_allocator<hsa_insn_call> *hsa_allocp_inst_call;
-static pool_allocator<hsa_insn_call_block> *hsa_allocp_inst_call_block;
+static pool_allocator<hsa_insn_arg_block> *hsa_allocp_inst_arg_block;
static pool_allocator<hsa_bb> *hsa_allocp_bb;
static pool_allocator<hsa_symbol> *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_insn_br> ("HSA branching instructions", 16);
hsa_allocp_inst_call
= new pool_allocator<hsa_insn_call> ("HSA call instructions", 16);
- hsa_allocp_inst_call_block
- = new pool_allocator<hsa_insn_call_block> ("HSA call block instructions",
+ hsa_allocp_inst_arg_block
+ = new pool_allocator<hsa_insn_arg_block> ("HSA arg block instructions",
16);
hsa_allocp_bb = new pool_allocator<hsa_bb> ("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 <hsa_op_reg_p> ssa_map)
+hsa_reg_for_gimple_ssa (tree ssa, vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map,
+hsa_reg_for_gimple_ssa_reqtype (tree ssa, vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map,
uses. */
static hsa_op_with_type *
-gen_address_calculation (tree exp, hsa_bb *hbb, vec <hsa_op_reg_p> ssa_map,
+gen_address_calculation (tree exp, hsa_bb *hbb, vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+gen_hsa_addr (tree ref, hsa_bb *hbb, vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map,
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+ vec <hsa_op_reg_p> *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 <hsa_op_reg_p> ssa_map)
+gen_body_from_gimple (vec <hsa_op_reg_p> *ssa_map)
{
basic_block bb;
@@ -2321,12 +2322,64 @@ gen_body_from_gimple (vec <hsa_op_reg_p> 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 <hsa_op_reg_p> ssa_map)
+gen_function_def_parameters (hsa_function_representation *f,
+ vec <hsa_op_reg_p> *ssa_map)
{
tree parm;
int i, count = 0;
@@ -2334,30 +2387,33 @@ gen_function_parameters (vec <hsa_op_reg_p> 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 <hsa_op_reg_p> 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 <hsa_op_reg_p> 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 <hsa_op_reg_p> 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<hsa_op_reg*> *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<hsa_op_reg*> &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 <hsa_insn_call_block *> (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 <hsa_insn_call_block *>
- (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 <hsa_insn_call_block *> (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 <hsa_insn_call_block *>
- (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 <hsa_insn_call_block *> (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 <hsa_insn_call_block *>
- (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 <hsa_insn_call_block *> (insn))
+ if (hsa_insn_arg_block *block = dyn_cast <hsa_insn_arg_block *> (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 <hsa_op_code_list *>::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 <hsa_symbol *> input_args;
+
+ /* Input arguments store instructions. */
+ auto_vec <hsa_insn_mem *> 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 <hsa_insn_call *>::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 <hsa_symbol *> input_args;
-
- /* Input arguments store instructions. */
- auto_vec <hsa_insn_mem *> 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 <hsa_insn_call_block *>::test (hsa_insn_basic *p)
+is_a_helper <hsa_insn_arg_block *>::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 <struct hsa_symbol *> spill_symbols;
+ /* Vector of called function declarations. */
+ vec <tree> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [hsa] HSA: add support for function declaration emission and, fix RA.
2015-06-30 13:20 [hsa] HSA: add support for function declaration emission and, fix RA Martin Liška
@ 2015-06-30 13:33 ` Michael Matz
2015-06-30 13:36 ` Martin Liška
0 siblings, 1 reply; 3+ messages in thread
From: Michael Matz @ 2015-06-30 13:33 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 460 bytes --]
Hi,
On Tue, 30 Jun 2015, Martin Liška wrote:
> 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.
Given that BRIG forces us to have a multi-level layering of instructions
in one way or the other, I indeed think this new representation is nicer,
so thanks.
Ciao,
Michael.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [hsa] HSA: add support for function declaration emission and, fix RA.
2015-06-30 13:33 ` Michael Matz
@ 2015-06-30 13:36 ` Martin Liška
0 siblings, 0 replies; 3+ messages in thread
From: Martin Liška @ 2015-06-30 13:36 UTC (permalink / raw)
To: Michael Matz; +Cc: GCC Patches
On 06/30/2015 03:28 PM, Michael Matz wrote:
> Hi,
>
> On Tue, 30 Jun 2015, Martin Liška wrote:
>
>> 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.
>
> Given that BRIG forces us to have a multi-level layering of instructions
> in one way or the other, I indeed think this new representation is nicer,
> so thanks.
>
>
> Ciao,
> Michael.
>
Yeah, I introduced the new insn which is used just as a placeholder that is used
to emit necessary block arguments. Having insns in a single stream just much nicer.
Martin
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-06-30 13:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-30 13:20 [hsa] HSA: add support for function declaration emission and, fix RA Martin Liška
2015-06-30 13:33 ` Michael Matz
2015-06-30 13:36 ` Martin Liška
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).