Skip to content

[HSABE] indexing of program scope functions #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
282 changes: 176 additions & 106 deletions gcc/hsa-brig.c

Large diffs are not rendered by default.

123 changes: 74 additions & 49 deletions gcc/hsa-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,31 @@ along with GCC; see the file COPYING3. If not see
function. */
class hsa_function_representation *hsa_cfun;

/* Element of the mapping vector between a host decl and an HSA kernel. */
/* Element of the mapping vector between a host decl and an HSA function. */

struct GTY(()) hsa_decl_kernel_map_element
struct GTY(()) hsa_decl_function_map_element
{
/* The decl of the host function. */
tree decl;
/* Name of the HSA kernel in BRIG. */
/* Name of the HSA function in BRIG. */
char * GTY((skip)) name;
/* Size of OMP data, if the kernel contains a kernel dispatch. */
unsigned omp_data_size;
/* True if the function is gridified kernel. */
/* True if the function is a host-callable kernel. */
bool kernel_p;
/* True if the function is a gridified kernel. */
bool gridified_kernel_p;
};

/* Mapping between decls and corresponding HSA kernels in this compilation
unit. */

static GTY (()) vec<hsa_decl_kernel_map_element, va_gc>
*hsa_decl_kernel_mapping;
static GTY (()) vec<hsa_decl_function_map_element, va_gc>
*hsa_decl_function_mapping;

/* Mapping between decls and corresponding HSA kernels
called by the function. */
hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
hash_map <tree, vec <const char *> *> *hsa_decl_function_dependencies;

/* Hash function to lookup a symbol for a decl. */
hash_table <hsa_noop_symbol_hasher> *hsa_global_variable_symbols;
Expand Down Expand Up @@ -649,87 +651,97 @@ hsa_destroy_operand (hsa_op_base *op)
op->~hsa_op_base ();
}

/* Create a mapping between the original function DECL and kernel name NAME. */
/* Create a mapping between the original function DECL and HSA function
named NAME. */

void
hsa_add_kern_decl_mapping (tree decl, char *name, unsigned omp_data_size,
bool gridified_kernel_p)
hsa_add_function_decl_mapping (tree decl, char *name, unsigned omp_data_size,
struct hsa_function_summary *s)
{
hsa_decl_kernel_map_element dkm;
hsa_decl_function_map_element dkm;
dkm.decl = decl;
dkm.name = name;
dkm.omp_data_size = omp_data_size;
dkm.gridified_kernel_p = gridified_kernel_p;
vec_safe_push (hsa_decl_kernel_mapping, dkm);
dkm.kernel_p = s->m_kind == HSA_KERNEL;
dkm.gridified_kernel_p = s->m_gridified_kernel_p;
vec_safe_push (hsa_decl_function_mapping, dkm);
}

/* Return the number of kernel decl name mappings. */
/* Return the number of function decl name mappings. */

unsigned
hsa_get_number_decl_kernel_mappings (void)
hsa_get_number_decl_function_mappings (void)
{
return vec_safe_length (hsa_decl_kernel_mapping);
return vec_safe_length (hsa_decl_function_mapping);
}

/* Return the decl in the Ith kernel decl name mapping. */
/* Return the decl in the Ith function decl name mapping. */

tree
hsa_get_decl_kernel_mapping_decl (unsigned i)
hsa_get_decl_function_mapping_decl (unsigned i)
{
return (*hsa_decl_kernel_mapping)[i].decl;
return (*hsa_decl_function_mapping)[i].decl;
}

/* Return the name in the Ith kernel decl name mapping. */
/* Return the name in the Ith function decl name mapping. */

char *
hsa_get_decl_kernel_mapping_name (unsigned i)
hsa_get_decl_function_mapping_name (unsigned i)
{
return (*hsa_decl_kernel_mapping)[i].name;
return (*hsa_decl_function_mapping)[i].name;
}

/* Return maximum OMP size for kernel decl name mapping. */
/* Return maximum OMP size for function decl name mapping. */

