* [HSA] Back-end enhancement and various fixes
@ 2015-11-02 10:18 Martin Liška
0 siblings, 0 replies; only message in thread
From: Martin Liška @ 2015-11-02 10:18 UTC (permalink / raw)
To: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 313 bytes --]
Hello.
In the following series, I enhance HSA BE to correctly support aggregate types (as function call arguments and return types).
Apart from that, we should not ICE in situations where we have a non-trivial memory reference. Finally, many memory leaks were
fixed and a lot of refactoring is included.
Martin
[-- Attachment #2: 0001-HSA-fix-generation-of-address-that-end-as-SSA_NAME-o.patch --]
[-- Type: text/x-patch, Size: 6876 bytes --]
From c5006ca75912bdab8256fe4670645d5f1ad54a14 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 26 Oct 2015 16:58:26 +0100
Subject: [PATCH 1/9] HSA: fix generation of address that end as SSA_NAME or
VAR_DECL.
gcc/ChangeLog:
2015-10-22 Martin Liska <mliska@suse.cz>
* hsa-brig.c (emit_function_directives): Emit private variables.
* hsa-gen.c (hsa_function_representation::~hsa_function_representation):
Release the container.
(hsa_function_representation::create_hsa_temporary): New function.
(gen_hsa_addr): Handle properly SSA_NAMEs and VAR_DECLs.
* hsa.h (hsa_function_representation::m_private_variables):
Declare new variable.
---
gcc/hsa-brig.c | 7 ++++++-
gcc/hsa-gen.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
gcc/hsa.h | 14 ++++++++++++++
3 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index be7ef59..0c26b58 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -626,6 +626,7 @@ emit_function_directives (hsa_function_representation *f, bool is_declaration)
if (TREE_CODE ((*iter)->m_decl) == VAR_DECL)
count++;
count += f->m_spill_symbols.length ();
+ count += f->m_private_variables.length ();
}
next_toplev_off = scoped_off + count * sizeof (struct BrigDirectiveVariable);
@@ -685,7 +686,11 @@ emit_function_directives (hsa_function_representation *f, bool is_declaration)
emit_directive_variable (sym);
brig_insn_count++;
}
-
+ for (unsigned i = 0; i < f->m_private_variables.length (); i++)
+ {
+ emit_directive_variable (f->m_private_variables[i]);
+ brig_insn_count++;
+ }
}
return ptr_to_fndir;
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index c36c9e0..15f9050 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -228,10 +228,10 @@ hsa_function_representation::hsa_function_representation
(tree fdecl, bool kernel_p): m_name (NULL),
m_input_args_count (0), m_reg_count (0), m_input_args (NULL),
m_output_arg (NULL), m_spill_symbols (vNULL), m_readonly_variables (vNULL),
- m_called_functions (vNULL), m_hbb_count (0), m_in_ssa (true),
- m_kern_p (kernel_p), m_declaration_p (false), m_decl (fdecl),
+ m_private_variables (vNULL), m_called_functions (vNULL), m_hbb_count (0),
+ m_in_ssa (true), m_kern_p (kernel_p), m_declaration_p (false), m_decl (fdecl),
m_shadow_reg (NULL), m_kernel_dispatch_count (0), m_maximum_omp_data_size (0),
- m_seen_error (false)
+ m_seen_error (false), m_temp_symbol_count (0)
{
int sym_init_len = (vec_safe_length (cfun->local_decls) / 2) + 1;;
m_local_symbols = new hash_table <hsa_noop_symbol_hasher> (sym_init_len);
@@ -251,6 +251,7 @@ hsa_function_representation::~hsa_function_representation ()
m_spill_symbols.release ();
m_readonly_variables.release ();
+ m_private_variables.release ();
m_called_functions.release ();
}
@@ -284,6 +285,24 @@ bool hsa_function_representation::has_shadow_reg_p ()
return m_shadow_reg != NULL;
}
+void
+hsa_function_representation::init_extra_bbs ()
+{
+ hsa_init_new_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ hsa_init_new_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
+}
+
+hsa_symbol *
+hsa_function_representation::create_hsa_temporary (BrigType16_t type)
+{
+ hsa_symbol *s = new hsa_symbol (type, BRIG_SEGMENT_PRIVATE,
+ BRIG_LINKAGE_FUNCTION);
+ s->m_name_number = m_temp_symbol_count++;
+
+ hsa_cfun->m_private_variables.safe_push (s);
+ return s;
+}
+
/* Allocate HSA structures that we need only while generating with this. */
static void
@@ -1711,6 +1730,13 @@ process_mem_base (tree base, hsa_symbol **symbol, BrigType16_t *addrtype,
gcc_unreachable ();
}
+/* Forward declaration of a function. */
+
+static void
+gen_hsa_addr_insns (tree val, hsa_op_reg *dest, hsa_bb *hbb,
+ vec <hsa_op_reg_p> *ssa_map);
+
+
/* Generate HSA address operand for a given tree memory reference REF. If
instructions need to be created to calculate the address, they will be added
to the end of HBB, SSA_MAP is an array mapping gimple SSA names to HSA
@@ -1731,6 +1757,7 @@ gen_hsa_addr (tree ref, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map,
tree varoffset = NULL_TREE;
BrigType16_t addrtype = hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT);
HOST_WIDE_INT bitsize = 0, bitpos = 0;
+ BrigType16_t flat_addrtype = hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT);
if (TREE_CODE (ref) == STRING_CST)
{
@@ -1762,8 +1789,27 @@ gen_hsa_addr (tree ref, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map,
switch (TREE_CODE (ref))
{
case ADDR_EXPR:
- gcc_unreachable ();
+ {
+ addrtype = hsa_get_segment_addr_type (BRIG_SEGMENT_PRIVATE);
+ symbol = hsa_cfun->create_hsa_temporary (flat_addrtype);
+ hsa_op_reg *r = new hsa_op_reg (flat_addrtype);
+ gen_hsa_addr_insns (ref, r, hbb, ssa_map);
+ hbb->append_insn (new hsa_insn_mem (BRIG_OPCODE_ST, r->m_type,
+ r, new hsa_op_address (symbol)));
+
+ break;
+ }
+ case SSA_NAME:
+ {
+ addrtype = hsa_get_segment_addr_type (BRIG_SEGMENT_PRIVATE);
+ symbol = hsa_cfun->create_hsa_temporary (flat_addrtype);
+ hsa_op_reg *r = hsa_reg_for_gimple_ssa (ref, ssa_map);
+
+ hbb->append_insn (new hsa_insn_mem (BRIG_OPCODE_ST, r->m_type,
+ r, new hsa_op_address (symbol)));
+ break;
+ }
case PARM_DECL:
case VAR_DECL:
case RESULT_DECL:
@@ -1821,7 +1867,6 @@ gen_hsa_addr (tree ref, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map,
HSA_SORRY_AT (EXPR_LOCATION (origref),
"support for HSA does not implement function pointers");
goto out;
- case SSA_NAME:
default:
HSA_SORRY_ATV (EXPR_LOCATION (origref), "support for HSA does "
"not implement memory access to %E", origref);
diff --git a/gcc/hsa.h b/gcc/hsa.h
index 3c83d61..d38255f 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -940,6 +940,14 @@ public:
shadow register. */
bool has_shadow_reg_p ();
+ /* The entry/exit blocks don't contain incoming code,
+ but the HSA generator might use them to put code into,
+ so we need hsa_bb instances of them. */
+ void init_extra_bbs ();
+
+ /* Create a private symbol of requested TYPE. */
+ hsa_symbol *create_hsa_temporary (BrigType16_t type);
+
/* Name of the function. */
char *m_name;
@@ -967,6 +975,9 @@ public:
noni-addressable variables with a constructor). */
vec <struct hsa_symbol *> m_readonly_variables;
+ /* Private function artificial variables. */
+ vec <struct hsa_symbol *> m_private_variables;
+
/* Vector of called function declarations. */
vec <tree> m_called_functions;
@@ -998,6 +1009,9 @@ public:
/* Return true if there's an HSA-specific warning already seen. */
bool m_seen_error;
+
+ /* Counter for temporary symbols created in the function representation. */
+ unsigned m_temp_symbol_count;
};
enum hsa_function_kind
--
2.6.2
[-- Attachment #3: 0002-HSA-Support-aggregate-type-as-a-function-return-type.patch --]
[-- Type: text/x-patch, Size: 5159 bytes --]
From 592d9c22f378067002ffb6d852049e7ae7acb787 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 26 Oct 2015 17:04:28 +0100
Subject: [PATCH 2/9] HSA: Support aggregate type as a function return type.
gcc/ChangeLog:
2015-10-22 Martin Liska <mliska@suse.cz>
* hsa-gen.c (gen_hsa_insns_for_direct_call): Support aggregate
type as a function return type.
(gen_hsa_insns_for_return): Likewise.
(hsa_symbol::total_byte_size): New function.
* hsa.h (struct hsa_symbol): Declare it.
---
gcc/hsa-gen.c | 82 +++++++++++++++++++++++++++++++++++------------------------
gcc/hsa.h | 6 +++++
2 files changed, 55 insertions(+), 33 deletions(-)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 15f9050..94e50c8 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -221,6 +221,25 @@ hsa_symbol::hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
{
}
+void *
+hsa_symbol::operator new (size_t)
+{
+ return hsa_allocp_symbols->vallocate ();
+}
+
+unsigned HOST_WIDE_INT
+hsa_symbol::total_byte_size ()
+{
+ unsigned HOST_WIDE_INT s = hsa_type_bit_size (~BRIG_TYPE_ARRAY_MASK & m_type);
+ gcc_assert (s % BITS_PER_UNIT == 0);
+ s /= BITS_PER_UNIT;
+
+ if (m_dim)
+ s *= m_dim;
+
+ return s;
+}
+
/* Constructor of class representing global HSA function/kernel information and
state. */
@@ -3243,14 +3262,6 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
hsa_insn_mem *result_insn = NULL;
if (!VOID_TYPE_P (result_type))
{
- if (AGGREGATE_TYPE_P (result_type))
- {
- HSA_SORRY_ATV (gimple_location (stmt),
- "support for HSA does not implement returning a value "
- "which is of an aggregate type %T", result_type);
- return;
- }
-
hsa_op_address *addr = gen_hsa_addr_for_arg (result_type, -1);
/* Even if result of a function call is unused, we have to emit
@@ -3258,25 +3269,25 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
if (result)
{
tree lhs_type = TREE_TYPE (result);
- if (AGGREGATE_TYPE_P (lhs_type))
- {
- HSA_SORRY_ATV (gimple_location (stmt), "support for HSA does not "
- "implement assignment of a returned value "
- "which is of an aggregate type %T", lhs_type);
- return;
- }
-
- BrigType16_t mtype = mem_type_for_type
- (hsa_type_for_scalar_tree_type (lhs_type, false));
if (hsa_seen_error ())
return;
- hsa_op_reg *dst = hsa_reg_for_gimple_ssa (result, ssa_map);
-
- result_insn = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dst, addr);
+ if (AGGREGATE_TYPE_P (lhs_type))
+ {
+ hsa_op_address *result_addr = gen_hsa_addr (result, hbb, ssa_map);
+ gen_hsa_memory_copy (hbb, result_addr, addr,
+ addr->m_symbol->total_byte_size ());
+ }
+ else
+ {
+ BrigType16_t mtype = mem_type_for_type
+ (hsa_type_for_scalar_tree_type (lhs_type, false));
- hbb->append_insn (result_insn);
+ hsa_op_reg *dst = hsa_reg_for_gimple_ssa (result, ssa_map);
+ result_insn = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dst, addr);
+ hbb->append_insn (result_insn);
+ }
}
call_insn->m_output_arg = addr->m_symbol;
@@ -3314,21 +3325,26 @@ gen_hsa_insns_for_return (greturn *stmt, hsa_bb *hbb,
tree retval = gimple_return_retval (stmt);
if (retval)
{
+ hsa_op_address *addr = new hsa_op_address (hsa_cfun->m_output_arg);
+
if (AGGREGATE_TYPE_P (TREE_TYPE (retval)))
{
- HSA_SORRY_AT (gimple_location (stmt),
- "HSA does not support return "
- "statement with an aggregate value type");
- return;
+ hsa_op_address *retval_addr = gen_hsa_addr (retval, hbb, ssa_map);
+ gen_hsa_memory_copy (hbb, addr, retval_addr,
+ hsa_cfun->m_output_arg->total_byte_size ());
}
+ else
+ {
+ BrigType16_t mtype = mem_type_for_type
+ (hsa_type_for_scalar_tree_type (TREE_TYPE (retval), false));
- /* Store of return value. */
- BrigType16_t mtype = mem_type_for_type
- (hsa_type_for_scalar_tree_type (TREE_TYPE (retval), false));
- hsa_op_address *addr = new hsa_op_address (hsa_cfun->m_output_arg);
- hsa_op_base *src = hsa_reg_or_immed_for_gimple_op (retval, hbb, ssa_map);
- hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src, addr);
- hbb->append_insn (mem);
+ /* Store of return value. */
+ hsa_op_base *src = hsa_reg_or_immed_for_gimple_op (retval, hbb,
+ ssa_map);
+ hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src,
+ addr);
+ hbb->append_insn (mem);
+ }
}
/* HSAIL return instruction emission. */
diff --git a/gcc/hsa.h b/gcc/hsa.h
index d38255f..f4184f9 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -60,6 +60,12 @@ struct hsa_symbol
hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
BrigLinkage8_t linkage);
+ /* New operator to allocate HSA symbol from pool alloc. */
+ void *operator new (size_t);
+
+ /* Return total size of the symbol. */
+ unsigned HOST_WIDE_INT total_byte_size ();
+
/* Pointer to the original tree, which is PARM_DECL for input parameters and
RESULT_DECL for the output parameters. */
tree m_decl;
--
2.6.2
[-- Attachment #4: 0003-HSA-convert-actual-argument-types-to-formal-types.patch --]
[-- Type: text/x-patch, Size: 4104 bytes --]
From 5b148fbe1110bcc8a7c826163451e04743b84143 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 26 Oct 2015 17:05:09 +0100
Subject: [PATCH 3/9] HSA: convert actual argument types to formal types.
gcc/ChangeLog:
2015-10-16 Martin Liska <mliska@suse.cz>
* hsa-gen.c (gen_hsa_insns_for_direct_call): Convert types of actual
arguments to formal types arguments.
(get_format_argument_type): New function.
(hsa_reg_for_gimple_ssa): Fix coding style.
---
gcc/hsa-gen.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 94e50c8..050475c 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -1130,7 +1130,7 @@ hsa_reg_for_gimple_ssa (tree ssa, vec <hsa_op_reg_p> *ssa_map)
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),
+ hreg = new hsa_op_reg (hsa_type_for_scalar_tree_type (TREE_TYPE (ssa),
true));
hreg->m_gimple_ssa = ssa;
(*ssa_map)[SSA_NAME_VERSION (ssa)] = hreg;
@@ -3201,6 +3201,20 @@ verify_function_arguments (tree decl)
}
}
+/* Return BRIG type for FORMAL_ARG_TYPE. If the formal argument type is NULL,
+ return ACTUAL_ARG_TYPE. */
+
+static BrigType16_t
+get_format_argument_type (tree formal_arg_type, BrigType16_t actual_arg_type)
+{
+ if (formal_arg_type == NULL)
+ return actual_arg_type;
+
+ BrigType16_t decl_type = hsa_type_for_scalar_tree_type
+ (formal_arg_type, false);
+ return mem_type_for_type (decl_type);
+}
+
/* Generate HSA instructions for a direct call instruction.
Instructions will be appended to HBB, which also needs to be the
corresponding structure to the basic_block of STMT. SSA_MAP maps gimple SSA
@@ -3223,11 +3237,15 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
(BRIG_KIND_DIRECTIVE_ARG_BLOCK_START, call_insn);
hbb->append_insn (arg_start);
+ tree parm_type_chain = TYPE_ARG_TYPES (gimple_call_fntype (stmt));
+
/* Preparation of arguments that will be passed to function. */
const unsigned args = gimple_call_num_args (stmt);
for (unsigned i = 0; i < args; ++i)
{
tree parm = gimple_call_arg (stmt, (int)i);
+ tree parm_decl_type = parm_type_chain != NULL_TREE
+ ? TREE_VALUE (parm_type_chain) : NULL_TREE;
if (AGGREGATE_TYPE_P (TREE_TYPE (parm)))
{
@@ -3237,20 +3255,36 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
return;
}
- BrigType16_t mtype = mem_type_for_type (hsa_type_for_scalar_tree_type
- (TREE_TYPE (parm), false));
+ hsa_op_with_type *src = hsa_reg_or_immed_for_gimple_op (parm, hbb,
+ ssa_map);
+ if (parm_decl_type != NULL && AGGREGATE_TYPE_P (parm_decl_type))
+ {
+ HSA_SORRY_AT (gimple_location (stmt),
+ "support for HSA does not implement an aggregate "
+ "formal argument in a function call, while actual "
+ "argument is not an aggregate");
+ return;
+ }
+ BrigType16_t formal_arg_type = get_format_argument_type
+ (parm_decl_type, src->m_type);
if (hsa_seen_error ())
return;
- hsa_op_address *addr = gen_hsa_addr_for_arg (TREE_TYPE (parm), i);
- hsa_op_base *src = hsa_reg_or_immed_for_gimple_op (parm, hbb, ssa_map);
- hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src, addr);
+ if (src->m_type != formal_arg_type)
+ src = src->get_in_type (formal_arg_type, hbb);
+
+ hsa_op_address *addr = gen_hsa_addr_for_arg
+ (parm_decl_type != NULL_TREE ? parm_decl_type: TREE_TYPE (parm), i);
+ hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, formal_arg_type,
+ src, addr);
- call_insn->m_input_args.safe_push (addr->m_symbol);
hbb->append_insn (mem);
+ call_insn->m_input_args.safe_push (addr->m_symbol);
call_insn->m_args_symbols.safe_push (addr->m_symbol);
+ if (parm_type_chain)
+ parm_type_chain = TREE_CHAIN (parm_type_chain);
}
call_insn->m_args_code_list = new hsa_op_code_list (args);
--
2.6.2
[-- Attachment #5: 0004-HSA-handle-taking-an-address-of-an-argument.patch --]
[-- Type: text/x-patch, Size: 5191 bytes --]
From 93f9684b50033e3c68e80ec0fbb25d992e1cafdf Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 22 Oct 2015 18:22:15 +0200
Subject: [PATCH 4/9] HSA: handle taking an address of an argument.
gcc/ChangeLog:
2015-10-22 Martin Liska <mliska@suse.cz>
* hsa-gen.c(gen_hsa_insns_for_direct_call): Support aggregate argument
types.
(gen_function_def_parameters): Copy function arguments to private
symbols.
---
gcc/hsa-gen.c | 88 ++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 34 deletions(-)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 050475c..ec0762e 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3246,40 +3246,44 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
tree parm = gimple_call_arg (stmt, (int)i);
tree parm_decl_type = parm_type_chain != NULL_TREE
? TREE_VALUE (parm_type_chain) : NULL_TREE;
+ hsa_op_address *addr;
if (AGGREGATE_TYPE_P (TREE_TYPE (parm)))
{
- HSA_SORRY_AT (gimple_location (stmt),
- "support for HSA does not "
- "implement an aggregate argument in a function call");
- return;
+ addr = gen_hsa_addr_for_arg (TREE_TYPE (parm), i);
+ hsa_op_address *src = gen_hsa_addr (parm, hbb, ssa_map);
+ gen_hsa_memory_copy (hbb, addr, src,
+ addr->m_symbol->total_byte_size ());
}
-
- hsa_op_with_type *src = hsa_reg_or_immed_for_gimple_op (parm, hbb,
- ssa_map);
- if (parm_decl_type != NULL && AGGREGATE_TYPE_P (parm_decl_type))
+ else
{
- HSA_SORRY_AT (gimple_location (stmt),
- "support for HSA does not implement an aggregate "
- "formal argument in a function call, while actual "
- "argument is not an aggregate");
- return;
- }
+ hsa_op_with_type *src = hsa_reg_or_immed_for_gimple_op (parm, hbb,
+ ssa_map);
- BrigType16_t formal_arg_type = get_format_argument_type
- (parm_decl_type, src->m_type);
- if (hsa_seen_error ())
- return;
+ if (parm_decl_type != NULL && AGGREGATE_TYPE_P (parm_decl_type))
+ {
+ HSA_SORRY_AT (gimple_location (stmt),
+ "support for HSA does not implement an aggregate "
+ "formal argument in a function call, while actual "
+ "argument is not an aggregate");
+ return;
+ }
- if (src->m_type != formal_arg_type)
- src = src->get_in_type (formal_arg_type, hbb);
+ BrigType16_t formal_arg_type = get_format_argument_type
+ (parm_decl_type, src->m_type);
+ if (hsa_seen_error ())
+ return;
- hsa_op_address *addr = gen_hsa_addr_for_arg
- (parm_decl_type != NULL_TREE ? parm_decl_type: TREE_TYPE (parm), i);
- hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, formal_arg_type,
- src, addr);
+ if (src->m_type != formal_arg_type)
+ src = src->get_in_type (formal_arg_type, hbb);
- hbb->append_insn (mem);
+ addr = gen_hsa_addr_for_arg
+ (parm_decl_type != NULL_TREE ? parm_decl_type: TREE_TYPE (parm), i);
+ hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, formal_arg_type,
+ src, addr);
+
+ hbb->append_insn (mem);
+ }
call_insn->m_input_args.safe_push (addr->m_symbol);
call_insn->m_args_symbols.safe_push (addr->m_symbol);
@@ -4996,14 +5000,33 @@ gen_function_def_parameters (hsa_function_representation *f,
f->m_input_args[i].m_segment = f->m_kern_p ? BRIG_SEGMENT_KERNARG :
BRIG_SEGMENT_ARG;
-
f->m_input_args[i].m_linkage = BRIG_LINKAGE_FUNCTION;
f->m_input_args[i].m_name = hsa_get_declaration_name (parm);
+ hsa_symbol *arg = &f->m_input_args[i];
+
+ /* Copy all input arguments and create corresponding private symbols
+ for them. */
+ hsa_symbol *private_arg;
+ hsa_op_address *parm_addr = new hsa_op_address (arg);
- slot = f->m_local_symbols->find_slot (&f->m_input_args[i],
- INSERT);
+ if (TREE_ADDRESSABLE (parm)
+ || (!is_gimple_reg (parm) && !TREE_READONLY (parm)))
+ {
+ private_arg = hsa_cfun->create_hsa_temporary (arg->m_type);
+ hsa_cfun->m_private_variables.safe_push (private_arg);
+ fillup_sym_for_decl (parm, private_arg);
+ f->m_private_variables.safe_push (private_arg);
+
+ hsa_op_address *private_arg_addr = new hsa_op_address (private_arg);
+ gen_hsa_memory_copy (prologue, private_arg_addr, parm_addr,
+ arg->total_byte_size ());
+ }
+ else
+ private_arg = arg;
+
+ slot = f->m_local_symbols->find_slot (private_arg, INSERT);
gcc_assert (!*slot);
- *slot = &f->m_input_args[i];
+ *slot = private_arg;
if (is_gimple_reg (parm))
{
@@ -5013,12 +5036,9 @@ gen_function_def_parameters (hsa_function_representation *f,
BrigType16_t mtype = mem_type_for_type
(hsa_type_for_scalar_tree_type (TREE_TYPE (ddef), false));
hsa_op_reg *dest = hsa_reg_for_gimple_ssa (ddef, ssa_map);
- hsa_op_address *addr;
-
- addr = gen_hsa_addr (parm, prologue, ssa_map);
hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, mtype,
- dest, addr);
- gcc_assert (!addr->m_reg);
+ dest, parm_addr);
+ gcc_assert (!parm_addr->m_reg);
prologue->append_insn (mem);
}
}
--
2.6.2
[-- Attachment #6: 0005-HSA-hsa_symbol-refactoring-and-memory-allocation-fix.patch --]
[-- Type: text/x-patch, Size: 31545 bytes --]
From a34342ce566bba60b12a550496b747370938cc52 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 27 Oct 2015 11:58:12 +0100
Subject: [PATCH 5/9] HSA: hsa_symbol refactoring and memory allocation fix-up
gcc/ChangeLog:
* hsa-brig.c (emit_function_directives): Simplify emission
of private symbols.
(emit_arg_block_insn): Use different property of hsa_symbol.
(emit_insn): Remove usage of comment_instructions.
(hsa_brig_emit_function): Properly release
comment_instructions vector.
* hsa-dump.c (dump_hsa_insn_1): Use different property of
hsa_symbol.
* hsa-gen.c (hsa_symbol::operator new):
(hsa_symbol::fillup_for_decl): New function.
(hsa_function_representation::~hsa_function_representation):
Release memory.
(hsa_function_representation::get_shadow_reg): Use ctor of
hsa_symbol.
(hsa_init_data_for_cfun): Remove BB allocation.
(hsa_deinit_data_for_cfun): Call ctor for all insns.
(fillup_sym_for_decl): Remove.
(get_symbol_for_decl): Use ctor of hsa_symbol.
(hsa_insn_basic::hsa_insn_basic): Register newly allocated
instance in hsa_instances.
(hsa_insn_call::~hsa_insn_call): Likewise.
(gen_hsa_addr_for_arg): Use ctor of hsa_symbol.
(gen_hsa_insns_for_direct_call): Do not push to remove
container.
(gen_hsa_insns_for_call): Small code refactoring.
(get_function_arg_count): Remove function.
(gen_function_decl_parameters): Use vector instread of
dynamically allocated memory array.
(gen_function_def_parameters): Do it method of
hsa_function_representation.
(hsa_generate_function_declaration): Use ctor instread of
XCNEW.
(convert_switch_statements): Release leaked memory.
(emit_hsa_module_variables): Use newly added function
init_extra_bbs.
(generate_hsa): Do not use removed argument.
* hsa.c (hsa_deinit_compilation_unit_data): Release
hsa_num_threads.
(hsa_destroy_insn): Handle hsa_insn_sbr and hsa_insn_comment.
(hsa_init_compilation_unit_data): Initialize
hsa_global_variable_symbols.
(hsa_deinit_compilation_unit_data): Do not release deleted
container.
(hsa_fail_cfun): Do not initialize hsa_failed_functions.
* hsa.h (struct hsa_symbol): Declare new methods and remove
unused properties.
---
gcc/hsa-brig.c | 50 +++--------
gcc/hsa-dump.c | 6 +-
gcc/hsa-gen.c | 279 +++++++++++++++++++++++++++------------------------------
gcc/hsa.c | 22 +++--
gcc/hsa.h | 45 +++++-----
5 files changed, 182 insertions(+), 220 deletions(-)
diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index 0c26b58..a09415c 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -137,9 +137,6 @@ static hash_map <tree, BrigDirectiveExecutable *> *emitted_declarations;
/* List of sbr instructions. */
static vec <hsa_insn_sbr *> *switch_instructions;
-/* List of comment instructions. */
-static vec <hsa_insn_comment *> *comment_instructions;
-
struct function_linkage_pair
{
function_linkage_pair (tree decl, unsigned int off):
@@ -615,16 +612,10 @@ emit_function_directives (hsa_function_representation *f, bool is_declaration)
inarg_off = brig_code.total_size + sizeof(fndir)
+ (f->m_output_arg ? sizeof (struct BrigDirectiveVariable) : 0);
scoped_off = inarg_off
- + f->m_input_args_count * sizeof (struct BrigDirectiveVariable);
+ + f->m_input_args.length () * sizeof (struct BrigDirectiveVariable);
if (!f->m_declaration_p)
{
- for (hash_table <hsa_noop_symbol_hasher>::iterator iter
- = f->m_local_symbols->begin ();
- iter != f->m_local_symbols->end ();
- ++iter)
- if (TREE_CODE ((*iter)->m_decl) == VAR_DECL)
- count++;
count += f->m_spill_symbols.length ();
count += f->m_private_variables.length ();
}
@@ -636,7 +627,7 @@ emit_function_directives (hsa_function_representation *f, bool is_declaration)
fndir.base.kind = htole16 (f->m_kern_p ? BRIG_KIND_DIRECTIVE_KERNEL
: BRIG_KIND_DIRECTIVE_FUNCTION);
fndir.name = htole32 (name_offset);
- fndir.inArgCount = htole16 (f->m_input_args_count);
+ fndir.inArgCount = htole16 (f->m_input_args.length ());
fndir.outArgCount = htole16 (f->m_output_arg ? 1 : 0);
fndir.firstInArg = htole32 (inarg_off);
fndir.firstCodeBlockEntry = htole32 (scoped_off);
@@ -667,20 +658,11 @@ emit_function_directives (hsa_function_representation *f, bool is_declaration)
if (f->m_output_arg)
emit_directive_variable (f->m_output_arg);
- for (unsigned i = 0; i < f->m_input_args_count; i++)
- emit_directive_variable (&f->m_input_args[i]);
+ for (unsigned i = 0; i < f->m_input_args.length (); i++)
+ emit_directive_variable (f->m_input_args[i]);
if (!f->m_declaration_p)
{
- for (hash_table <hsa_noop_symbol_hasher>::iterator iter
- = f->m_local_symbols->begin ();
- iter != f->m_local_symbols->end ();
- ++iter)
- {
- if (TREE_CODE ((*iter)->m_decl) == VAR_DECL)
- brig_insn_count++;
- emit_directive_variable (*iter);
- }
for (int i = 0; f->m_spill_symbols.iterate (i, &sym); i++)
{
emit_directive_variable (sym);
@@ -1526,7 +1508,7 @@ emit_cvt_insn (hsa_insn_basic *insn)
within a call block instruction. */
static void
-emit_m_call_insn (hsa_insn_basic *insn)
+emit_call_insn (hsa_insn_basic *insn)
{
hsa_insn_call *call = dyn_cast <hsa_insn_call *> (insn);
struct BrigInstBr repr;
@@ -1584,7 +1566,7 @@ emit_arg_block_insn (hsa_insn_arg_block *insn)
brig_insn_count++;
}
- if (insn->m_call_insn->m_result_symbol)
+ if (insn->m_call_insn->m_output_arg)
{
insn->m_call_insn->m_result_code_list->m_offsets[0] = htole32
(emit_directive_variable (insn->m_call_insn->m_output_arg));
@@ -1795,16 +1777,11 @@ emit_insn (hsa_insn_basic *insn)
}
if (hsa_insn_call *call = dyn_cast <hsa_insn_call *> (insn))
{
- emit_m_call_insn (call);
+ emit_call_insn (call);
return;
}
if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
{
- if (comment_instructions == NULL)
- comment_instructions = new vec <hsa_insn_comment *> ();
-
- comment_instructions->safe_push (comment);
-
emit_comment_insn (comment);
return;
}
@@ -1915,6 +1892,10 @@ hsa_brig_emit_function (void)
hbb->m_label_ref.m_directive_offset;
}
}
+
+ switch_instructions->release ();
+ delete switch_instructions;
+ switch_instructions = NULL;
}
if (dump_file)
@@ -1923,15 +1904,6 @@ hsa_brig_emit_function (void)
dump_hsa_cfun (dump_file);
}
- if (comment_instructions)
- for (unsigned i = 0; i < comment_instructions->length (); i++)
- (*comment_instructions)[i]->release_string ();
-
- delete switch_instructions;
- switch_instructions = NULL;
- delete comment_instructions;
- comment_instructions = NULL;
-
emit_queued_operands ();
}
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index f926e39..1a68bc2 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -954,15 +954,15 @@ dump_hsa_insn_1 (FILE *f, hsa_insn_basic *insn, int *indent)
fprintf (f, "call &%s", name);
- if (call->m_result_symbol)
+ if (call->m_output_arg)
fprintf (f, "(%%res) ");
fprintf (f, "(");
- for (unsigned i = 0; i < call->m_args_symbols.length (); i++)
+ for (unsigned i = 0; i < call->m_input_args.length (); i++)
{
fprintf (f, "%%__arg_%u", i);
- if (i != call->m_args_symbols.length () - 1)
+ if (i != call->m_input_args.length () - 1)
fprintf (f, ", ");
}
fprintf (f, ")");
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index ec0762e..4a30eb0 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -195,7 +195,9 @@ static object_allocator<hsa_insn_arg_block> *hsa_allocp_inst_arg_block;
static object_allocator<hsa_insn_comment> *hsa_allocp_inst_comment;
static object_allocator<hsa_insn_queue> *hsa_allocp_inst_queue;
static object_allocator<hsa_bb> *hsa_allocp_bb;
-static object_allocator<hsa_symbol> *hsa_allocp_symbols;
+
+/* List of pointers to all instructions that come from an object allocator. */
+static vec <hsa_insn_basic *> hsa_instructions;
/* Vectors with selected instructions and operands that need
a destruction. */
@@ -221,12 +223,6 @@ hsa_symbol::hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
{
}
-void *
-hsa_symbol::operator new (size_t)
-{
- return hsa_allocp_symbols->vallocate ();
-}
-
unsigned HOST_WIDE_INT
hsa_symbol::total_byte_size ()
{
@@ -240,12 +236,28 @@ hsa_symbol::total_byte_size ()
return s;
}
+/* Forward declaration. */
+
+static BrigType16_t
+hsa_type_for_tree_type (const_tree type, unsigned HOST_WIDE_INT *dim_p,
+ bool min32int);
+
+void
+hsa_symbol::fillup_for_decl (tree decl)
+{
+ m_decl = decl;
+ m_type = hsa_type_for_tree_type (TREE_TYPE (decl), &m_dim, false);
+
+ if (hsa_seen_error ())
+ m_seen_error = true;
+}
+
/* Constructor of class representing global HSA function/kernel information and
state. */
hsa_function_representation::hsa_function_representation
(tree fdecl, bool kernel_p): m_name (NULL),
- m_input_args_count (0), m_reg_count (0), m_input_args (NULL),
+ m_reg_count (0), m_input_args (vNULL),
m_output_arg (NULL), m_spill_symbols (vNULL), m_readonly_variables (vNULL),
m_private_variables (vNULL), m_called_functions (vNULL), m_hbb_count (0),
m_in_ssa (true), m_kern_p (kernel_p), m_declaration_p (false), m_decl (fdecl),
@@ -260,16 +272,28 @@ hsa_function_representation::hsa_function_representation
hsa_function_representation::~hsa_function_representation ()
{
- delete m_local_symbols;
- free (m_input_args);
- free (m_output_arg);
/* Kernel names are deallocated at the end of BRIG output when deallocating
hsa_decl_kernel_mapping. */
- if (!m_kern_p)
+ if (!m_kern_p || m_seen_error)
free (m_name);
+ for (unsigned i = 0; i < m_input_args.length (); i++)
+ delete m_input_args[i];
+ m_input_args.release ();
+
+ delete m_output_arg;
+ delete m_local_symbols;
+
+ for (unsigned i = 0; i < m_spill_symbols.length (); i++)
+ delete m_spill_symbols[i];
m_spill_symbols.release ();
+
+ for (unsigned i = 0; i < m_readonly_variables.length (); i++)
+ delete m_readonly_variables[i];
m_readonly_variables.release ();
+
+ for (unsigned i = 0; i < m_private_variables.length (); i++)
+ delete m_private_variables[i];
m_private_variables.release ();
m_called_functions.release ();
}
@@ -283,10 +307,9 @@ hsa_function_representation::get_shadow_reg ()
return m_shadow_reg;
/* Append the shadow argument. */
- hsa_symbol *shadow = &m_input_args[m_input_args_count++];
- shadow->m_type = BRIG_TYPE_U64;
- shadow->m_segment = BRIG_SEGMENT_KERNARG;
- shadow->m_linkage = BRIG_LINKAGE_FUNCTION;
+ hsa_symbol *shadow = new hsa_symbol (BRIG_TYPE_U64, BRIG_SEGMENT_KERNARG,
+ BRIG_LINKAGE_FUNCTION);
+ m_input_args.safe_push (shadow);
shadow->m_name = "hsa_runtime_shadow";
hsa_op_reg *r = new hsa_op_reg (BRIG_TYPE_U64);
@@ -363,13 +386,6 @@ hsa_init_data_for_cfun ()
hsa_allocp_inst_queue
= new object_allocator<hsa_insn_queue> ("HSA queue instructions");
hsa_allocp_bb = new object_allocator<hsa_bb> ("HSA basic blocks");
- hsa_allocp_symbols = new object_allocator<hsa_symbol> ("HSA symbols");
-
- /* The entry/exit blocks don't contain incoming code,
- but the HSA generator might use them to put code into,
- so we need hsa_bb instances of them. */
- hsa_init_new_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- hsa_init_new_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
}
/* Deinitialize HSA subsystem and free all allocated memory. */
@@ -383,14 +399,6 @@ hsa_deinit_data_for_cfun (void)
if (bb->aux)
{
hsa_bb *hbb = hsa_bb_for_bb (bb);
- hsa_insn_phi *phi;
- for (phi = hbb->m_first_phi;
- phi;
- phi = phi->m_next ? as_a <hsa_insn_phi *> (phi->m_next): NULL)
- phi->~hsa_insn_phi ();
- for (hsa_insn_basic *insn = hbb->m_first_insn; insn; insn = insn->m_next)
- hsa_destroy_insn (insn);
-
hbb->~hsa_bb ();
bb->aux = NULL;
}
@@ -408,6 +416,11 @@ hsa_deinit_data_for_cfun (void)
hsa_list_operand_reg.release ();
hsa_list_operand_immed.release ();
+ for (unsigned i = 0; i < hsa_instructions.length (); i++)
+ hsa_destroy_insn (hsa_instructions[i]);
+
+ hsa_instructions.release ();
+
delete hsa_allocp_operand_address;
delete hsa_allocp_operand_immed;
delete hsa_allocp_operand_reg;
@@ -426,7 +439,6 @@ hsa_deinit_data_for_cfun (void)
delete hsa_allocp_inst_comment;
delete hsa_allocp_inst_queue;
delete hsa_allocp_bb;
- delete hsa_allocp_symbols;
delete hsa_cfun;
}
@@ -694,28 +706,14 @@ hsa_needs_cvt (BrigType16_t dtype, BrigType16_t stype)
return false;
}
-/* Fill in those values into SYM according to DECL, which are determined
- independently from whether it is parameter, result, or a variable, local or
- global. */
-
-static void
-fillup_sym_for_decl (tree decl, struct hsa_symbol *sym)
-{
- sym->m_decl = decl;
- sym->m_type = hsa_type_for_tree_type (TREE_TYPE (decl), &sym->m_dim);
-
- if (hsa_seen_error ())
- sym->m_seen_error = true;
-}
-
/* Lookup or create the associated hsa_symbol structure with a given VAR_DECL
or lookup the hsa_structure corresponding to a PARM_DECL. */
static hsa_symbol *
get_symbol_for_decl (tree decl)
{
- struct hsa_symbol **slot;
- struct hsa_symbol dummy, *sym;
+ hsa_symbol **slot, *sym;
+ hsa_symbol dummy (BRIG_TYPE_NONE, BRIG_SEGMENT_NONE, BRIG_LINKAGE_NONE);
gcc_assert (TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == RESULT_DECL
@@ -723,51 +721,47 @@ get_symbol_for_decl (tree decl)
dummy.m_decl = decl;
- if (TREE_CODE (decl) == VAR_DECL && is_global_var (decl))
+ slot = hsa_cfun->m_local_symbols->find_slot (&dummy, INSERT);
+ gcc_checking_assert (slot);
+ if (*slot)
{
- slot = hsa_global_variable_symbols->find_slot (&dummy, INSERT);
- gcc_checking_assert (slot);
- if (*slot)
- {
- sym = *slot;
+ sym = *slot;
- /* If the symbol is problematic, mark current function also as
- problematic. */
- if (sym->m_seen_error)
- hsa_fail_cfun ();
+ /* If the symbol is problematic, mark current function also as
+ problematic. */
+ if (sym->m_seen_error)
+ hsa_fail_cfun ();
- return sym;
- }
- sym = XCNEW (struct hsa_symbol);
- sym->m_segment = BRIG_SEGMENT_GLOBAL;
- sym->m_linkage = BRIG_LINKAGE_FUNCTION;
+ return sym;
+ }
+
+ if (TREE_CODE (decl) == VAR_DECL && is_global_var (decl))
+ {
+ sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_READONLY,
+ BRIG_LINKAGE_MODULE);
/* Following type of global variables can be handled. */
if (TREE_READONLY (decl) && !TREE_ADDRESSABLE (decl)
&& DECL_INITIAL (decl) && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == INTEGER_TYPE)
{
- sym->m_segment = BRIG_SEGMENT_READONLY;
- sym->m_linkage = BRIG_LINKAGE_MODULE;
sym->m_cst_value = new hsa_op_immed (DECL_INITIAL (decl), false);
- hsa_cfun->m_readonly_variables.safe_push (sym);
}
else
HSA_SORRY_ATV (EXPR_LOCATION (decl), "referring to global symbol "
"%q+D by name from HSA code won't work", decl);
+
+ hsa_cfun->m_readonly_variables.safe_push (sym);
}
else
{
- slot = hsa_cfun->m_local_symbols->find_slot (&dummy, INSERT);
- gcc_checking_assert (slot);
- if (*slot)
- return *slot;
gcc_assert (TREE_CODE (decl) == VAR_DECL);
sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_PRIVATE,
BRIG_LINKAGE_FUNCTION);
+ hsa_cfun->m_private_variables.safe_push (sym);
}
- fillup_sym_for_decl (decl, sym);
+ sym->fillup_for_decl (decl);
sym->m_name = hsa_get_declaration_name (decl);
*slot = sym;
return sym;
@@ -1161,6 +1155,8 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc): m_prev (NULL),
{
if (nops > 0)
operands.safe_grow_cleared (nops);
+
+ hsa_instructions.safe_push (this);
}
/* Make OP the operand number INDEX of operands of this instuction. If OP is a
@@ -1250,6 +1246,8 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
gcc_checking_assert (nops >= 4);
set_op (3, arg3);
}
+
+ hsa_instructions.safe_push (this);
}
/* New operator to allocate basic instruction from pool alloc. */
@@ -1366,6 +1364,11 @@ hsa_insn_sbr::replace_all_labels (basic_block old_bb, basic_block new_bb)
m_jump_table[i] = new_bb;
}
+hsa_insn_sbr::~hsa_insn_sbr ()
+{
+ m_jump_table.release ();
+}
+
/* Constructor of comparison instructin. CMP is the comparison operation and T
is the result type. */
@@ -1498,7 +1501,7 @@ hsa_insn_seg::operator new (size_t)
hsa_insn_call::hsa_insn_call (tree callee)
: hsa_insn_basic (0, BRIG_OPCODE_CALL), m_called_function (callee),
- m_args_code_list (NULL), m_result_symbol (NULL), m_result_code_list (NULL)
+ m_output_arg (NULL), m_args_code_list (NULL), m_result_code_list (NULL)
{
}
@@ -1510,6 +1513,17 @@ hsa_insn_call::operator new (size_t)
return hsa_allocp_inst_call->vallocate ();
}
+hsa_insn_call::~hsa_insn_call ()
+{
+ for (unsigned i = 0; i < m_input_args.length (); i++)
+ delete m_input_args[i];
+
+ delete m_output_arg;
+
+ m_input_args.release ();
+ m_input_arg_insns.release ();
+}
+
/* 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,
@@ -1546,8 +1560,7 @@ hsa_insn_comment::operator new (size_t)
return hsa_allocp_inst_comment->vallocate ();
}
-void
-hsa_insn_comment::release_string ()
+hsa_insn_comment::~hsa_insn_comment ()
{
gcc_checking_assert (m_comment);
free (m_comment);
@@ -1942,10 +1955,8 @@ out:
static hsa_op_address *
gen_hsa_addr_for_arg (tree tree_type, int index)
{
- hsa_symbol *sym = hsa_allocp_symbols->allocate ();
- memset (sym, 0, sizeof (hsa_symbol));
- sym->m_segment = BRIG_SEGMENT_ARG;
- sym->m_linkage = BRIG_LINKAGE_ARG;
+ hsa_symbol *sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_ARG,
+ BRIG_LINKAGE_ARG);
sym->m_type = hsa_type_for_tree_type (tree_type, &sym->m_dim);
if (index == -1) /* Function result. */
@@ -3286,7 +3297,6 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
}
call_insn->m_input_args.safe_push (addr->m_symbol);
- call_insn->m_args_symbols.safe_push (addr->m_symbol);
if (parm_type_chain)
parm_type_chain = TREE_CHAIN (parm_type_chain);
}
@@ -3329,7 +3339,6 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb,
}
call_insn->m_output_arg = addr->m_symbol;
- call_insn->m_result_symbol = addr->m_symbol;
call_insn->m_result_code_list = new hsa_op_code_list (1);
}
else
@@ -4537,9 +4546,9 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
called = TREE_OPERAND (called, 0);
gcc_checking_assert (TREE_CODE (called) == FUNCTION_DECL);
- char *name = xstrdup (hsa_get_declaration_name (called));
hsa_add_kernel_dependency
- (hsa_cfun->m_decl, hsa_brig_function_name (name));
+ (hsa_cfun->m_decl,
+ hsa_brig_function_name (hsa_get_declaration_name (called)));
gen_hsa_insns_for_kernel_call (hbb, as_a <gcall *> (stmt));
break;
@@ -4913,21 +4922,6 @@ 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)
@@ -4935,32 +4929,31 @@ gen_function_decl_parameters (hsa_function_representation *f,
tree parm;
unsigned i;
- f->m_input_args_count = get_function_arg_count (decl);
- f->m_input_args = XCNEWVEC (hsa_symbol, f->m_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->m_input_args_count)
+ if (TREE_CHAIN (parm) == NULL)
break;
tree v = TREE_VALUE (parm);
- f->m_input_args[i].m_type = hsa_type_for_tree_type
- (v, &f->m_input_args[i].m_dim);
- f->m_input_args[i].m_segment = BRIG_SEGMENT_ARG;
- f->m_input_args[i].m_linkage = BRIG_LINKAGE_NONE;
- f->m_input_args[i].m_name_number = i;
+
+ hsa_symbol *arg = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_ARG,
+ BRIG_LINKAGE_NONE);
+ arg->m_type = hsa_type_for_tree_type (v, &arg->m_dim);
+ arg->m_name_number = i;
+
+ f->m_input_args.safe_push (arg);
}
tree result_type = TREE_TYPE (TREE_TYPE (decl));
if (!VOID_TYPE_P (result_type))
{
- f->m_output_arg = XCNEW (hsa_symbol);
- f->m_output_arg->m_type = hsa_type_for_tree_type (result_type,
- &f->m_output_arg->m_dim);
- f->m_output_arg->m_segment = BRIG_SEGMENT_ARG;
- f->m_output_arg->m_linkage = BRIG_LINKAGE_NONE;
+ f->m_output_arg = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_ARG,
+ BRIG_LINKAGE_NONE);
+ f->m_output_arg->m_type = hsa_type_for_tree_type
+ (result_type, &f->m_output_arg->m_dim);
f->m_output_arg->m_name = "res";
}
}
@@ -4970,39 +4963,29 @@ gen_function_decl_parameters (hsa_function_representation *f,
result. */
static void
-gen_function_def_parameters (hsa_function_representation *f,
- vec <hsa_op_reg_p> *ssa_map)
+gen_function_def_parameters (vec <hsa_op_reg_p> *ssa_map)
{
tree parm;
- int i, count = 0;
-
- for (parm = DECL_ARGUMENTS (cfun->decl); parm; parm = DECL_CHAIN (parm))
- count++;
-
- f->m_input_args_count = count;
-
- /* Allocate one more argument which can be potentially used for a kernel
- dispatching. */
- f->m_input_args = XCNEWVEC (hsa_symbol, f->m_input_args_count + 1);
hsa_bb *prologue = hsa_bb_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- for (parm = DECL_ARGUMENTS (cfun->decl), i = 0;
- parm;
- parm = DECL_CHAIN (parm), i++)
+ for (parm = DECL_ARGUMENTS (cfun->decl); parm;
+ parm = DECL_CHAIN (parm))
{
struct hsa_symbol **slot;
- fillup_sym_for_decl (parm, &f->m_input_args[i]);
+ hsa_symbol *arg = new hsa_symbol
+ (BRIG_TYPE_NONE,
+ hsa_cfun->m_kern_p ? BRIG_SEGMENT_KERNARG : BRIG_SEGMENT_ARG,
+ BRIG_LINKAGE_FUNCTION);
+ arg->fillup_for_decl (parm);
+
+ hsa_cfun->m_input_args.safe_push (arg);
if (hsa_seen_error ())
return;
- f->m_input_args[i].m_segment = f->m_kern_p ? BRIG_SEGMENT_KERNARG :
- BRIG_SEGMENT_ARG;
- f->m_input_args[i].m_linkage = BRIG_LINKAGE_FUNCTION;
- f->m_input_args[i].m_name = hsa_get_declaration_name (parm);
- hsa_symbol *arg = &f->m_input_args[i];
+ arg->m_name = hsa_get_declaration_name (parm);
/* Copy all input arguments and create corresponding private symbols
for them. */
@@ -5013,9 +4996,7 @@ gen_function_def_parameters (hsa_function_representation *f,
|| (!is_gimple_reg (parm) && !TREE_READONLY (parm)))
{
private_arg = hsa_cfun->create_hsa_temporary (arg->m_type);
- hsa_cfun->m_private_variables.safe_push (private_arg);
- fillup_sym_for_decl (parm, private_arg);
- f->m_private_variables.safe_push (private_arg);
+ private_arg->fillup_for_decl (parm);
hsa_op_address *private_arg_addr = new hsa_op_address (private_arg);
gen_hsa_memory_copy (prologue, private_arg_addr, parm_addr,
@@ -5024,7 +5005,7 @@ gen_function_def_parameters (hsa_function_representation *f,
else
private_arg = arg;
- slot = f->m_local_symbols->find_slot (private_arg, INSERT);
+ slot = hsa_cfun->m_local_symbols->find_slot (private_arg, INSERT);
gcc_assert (!*slot);
*slot = private_arg;
@@ -5048,18 +5029,18 @@ gen_function_def_parameters (hsa_function_representation *f,
{
struct hsa_symbol **slot;
- f->m_output_arg = XCNEW (hsa_symbol);
- fillup_sym_for_decl (DECL_RESULT (cfun->decl), f->m_output_arg);
+ hsa_cfun->m_output_arg = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_ARG,
+ BRIG_LINKAGE_FUNCTION);
+ hsa_cfun->m_output_arg->fillup_for_decl (DECL_RESULT (cfun->decl));
if (hsa_seen_error ())
return;
- f->m_output_arg->m_segment = BRIG_SEGMENT_ARG;
- f->m_output_arg->m_linkage = BRIG_LINKAGE_FUNCTION;
- f->m_output_arg->m_name = "res";
- slot = f->m_local_symbols->find_slot (f->m_output_arg, INSERT);
+ hsa_cfun->m_output_arg->m_name = "res";
+ slot = hsa_cfun->m_local_symbols->find_slot (hsa_cfun->m_output_arg,
+ INSERT);
gcc_assert (!*slot);
- *slot = f->m_output_arg;
+ *slot = hsa_cfun->m_output_arg;
}
}
@@ -5069,10 +5050,10 @@ gen_function_def_parameters (hsa_function_representation *f,
hsa_function_representation *
hsa_generate_function_declaration (tree decl)
{
- hsa_function_representation *fun = XCNEW (hsa_function_representation);
+ hsa_function_representation *fun = new hsa_function_representation
+ (decl, false);
fun->m_declaration_p = true;
- fun->m_decl = decl;
fun->m_name = get_brig_function_name (decl);
gen_function_decl_parameters (fun, decl);
@@ -5320,6 +5301,7 @@ convert_switch_statements ()
gphi *phi = it.phi ();
add_phi_arg (phi, phi_def->phi_value, new_edge, UNKNOWN_LOCATION);
+ delete phi_def;
}
/* Remove the original GIMPLE switch statement. */
@@ -5360,13 +5342,14 @@ static void
generate_hsa (bool kernel)
{
vec <hsa_op_reg_p> ssa_map = vNULL;
+ hsa_init_data_for_cfun ();
if (hsa_num_threads == NULL)
emit_hsa_module_variables ();
/* Initialize hsa_cfun. */
hsa_cfun = new hsa_function_representation (cfun->decl, kernel);
- hsa_init_data_for_cfun ();
+ hsa_cfun->init_extra_bbs ();
if (flag_tm)
{
@@ -5382,7 +5365,7 @@ generate_hsa (bool kernel)
ssa_map.safe_grow_cleared (SSANAMES (cfun)->length ());
hsa_cfun->m_name = get_brig_function_name (cfun->decl);
- gen_function_def_parameters (hsa_cfun, &ssa_map);
+ gen_function_def_parameters (&ssa_map);
if (hsa_seen_error ())
goto fail;
@@ -5417,13 +5400,13 @@ generate_hsa (bool kernel)
#endif
- ssa_map.release ();
-
hsa_regalloc ();
hsa_brig_emit_function ();
fail:
+ ssa_map.release ();
+
hsa_deinit_data_for_cfun ();
}
diff --git a/gcc/hsa.c b/gcc/hsa.c
index c4990e2..aca8bd4 100644
--- a/gcc/hsa.c
+++ b/gcc/hsa.c
@@ -131,7 +131,8 @@ hsa_init_compilation_unit_data (void)
return;
compilation_unit_data_initialized = true;
- hsa_global_variable_symbols = new hash_table <hsa_free_symbol_hasher> (8);
+
+ hsa_failed_functions = new hash_set <tree> ();
}
/* Free data structures that are used when dealing with different
@@ -140,11 +141,11 @@ hsa_init_compilation_unit_data (void)
void
hsa_deinit_compilation_unit_data (void)
{
- if (compilation_unit_data_initialized)
- delete hsa_global_variable_symbols;
-
if (hsa_failed_functions)
delete hsa_failed_functions;
+
+ if (hsa_num_threads)
+ delete hsa_num_threads;
}
/* Return true if we are generating large HSA machine model. */
@@ -547,6 +548,17 @@ hsa_destroy_insn (hsa_insn_basic *insn)
block->~hsa_insn_arg_block ();
return;
}
+ if (hsa_insn_sbr *sbr = dyn_cast <hsa_insn_sbr *> (insn))
+ {
+ sbr->~hsa_insn_sbr ();
+ return;
+ }
+ if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
+ {
+ comment->~hsa_insn_comment ();
+ return;
+ }
+
insn->~hsa_insn_basic ();
return;
}
@@ -711,8 +723,6 @@ hsa_seen_error (void)
void
hsa_fail_cfun (void)
{
- if (hsa_failed_functions == NULL)
- hsa_failed_functions = new hash_set <tree> ();
hsa_failed_functions->add (hsa_cfun->m_decl);
hsa_cfun->m_seen_error = true;
}
diff --git a/gcc/hsa.h b/gcc/hsa.h
index f4184f9..dfa0d1f 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -53,19 +53,18 @@ typedef hsa_insn_basic *hsa_insn_basic_p;
struct hsa_symbol
{
- /* Default constructor. */
- hsa_symbol ();
-
/* Constructor. */
hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
BrigLinkage8_t linkage);
- /* New operator to allocate HSA symbol from pool alloc. */
- void *operator new (size_t);
-
/* Return total size of the symbol. */
unsigned HOST_WIDE_INT total_byte_size ();
+ /* Fill in those values into the symbol according to DECL, which are
+ determined independently from whether it is parameter, result,
+ or a variable, local or global. */
+ void fillup_for_decl (tree decl);
+
/* Pointer to the original tree, which is PARM_DECL for input parameters and
RESULT_DECL for the output parameters. */
tree m_decl;
@@ -102,6 +101,10 @@ struct hsa_symbol
/* True if an error has been seen for the symbol. */
bool m_seen_error;
+
+private:
+ /* Default constructor. */
+ hsa_symbol ();
};
/* Abstract class for HSA instruction operands. */
@@ -483,6 +486,9 @@ class hsa_insn_sbr : public hsa_insn_basic
public:
hsa_insn_sbr (hsa_op_reg *index, unsigned jump_count);
+ /* Default destructor. */
+ ~hsa_insn_sbr ();
+
void *operator new (size_t);
void replace_all_labels (basic_block old_bb, basic_block new_bb);
@@ -708,6 +714,9 @@ class hsa_insn_call : public hsa_insn_basic
public:
hsa_insn_call (tree callee);
+ /* Default destructor. */
+ ~hsa_insn_call ();
+
void *operator new (size_t);
/* Called function */
@@ -725,15 +734,9 @@ public:
/* Called function code reference. */
hsa_op_code_ref m_func;
- /* Argument symbols. */
- auto_vec <hsa_symbol *> m_args_symbols;
-
/* Code list for arguments of the function. */
hsa_op_code_list *m_args_code_list;
- /* Result symbol. */
- hsa_symbol *m_result_symbol;
-
/* Code list for result of the function. */
hsa_op_code_list *m_result_code_list;
private:
@@ -796,13 +799,10 @@ public:
/* Constructor of class representing the comment in HSAIL. */
hsa_insn_comment (const char *s);
- void *operator new (size_t);
-
- /* Destructor. */
+ /* Default destructor. */
~hsa_insn_comment ();
- /* Release memory for comment. */
- void release_string ();
+ void *operator new (size_t);
char *m_comment;
};
@@ -957,17 +957,15 @@ public:
/* Name of the function. */
char *m_name;
- /* 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. */
- unsigned m_input_args_count;
-
/* Number of allocated register structures. */
int m_reg_count;
- hsa_symbol *m_input_args;
+ /* Input arguments. */
+ vec <hsa_symbol *> m_input_args;
+
/* Output argument or NULL if there is none. */
hsa_symbol *m_output_arg;
+
/* Hash table of local variable symbols. */
hash_table <hsa_noop_symbol_hasher> *m_local_symbols;
@@ -1080,7 +1078,6 @@ hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,
/* in hsa.c */
extern struct hsa_function_representation *hsa_cfun;
-extern hash_table <hsa_free_symbol_hasher> *hsa_global_variable_symbols;
extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
extern hsa_summary_t *hsa_summaries;
extern hsa_symbol *hsa_num_threads;
--
2.6.2
[-- Attachment #7: 0006-HSA-introduce-hsa_debug_symbol-and-refact.-hsa_funct.patch --]
[-- Type: text/x-patch, Size: 4655 bytes --]
From 0d38552c5c84e54aa7b1cf7d6fa38c80b85b6108 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 27 Oct 2015 16:01:56 +0100
Subject: [PATCH 6/9] HSA: introduce hsa_debug_symbol and refact.
hsa_function_representation.
gcc/ChangeLog:
2015-10-27 Martin Liska <mliska@suse.cz>
* hsa-dump.c (dump_hsa_symbol): New function.
(debug_hsa_symbol): Likewise.
* hsa-gen.c (hsa_function_representation::~hsa_function_representation):
Release memory.
(generate_hsa): Use hsa_cfun->m_map.
* hsa.h: Declare hsa_function_representation::m_map.
---
gcc/hsa-dump.c | 29 +++++++++++++++++++++++++++++
gcc/hsa-gen.c | 19 ++++++++-----------
gcc/hsa.h | 3 +++
3 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index 1a68bc2..6e58001 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -726,6 +726,26 @@ dump_hsa_address (FILE *f, hsa_op_address *addr)
fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]", addr->m_imm_offset);
}
+/* Dump textual representation of HSA IL symbol SYMBOL to file F. */
+
+static void
+dump_hsa_symbol (FILE *f, hsa_symbol *symbol)
+{
+ const char *name;
+ if (symbol->m_name)
+ name = symbol->m_name;
+ else
+ {
+ char buf[64];
+ sprintf (buf, "__%s_%i", hsa_seg_name (symbol->m_segment),
+ symbol->m_name_number);
+
+ name = buf;
+ }
+
+ fprintf (f, "%s (%s)", name, hsa_type_name (symbol->m_type));
+}
+
/* Dump textual representation of HSA IL operand OP to file F. */
static void
@@ -1127,3 +1147,12 @@ debug_hsa_operand (hsa_op_base *opc)
dump_hsa_operand (stderr, opc, true);
fprintf (stderr, "\n");
}
+
+/* Dump textual representation of as HSA symbol. */
+
+DEBUG_FUNCTION void
+debug_hsa_symbol (hsa_symbol *symbol)
+{
+ dump_hsa_symbol (stderr, symbol);
+ fprintf (stderr, "\n");
+}
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 4a30eb0..2139499 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -262,7 +262,7 @@ hsa_function_representation::hsa_function_representation
m_private_variables (vNULL), m_called_functions (vNULL), m_hbb_count (0),
m_in_ssa (true), m_kern_p (kernel_p), m_declaration_p (false), m_decl (fdecl),
m_shadow_reg (NULL), m_kernel_dispatch_count (0), m_maximum_omp_data_size (0),
- m_seen_error (false), m_temp_symbol_count (0)
+ m_seen_error (false), m_temp_symbol_count (0), m_ssa_map ()
{
int sym_init_len = (vec_safe_length (cfun->local_decls) / 2) + 1;;
m_local_symbols = new hash_table <hsa_noop_symbol_hasher> (sym_init_len);
@@ -296,6 +296,7 @@ hsa_function_representation::~hsa_function_representation ()
delete m_private_variables[i];
m_private_variables.release ();
m_called_functions.release ();
+ m_ssa_map.release ();
}
hsa_op_reg *
@@ -5341,7 +5342,6 @@ emit_hsa_module_variables (void)
static void
generate_hsa (bool kernel)
{
- vec <hsa_op_reg_p> ssa_map = vNULL;
hsa_init_data_for_cfun ();
if (hsa_num_threads == NULL)
@@ -5349,6 +5349,7 @@ generate_hsa (bool kernel)
/* Initialize hsa_cfun. */
hsa_cfun = new hsa_function_representation (cfun->decl, kernel);
+ hsa_cfun->m_ssa_map.safe_grow_cleared (SSANAMES (cfun)->length ());
hsa_cfun->init_extra_bbs ();
if (flag_tm)
@@ -5362,16 +5363,15 @@ generate_hsa (bool kernel)
if (hsa_seen_error ())
goto fail;
- ssa_map.safe_grow_cleared (SSANAMES (cfun)->length ());
hsa_cfun->m_name = get_brig_function_name (cfun->decl);
- gen_function_def_parameters (&ssa_map);
+ gen_function_def_parameters (&hsa_cfun->m_ssa_map);
if (hsa_seen_error ())
goto fail;
init_prologue ();
- gen_body_from_gimple (&ssa_map);
+ gen_body_from_gimple (&hsa_cfun->m_ssa_map);
if (hsa_seen_error ())
goto fail;
@@ -5385,9 +5385,9 @@ generate_hsa (bool kernel)
}
#ifdef ENABLE_CHECKING
- for (unsigned i = 0; i < ssa_map.length (); i++)
- if (ssa_map[i])
- ssa_map[i]->verify_ssa ();
+ for (unsigned i = 0; i < hsa_cfun->m_ssa_map.length (); i++)
+ if (hsa_cfun->m_ssa_map[i])
+ hsa_cfun->m_ssa_map[i]->verify_ssa ();
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
@@ -5401,12 +5401,9 @@ generate_hsa (bool kernel)
#endif
hsa_regalloc ();
-
hsa_brig_emit_function ();
fail:
- ssa_map.release ();
-
hsa_deinit_data_for_cfun ();
}
diff --git a/gcc/hsa.h b/gcc/hsa.h
index dfa0d1f..0bdd530 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -1016,6 +1016,9 @@ public:
/* Counter for temporary symbols created in the function representation. */
unsigned m_temp_symbol_count;
+
+ /* SSA names mapping. */
+ vec <hsa_op_reg_p> m_ssa_map;
};
enum hsa_function_kind
--
2.6.2
[-- Attachment #8: 0007-HSA-prepend-_m-to-hsa_insn_basic-operands.patch --]
[-- Type: text/x-patch, Size: 2699 bytes --]
From 1aad365cac3f81561bf0c9f819a4f9515300f347 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 30 Oct 2015 20:04:33 +0100
Subject: [PATCH 7/9] HSA: prepend _m to hsa_insn_basic::operands
gcc/ChangeLog:
2015-10-30 Martin Liska <mliska@suse.cz>
* hsa-gen.c (hsa_insn_basic::hsa_insn_basic): Rename operands
to m_operands.
(hsa_insn_basic::set_op): Likewise.
(hsa_insn_basic::get_op): Likewise.
(hsa_insn_basic::get_op_addr): Likewise.
(hsa_insn_basic::operand_count): Likewise.
* hsa.h: Likewise.
---
gcc/hsa-gen.c | 12 ++++++------
gcc/hsa.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 2139499..3a0b99b7 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -1155,7 +1155,7 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc): m_prev (NULL),
m_type (BRIG_TYPE_NONE), m_brig_offset (0)
{
if (nops > 0)
- operands.safe_grow_cleared (nops);
+ m_operands.safe_grow_cleared (nops);
hsa_instructions.safe_push (this);
}
@@ -1184,7 +1184,7 @@ hsa_insn_basic::set_op (int index, hsa_op_base *op)
}
}
- operands[index] = op;
+ m_operands[index] = op;
}
/* Get INDEX-th operand of the instruction. */
@@ -1192,7 +1192,7 @@ hsa_insn_basic::set_op (int index, hsa_op_base *op)
hsa_op_base *
hsa_insn_basic::get_op (int index)
{
- return operands[index];
+ return m_operands[index];
}
/* Get address of INDEX-th operand of the instruction. */
@@ -1200,14 +1200,14 @@ hsa_insn_basic::get_op (int index)
hsa_op_base **
hsa_insn_basic::get_op_addr (int index)
{
- return &operands[index];
+ return &m_operands[index];
}
/* Get number of operands of the instruction. */
unsigned int
hsa_insn_basic::operand_count ()
{
- return operands.length ();
+ return m_operands.length ();
}
/* Constructor of the class which is the bases of all instructions and directly
@@ -1222,7 +1222,7 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
m_type (t), m_brig_offset (0)
{
if (nops > 0)
- operands.safe_grow_cleared (nops);
+ m_operands.safe_grow_cleared (nops);
if (arg0 != NULL)
{
diff --git a/gcc/hsa.h b/gcc/hsa.h
index 0bdd530..f08b12e 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -414,7 +414,7 @@ private:
fewer instructions and so will fit the internal storage. */
/* TODO: Vast majority of instructions have three or fewer operands, so we
may actually try reducing it. */
- auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> operands;
+ auto_vec<hsa_op_base *, HSA_BRIG_INT_STORAGE_OPERANDS> m_operands;
};
/* Class representing a PHI node of the SSA form of HSA virtual
--
2.6.2
[-- Attachment #9: 0008-HSA-correctly-handle-memory-order-for-atomic-insns.patch --]
[-- Type: text/x-patch, Size: 8315 bytes --]
From 77d7f6ee98a46fa123394a5073f44ae591e26c76 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 27 Oct 2015 17:49:05 +0100
Subject: [PATCH 8/9] HSA: correctly handle memory order for atomic insns
gcc/ChangeLog:
2015-10-27 Martin Liska <mliska@suse.cz>
* hsa-gen.c (hsa_insn_signal::hsa_insn_signal): Use modified
ctor of hsa_insn_atomic.
(gen_hsa_insns_for_kernel_call): Likewise.
(get_memory_order_name): New function.
(get_memory_order): New function.
(gen_hsa_ternary_atomic_for_builtin): Fill up memory order.
(gen_hsa_insns_for_call): Likewise.
* hsa.h: Declare new argument for
hsa_insn_atomic::hsa_insn_atomic.
---
gcc/hsa-gen.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
gcc/hsa.h | 2 +-
2 files changed, 108 insertions(+), 18 deletions(-)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 3a0b99b7..856fdce 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -1429,11 +1429,12 @@ hsa_insn_mem::operator new (size_t)
hsa_insn_atomic::hsa_insn_atomic (int nops, int opc,
enum BrigAtomicOperation aop,
- BrigType16_t t, hsa_op_base *arg0,
+ BrigType16_t t, BrigMemoryOrder memorder,
+ hsa_op_base *arg0,
hsa_op_base *arg1, hsa_op_base *arg2,
hsa_op_base *arg3)
: hsa_insn_mem (nops, opc, t, arg0, arg1, arg2, arg3), m_atomicop (aop),
- m_memoryorder (BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE),
+ m_memoryorder (memorder),
m_memoryscope (BRIG_MEMORY_SCOPE_SYSTEM)
{
gcc_checking_assert (opc == BRIG_OPCODE_ATOMICNORET ||
@@ -1462,7 +1463,8 @@ hsa_insn_signal::hsa_insn_signal (int nops, int opc,
BrigType16_t t, hsa_op_base *arg0,
hsa_op_base *arg1, hsa_op_base *arg2,
hsa_op_base *arg3)
- : hsa_insn_atomic (nops, opc, sop, t, arg0, arg1, arg2, arg3)
+ : hsa_insn_atomic (nops, opc, sop, t, BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE,
+ arg0, arg1, arg2, arg3)
{
}
@@ -4028,10 +4030,9 @@ gen_hsa_insns_for_kernel_call (hsa_bb *hbb, gcall *call)
/* Store 5122 << 16 + 1 to packet->header. */
c = new hsa_op_immed (70658, BRIG_TYPE_U32);
- hsa_insn_atomic *atomic = new hsa_insn_atomic (2, BRIG_OPCODE_ATOMICNORET,
- BRIG_ATOMIC_ST, BRIG_TYPE_B32,
- addr, c);
- atomic->m_memoryorder = BRIG_MEMORY_ORDER_SC_RELEASE;
+ hsa_insn_atomic *atomic = new hsa_insn_atomic
+ (2, BRIG_OPCODE_ATOMICNORET, BRIG_ATOMIC_ST, BRIG_TYPE_B32,
+ BRIG_MEMORY_ORDER_SC_RELEASE, addr, c);
atomic->m_memoryscope = BRIG_MEMORY_SCOPE_SYSTEM;
hbb->append_insn (atomic);
@@ -4145,6 +4146,54 @@ get_address_from_value (tree val, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map)
}
}
+/* Return strign for MEMMODEL. */
+
+static const char *
+get_memory_order_name (unsigned memmodel)
+{
+ switch (memmodel)
+ {
+ case __ATOMIC_RELAXED:
+ return "__ATOMIC_RELAXED";
+ case __ATOMIC_CONSUME:
+ return "__ATOMIC_CONSUME";
+ case __ATOMIC_ACQUIRE:
+ return "__ATOMIC_ACQUIRE";
+ case __ATOMIC_RELEASE:
+ return "__ATOMIC_RELEASE";
+ case __ATOMIC_ACQ_REL:
+ return "__ATOMIC_ACQ_REL";
+ case __ATOMIC_SEQ_CST:
+ return "__ATOMIC_SEQ_CST";
+ default:
+ return NULL;
+ }
+}
+
+/* Return memory order according to predefined __atomic memory model
+ constants. LOCATION is provided to locate the problemati statement. */
+
+static BrigMemoryOrder
+get_memory_order (unsigned memmodel, location_t location)
+{
+ switch (memmodel)
+ {
+ case __ATOMIC_RELAXED:
+ return BRIG_MEMORY_ORDER_RELAXED;
+ case __ATOMIC_ACQUIRE:
+ return BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ case __ATOMIC_RELEASE:
+ return BRIG_MEMORY_ORDER_SC_RELEASE;
+ case __ATOMIC_ACQ_REL:
+ return BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
+ default:
+ HSA_SORRY_ATV (location,
+ "support for HSA does not implement memory model: %s",
+ get_memory_order_name (memmodel));
+ return BRIG_MEMORY_ORDER_NONE;
+ }
+}
+
/* Helper function to create an HSA atomic binary operation instruction out of
calls to atomic builtins. RET_ORIG is true if the built-in is the variant
that return s the value before applying operation, and false if it should
@@ -4161,8 +4210,22 @@ gen_hsa_ternary_atomic_for_builtin (bool ret_orig,
tree lhs = gimple_call_lhs (stmt);
tree type = TREE_TYPE (gimple_call_arg (stmt, 1));
- BrigType16_t hsa_type = hsa_type_for_scalar_tree_type (type, false);
+ BrigType16_t hsa_type = hsa_type_for_scalar_tree_type (type, false);
BrigType16_t mtype = mem_type_for_type (hsa_type);
+ tree model = gimple_call_arg (stmt, 2);
+
+ if (!tree_fits_uhwi_p (model))
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model %E", model);
+ return;
+ }
+
+ unsigned HOST_WIDE_INT mmodel = tree_to_uhwi (model);
+
+ BrigMemoryOrder memorder = get_memory_order
+ (mmodel, gimple_location (stmt));
/* Certain atomic insns must have Bx memory types. */
switch (acode)
@@ -4193,12 +4256,19 @@ gen_hsa_ternary_atomic_for_builtin (bool ret_orig,
nops = 2;
}
- hsa_insn_atomic *atominsn = new hsa_insn_atomic (nops, opcode, acode, mtype);
-
/* Overwrite default memory order for ATOMIC_ST insn which can have just
RLX or SCREL memory order. */
- if (acode == BRIG_ATOMIC_ST)
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_RELEASE;
+ if (acode == BRIG_ATOMIC_ST && memorder != BRIG_MEMORY_ORDER_RELAXED
+ && memorder != BRIG_MEMORY_ORDER_SC_RELEASE)
+ {
+ HSA_SORRY_ATV (gimple_location (stmt),
+ "support for HSA does not implement memory model for "
+ "ATOMIC_ST: %s", get_memory_order_name (mmodel));
+ return;
+ }
+
+ hsa_insn_atomic *atominsn = new hsa_insn_atomic (nops, opcode, acode, mtype,
+ memorder);
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
@@ -4369,6 +4439,28 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
BrigType16_t mtype;
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
+ tree model = gimple_call_arg (stmt, 1);
+ if (!tree_fits_uhwi_p (model))
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model: %E", model);
+ return;
+ }
+
+ unsigned HOST_WIDE_INT mmodel = tree_to_uhwi (model);
+ BrigMemoryOrder memorder = get_memory_order (mmodel,
+ gimple_location (stmt));
+
+ if (memorder != BRIG_MEMORY_ORDER_RELAXED
+ && memorder != BRIG_MEMORY_ORDER_SC_RELEASE)
+ {
+ HSA_SORRY_ATV
+ (gimple_location (stmt),
+ "support for HSA does not implement memory model for "
+ "ATOMIC_LD: %s", get_memory_order_name (mmodel));
+ return;
+ }
if (lhs)
{
@@ -4385,9 +4477,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
hsa_insn_atomic *atominsn
= new hsa_insn_atomic (2, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_LD, mtype,
- dest, addr);
-
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE;
+ memorder, dest, addr);
hbb->append_insn (atominsn);
break;
@@ -4515,7 +4605,8 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
(hsa_type_for_scalar_tree_type (type, false));
hsa_insn_atomic *atominsn = new hsa_insn_atomic
- (4, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_CAS, atype);
+ (4, BRIG_OPCODE_ATOMIC, BRIG_ATOMIC_CAS, atype,
+ BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE);
hsa_op_address *addr;
addr = get_address_from_value (gimple_call_arg (stmt, 0), hbb, ssa_map);
@@ -4534,7 +4625,6 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb,
atominsn->set_op
(3, hsa_reg_or_immed_for_gimple_op (gimple_call_arg (stmt, 2),
hbb, ssa_map));
- atominsn->m_memoryorder = BRIG_MEMORY_ORDER_SC_ACQUIRE_RELEASE;
hbb->append_insn (atominsn);
break;
diff --git a/gcc/hsa.h b/gcc/hsa.h
index f08b12e..1081fb6 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -612,7 +612,7 @@ class hsa_insn_atomic : public hsa_insn_mem
{
public:
hsa_insn_atomic (int nops, int opc, enum BrigAtomicOperation aop,
- BrigType16_t t,
+ BrigType16_t t, BrigMemoryOrder memorder,
hsa_op_base *arg0 = NULL, hsa_op_base *arg1 = NULL,
hsa_op_base *arg2 = NULL, hsa_op_base *arg3 = NULL);
void *operator new (size_t);
--
2.6.2
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-11-02 10:18 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-02 10:18 [HSA] Back-end enhancement and various fixes 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).