unsigned
hsa_get_decl_kernel_mapping_omp_size (unsigned i)
{
return (*hsa_decl_kernel_mapping)[i].omp_data_size;
return (*hsa_decl_function_mapping)[i].omp_data_size;
}

/* Return if the function is gridified kernel in decl name mapping. */
/* Return if the function is a gridified kernel in decl name mapping. */

bool
hsa_get_decl_kernel_mapping_gridified (unsigned i)
hsa_get_decl_function_mapping_gridified_p (unsigned i)
{
return (*hsa_decl_kernel_mapping)[i].gridified_kernel_p;
return (*hsa_decl_function_mapping)[i].gridified_kernel_p;
}

/* Free the mapping between original decls and kernel names. */
/* Return true if the function is a host-callable kernel. */

bool
hsa_get_decl_function_mapping_kernel_p (unsigned i)
{
return (*hsa_decl_function_mapping)[i].kernel_p;
}

/* Free the mapping between original decls and function names. */

void
hsa_free_decl_kernel_mapping (void)
hsa_free_decl_function_mapping (void)
{
if (hsa_decl_kernel_mapping == NULL)
if (hsa_decl_function_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);
for (unsigned i = 0; i < hsa_decl_function_mapping->length (); ++i)
free ((*hsa_decl_function_mapping)[i].name);
ggc_free (hsa_decl_function_mapping);
}

/* Add new kernel dependency. */
/* Add new function dependency. */

void
hsa_add_kernel_dependency (tree caller, const char *called_function)
hsa_add_function_dependency (tree caller, const char *called_function)
{
if (hsa_decl_kernel_dependencies == NULL)
hsa_decl_kernel_dependencies = new hash_map<tree, vec<const char *> *> ();
if (hsa_decl_function_dependencies == NULL)
hsa_decl_function_dependencies = new hash_map<tree, vec<const char *> *> ();

vec <const char *> *s = NULL;
vec <const char *> **slot = hsa_decl_kernel_dependencies->get (caller);
vec <const char *> **slot = hsa_decl_function_dependencies->get (caller);
if (slot == NULL)
{
s = new vec <const char *> ();
hsa_decl_kernel_dependencies->put (caller, s);
hsa_decl_function_dependencies->put (caller, s);
}
else
s = *slot;
Expand Down Expand Up @@ -816,8 +828,8 @@ hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,
gpu_summary->m_kind = kind;
host_summary->m_kind = kind;

gpu_summary->m_gpu_implementation_p = true;
host_summary->m_gpu_implementation_p = false;
gpu_summary->m_hsa_implementation_p = true;
host_summary->m_hsa_implementation_p = false;

gpu_summary->m_gridified_kernel_p = gridified_kernel_p;
host_summary->m_gridified_kernel_p = gridified_kernel_p;
Expand All @@ -827,32 +839,45 @@ hsa_summary_t::link_functions (cgraph_node *gpu, cgraph_node *host,

process_gpu_implementation_attributes (gpu->decl);

/* Create reference between a kernel and a corresponding host implementation
to quarantee LTO streaming to a same LTRANS. */
if (kind == HSA_KERNEL)
gpu->create_reference (host, IPA_REF_ADDR);
/* Create reference between an HSA function and a corresponding host
implementation to quarantee LTO streaming to a same LTRANS. */
gpu->create_reference (host, IPA_REF_ADDR);
}

void
hsa_summary_t::mark_hsa_only_implementation (cgraph_node *node,
hsa_function_kind kind)
{
hsa_function_summary *gpu_summary = get (node);
gpu_summary->m_kind = kind;
gpu_summary->m_hsa_implementation_p = true;
gcc_assert (!gpu_summary->m_bound_function);
process_gpu_implementation_attributes (node->decl);
}

/* Add a HOST function to HSA summaries. */

void
hsa_register_kernel (cgraph_node *host)
hsa_register_function (cgraph_node *host, bool kernel_p)
{
if (hsa_summaries == NULL)
hsa_summaries = new hsa_summary_t (symtab);
hsa_function_summary *s = hsa_summaries->get (host);
s->m_kind = HSA_KERNEL;
s->m_kind = kernel_p ? HSA_KERNEL : HSA_FUNCTION;
}

/* Add a pair of functions to HSA summaries. GPU is an HSA implementation of
a HOST function. */

void
hsa_register_kernel (cgraph_node *gpu, cgraph_node *host)
hsa_register_function (cgraph_node *gpu, cgraph_node *host, bool kernel_p)
{
if (hsa_summaries == NULL)
hsa_summaries = new hsa_summary_t (symtab);
hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true);
if (kernel_p)
hsa_summaries->link_functions (gpu, host, HSA_KERNEL, true);
else
hsa_summaries->link_functions (gpu, host, HSA_FUNCTION, true);
}

/* Return true if expansion of the current HSA function has already failed. */
Expand Down
41 changes: 27 additions & 14 deletions gcc/hsa-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1223,19 +1223,22 @@ struct hsa_function_summary

/* Pointer to a cgraph node which is a HSA implementation of the function.
In case of the function is a HSA function, the bound function points
to the host function. */
to the host function.
This can also be NULL if there is no counterpart, which can happen for GPU
implementations if they are functions marked with hsa_kernel or
hsa_function attributes. */
cgraph_node *m_bound_function;

/* Identifies if the function is an HSA function or a host function. */
bool m_gpu_implementation_p;
/* Identifies if the function is an HSA function. */
bool m_hsa_implementation_p;

/* True if the function is a gridified kernel. */
bool m_gridified_kernel_p;
};

inline
hsa_function_summary::hsa_function_summary (): m_kind (HSA_NONE),
m_bound_function (NULL), m_gpu_implementation_p (false)
m_bound_function (NULL), m_hsa_implementation_p (false)
{
}

Expand All @@ -1254,6 +1257,13 @@ class hsa_summary_t: public function_summary <hsa_function_summary *>
void link_functions (cgraph_node *gpu, cgraph_node *host,
hsa_function_kind kind, bool gridified_kernel_p);

/* Mark a specific function NODE as a standalone HSA implementation (that has
no CPU counterpart). KIND determines whether this is a host-invokable
kernel or an agent-callable function. */

void mark_hsa_only_implementation (cgraph_node *node,
hsa_function_kind kind);

private:
void process_gpu_implementation_attributes (tree gdecl);
};
Expand Down Expand Up @@ -1314,7 +1324,7 @@ hsa_internal_fn_hasher::equal (const value_type a, const compare_type b)

/* in hsa-common.c */
extern struct hsa_function_representation *hsa_cfun;
extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
extern hash_map <tree, vec <const char *> *> *hsa_decl_function_dependencies;
extern hsa_summary_t *hsa_summaries;
extern hsa_symbol *hsa_num_threads;
extern unsigned hsa_kernel_calls_counter;
Expand Down Expand Up @@ -1343,22 +1353,25 @@ BrigAlignment8_t hsa_object_alignment (tree t);
unsigned hsa_byte_alignment (BrigAlignment8_t alignment);
void hsa_destroy_operand (hsa_op_base *op);
void hsa_destroy_insn (hsa_insn_basic *insn);
void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
unsigned hsa_get_number_decl_kernel_mappings (void);
tree hsa_get_decl_kernel_mapping_decl (unsigned i);
char *hsa_get_decl_kernel_mapping_name (unsigned i);
void hsa_add_function_decl_mapping (tree decl, char *name, unsigned,
struct hsa_function_summary *s);
unsigned hsa_get_number_decl_function_mappings (void);
tree hsa_get_decl_function_mapping_decl (unsigned i);
char *hsa_get_decl_function_mapping_name (unsigned i);
unsigned hsa_get_decl_kernel_mapping_omp_size (unsigned i);
bool hsa_get_decl_kernel_mapping_gridified (unsigned i);
void hsa_free_decl_kernel_mapping (void);
bool hsa_get_decl_function_mapping_gridified_p (unsigned i);
bool hsa_get_decl_function_mapping_kernel_p (unsigned i);
void hsa_free_decl_function_mapping (void);
tree *hsa_get_ctor_statements (void);
tree *hsa_get_dtor_statements (void);
tree *hsa_get_kernel_dispatch_type (void);
void hsa_add_kernel_dependency (tree caller, const char *called_function);
void hsa_sanitize_name (char *p);
char *hsa_brig_function_name (const char *p);
const char *hsa_get_declaration_name (tree decl);
void hsa_register_kernel (cgraph_node *host);
void hsa_register_kernel (cgraph_node *gpu, cgraph_node *host);
void hsa_register_function (cgraph_node *host, bool kernel_p);
void hsa_register_function (cgraph_node *gpu, cgraph_node *host,
bool kernel_p);
bool hsa_seen_error (void);
void hsa_fail_cfun (void);

Expand Down Expand Up @@ -1409,7 +1422,7 @@ hsa_gpu_implementation_p (tree decl)

hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (decl));

return s->m_gpu_implementation_p;
return s->m_hsa_implementation_p;
}

#endif /* HSA_H */
25 changes: 9 additions & 16 deletions gcc/hsa-gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,6 @@ hsa_function_representation::hsa_function_representation (hsa_internal_fn *fn)

hsa_function_representation::~hsa_function_representation ()
{
/* Kernel names are deallocated at the end of BRIG output when deallocating
hsa_decl_kernel_mapping. */
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 ();
Expand Down Expand Up @@ -952,15 +947,17 @@ get_symbol_for_decl (tree decl)
}

/* For a given HSA function declaration, return a host
function declaration. */
function declaration, NULL if the declaration is an HSA-only
function.
*/

tree
hsa_get_host_function (tree decl)
{
hsa_function_summary *s
= hsa_summaries->get (cgraph_node::get_create (decl));
gcc_assert (s->m_kind != HSA_NONE);
gcc_assert (s->m_gpu_implementation_p);
gcc_assert (s->m_hsa_implementation_p);

return s->m_bound_function ? s->m_bound_function->decl : NULL;
}
Expand All @@ -974,7 +971,7 @@ get_brig_function_name (tree decl)

hsa_function_summary *s = hsa_summaries->get (cgraph_node::get_create (d));
if (s->m_kind != HSA_NONE
&& s->m_gpu_implementation_p
&& s->m_hsa_implementation_p
&& s->m_bound_function)
d = s->m_bound_function->decl;

Expand Down Expand Up @@ -5875,7 +5872,7 @@ init_prologue (void)
hsa_bb *prologue = hsa_bb_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));

/* Create a magic number that is going to be printed by libgomp. */
unsigned index = hsa_get_number_decl_kernel_mappings ();
unsigned index = hsa_get_number_decl_function_mappings ();

/* Emit store to debug argument. */
if (PARAM_VALUE (PARAM_HSA_GEN_DEBUG_STORES) > 0)
Expand Down Expand Up @@ -6542,14 +6539,10 @@ generate_hsa (bool kernel)
if (hsa_cfun->m_kernel_dispatch_count)
init_hsa_num_threads ();

if (hsa_cfun->m_kern_p)
{
hsa_function_summary *s
= hsa_summaries->get (cgraph_node::get (hsa_cfun->m_decl));
hsa_add_kern_decl_mapping (current_function_decl, hsa_cfun->m_name,
hsa_add_function_decl_mapping (current_function_decl, hsa_cfun->m_name,
hsa_cfun->m_maximum_omp_data_size,
s->m_gridified_kernel_p);
}
hsa_summaries->get
(cgraph_node::get (hsa_cfun->m_decl)));

if (flag_checking)
{
Expand Down
Loading