Commit 7039cebf by Kwok Cheung Yeung Committed by Andrew Stubbs

Add support for constructors and destuctors on GCN

2019-05-22  Kwok Cheung Yeung  <kcy@codesourcery.com>
            Andrew Stubbs  <amd@codesourcery.com>

	gcc/
	* config.gcc (gcc_cv_initfini_array): Set for AMD GCN.
	* config/gcn/gcn-run.c (init_array_kernel, fini_array_kernel): New.
	(kernel): Rename to...
	(main_kernel): ... this.
	(load_image): Load _init_array and _fini_array kernels.
	(run): Add argument for kernel to run.
	(main): Run init_array_kernel before main_kernel, and
	fini_array_kernel after.
	* config/gcn/gcn.c (gcn_handle_amdgpu_hsa_kernel_attribute): Allow
	amdgpu_hsa_kernel attribute on functions.
	(gcn_disable_constructors): Delete.
	(TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR): Delete.
	* config/gcn/crt0.c (size_t): Define.
	(_init_array, _fini_array): New.
	(__preinit_array_start, __preinit_array_end,
	__init_array_start, __init_array_end,
	__fini_array_start, __fini_array_end): Declare weak references.

Co-Authored-By: Andrew Stubbs <ams@codesourcery.com>

From-SVN: r271526
parent b7c28a47
2019-05-22 Kwok Cheung Yeung <kcy@codesourcery.com>
Andrew Stubbs <amd@codesourcery.com>
* config.gcc (gcc_cv_initfini_array): Set for AMD GCN.
* config/gcn/gcn-run.c (init_array_kernel, fini_array_kernel): New.
(kernel): Rename to...
(main_kernel): ... this.
(load_image): Load _init_array and _fini_array kernels.
(run): Add argument for kernel to run.
(main): Run init_array_kernel before main_kernel, and
fini_array_kernel after.
* config/gcn/gcn.c (gcn_handle_amdgpu_hsa_kernel_attribute): Allow
amdgpu_hsa_kernel attribute on functions.
(gcn_disable_constructors): Delete.
(TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR): Delete.
* config/gcn/crt0.c (size_t): Define.
(_init_array, _fini_array): New.
(__preinit_array_start, __preinit_array_end,
__init_array_start, __init_array_end,
__fini_array_start, __fini_array_end): Declare weak references.
2019-05-22 Andrew Stubbs <ams@codesourcery.com> 2019-05-22 Andrew Stubbs <ams@codesourcery.com>
* config/gcn/gcn.c (gcn_trampoline_init): Call "sorry" on GCN5. * config/gcn/gcn.c (gcn_trampoline_init): Call "sorry" on GCN5.
......
...@@ -1424,6 +1424,8 @@ amdgcn-*-amdhsa) ...@@ -1424,6 +1424,8 @@ amdgcn-*-amdhsa)
extra_programs="${extra_programs} mkoffload\$(exeext)" extra_programs="${extra_programs} mkoffload\$(exeext)"
tm_file="${tm_file} gcn/offload.h" tm_file="${tm_file} gcn/offload.h"
fi fi
# Force .init_array support.
gcc_cv_initfini_array=yes
;; ;;
moxie-*-elf) moxie-*-elf)
gas=yes gas=yes
......
...@@ -66,7 +66,9 @@ bool debug = false; ...@@ -66,7 +66,9 @@ bool debug = false;
hsa_agent_t device = { 0 }; hsa_agent_t device = { 0 };
hsa_queue_t *queue = NULL; hsa_queue_t *queue = NULL;
uint64_t kernel = 0; uint64_t init_array_kernel = 0;
uint64_t fini_array_kernel = 0;
uint64_t main_kernel = 0;
hsa_executable_t executable = { 0 }; hsa_executable_t executable = { 0 };
hsa_region_t kernargs_region = { 0 }; hsa_region_t kernargs_region = { 0 };
...@@ -427,14 +429,30 @@ load_image (const char *filename) ...@@ -427,14 +429,30 @@ load_image (const char *filename)
XHSA (hsa_fns.hsa_executable_freeze_fn (executable, ""), XHSA (hsa_fns.hsa_executable_freeze_fn (executable, ""),
"Freeze GCN executable"); "Freeze GCN executable");
/* Locate the "main" function, and read the kernel's properties. */ /* Locate the "_init_array" function, and read the kernel's properties. */
hsa_executable_symbol_t symbol; hsa_executable_symbol_t symbol;
XHSA (hsa_fns.hsa_executable_get_symbol_fn (executable, NULL, "_init_array",
device, 0, &symbol),
"Find '_init_array' function");
XHSA (hsa_fns.hsa_executable_symbol_get_info_fn
(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &init_array_kernel),
"Extract '_init_array' kernel object kernel object");
/* Locate the "_fini_array" function, and read the kernel's properties. */
XHSA (hsa_fns.hsa_executable_get_symbol_fn (executable, NULL, "_fini_array",
device, 0, &symbol),
"Find '_fini_array' function");
XHSA (hsa_fns.hsa_executable_symbol_get_info_fn
(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &fini_array_kernel),
"Extract '_fini_array' kernel object kernel object");
/* Locate the "main" function, and read the kernel's properties. */
XHSA (hsa_fns.hsa_executable_get_symbol_fn (executable, NULL, "main", XHSA (hsa_fns.hsa_executable_get_symbol_fn (executable, NULL, "main",
device, 0, &symbol), device, 0, &symbol),
"Find 'main' function"); "Find 'main' function");
XHSA (hsa_fns.hsa_executable_symbol_get_info_fn XHSA (hsa_fns.hsa_executable_symbol_get_info_fn
(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &kernel), (symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_OBJECT, &main_kernel),
"Extract kernel object"); "Extract 'main' kernel object");
XHSA (hsa_fns.hsa_executable_symbol_get_info_fn XHSA (hsa_fns.hsa_executable_symbol_get_info_fn
(symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE, (symbol, HSA_EXECUTABLE_SYMBOL_INFO_KERNEL_KERNARG_SEGMENT_SIZE,
&kernarg_segment_size), &kernarg_segment_size),
...@@ -684,7 +702,7 @@ gomp_print_output (struct kernargs *kernargs, bool final) ...@@ -684,7 +702,7 @@ gomp_print_output (struct kernargs *kernargs, bool final)
/* Execute an already-loaded kernel on the device. */ /* Execute an already-loaded kernel on the device. */
static void static void
run (void *kernargs) run (uint64_t kernel, void *kernargs)
{ {
/* A "signal" is used to launch and monitor the kernel. */ /* A "signal" is used to launch and monitor the kernel. */
hsa_signal_t signal; hsa_signal_t signal;
...@@ -822,11 +840,17 @@ main (int argc, char *argv[]) ...@@ -822,11 +840,17 @@ main (int argc, char *argv[])
kernargs->heap_ptr = (int64_t) &kernargs->heap; kernargs->heap_ptr = (int64_t) &kernargs->heap;
kernargs->heap.size = heap_size; kernargs->heap.size = heap_size;
/* Run constructors on the GPU. */
run (init_array_kernel, kernargs);
/* Run the kernel on the GPU. */ /* Run the kernel on the GPU. */
run (kernargs); run (main_kernel, kernargs);
unsigned int return_value = unsigned int return_value =
(unsigned int) kernargs->output_data.return_value; (unsigned int) kernargs->output_data.return_value;
/* Run destructors on the GPU. */
run (fini_array_kernel, kernargs);
unsigned int upper = (return_value & ~0xffff) >> 16; unsigned int upper = (return_value & ~0xffff) >> 16;
if (upper == 0xcafe) if (upper == 0xcafe)
printf ("Kernel exit value was never set\n"); printf ("Kernel exit value was never set\n");
......
...@@ -305,9 +305,7 @@ static tree ...@@ -305,9 +305,7 @@ static tree
gcn_handle_amdgpu_hsa_kernel_attribute (tree *node, tree name, gcn_handle_amdgpu_hsa_kernel_attribute (tree *node, tree name,
tree args, int, bool *no_add_attrs) tree args, int, bool *no_add_attrs)
{ {
if (FUNC_OR_METHOD_TYPE_P (*node) if (!FUNC_OR_METHOD_TYPE_P (*node))
&& TREE_CODE (*node) != FIELD_DECL
&& TREE_CODE (*node) != TYPE_DECL)
{ {
warning (OPT_Wattributes, "%qE attribute only applies to functions", warning (OPT_Wattributes, "%qE attribute only applies to functions",
name); name);
...@@ -3165,20 +3163,6 @@ gcn_valid_cvt_p (machine_mode from, machine_mode to, enum gcn_cvt_t op) ...@@ -3165,20 +3163,6 @@ gcn_valid_cvt_p (machine_mode from, machine_mode to, enum gcn_cvt_t op)
|| (to == DFmode && (from == SImode || from == SFmode))); || (to == DFmode && (from == SImode || from == SFmode)));
} }
/* Implement both TARGET_ASM_CONSTRUCTOR and TARGET_ASM_DESTRUCTOR.
The current loader does not support running code outside "main". This
hook implementation can be replaced or removed when that changes. */
void
gcn_disable_constructors (rtx symbol, int priority __attribute__ ((unused)))
{
tree d = SYMBOL_REF_DECL (symbol);
location_t l = d ? DECL_SOURCE_LOCATION (d) : UNKNOWN_LOCATION;
sorry_at (l, "GCN does not support static constructors or destructors");
}
/* }}} */ /* }}} */
/* {{{ Costs. */ /* {{{ Costs. */
...@@ -5995,10 +5979,6 @@ print_operand (FILE *file, rtx x, int code) ...@@ -5995,10 +5979,6 @@ print_operand (FILE *file, rtx x, int code)
#define TARGET_ARG_PARTIAL_BYTES gcn_arg_partial_bytes #define TARGET_ARG_PARTIAL_BYTES gcn_arg_partial_bytes
#undef TARGET_ASM_ALIGNED_DI_OP #undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.8byte\t" #define TARGET_ASM_ALIGNED_DI_OP "\t.8byte\t"
#undef TARGET_ASM_CONSTRUCTOR
#define TARGET_ASM_CONSTRUCTOR gcn_disable_constructors
#undef TARGET_ASM_DESTRUCTOR
#define TARGET_ASM_DESTRUCTOR gcn_disable_constructors
#undef TARGET_ASM_FILE_START #undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START output_file_start #define TARGET_ASM_FILE_START output_file_start
#undef TARGET_ASM_FUNCTION_PROLOGUE #undef TARGET_ASM_FUNCTION_PROLOGUE
......
...@@ -19,5 +19,61 @@ ...@@ -19,5 +19,61 @@
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
typedef long long size_t;
/* Provide an entry point symbol to silence a linker warning. */ /* Provide an entry point symbol to silence a linker warning. */
void _start() {} void _start() {}
#ifdef USE_NEWLIB_INITFINI
extern void __libc_init_array (void) __attribute__((weak));
extern void __libc_fini_array (void) __attribute__((weak));
__attribute__((amdgpu_hsa_kernel ()))
void _init_array()
{
__libc_init_array ();
}
__attribute__((amdgpu_hsa_kernel ()))
void _fini_array()
{
__libc_fini_array ();
}
#endif
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));
__attribute__((amdgpu_hsa_kernel ()))
void _init_array()
{
/* Iterate over all the init routines. */
size_t count;
size_t i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++)
__preinit_array_start[i] ();
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++)
__init_array_start[i] ();
}
__attribute__((amdgpu_hsa_kernel ()))
void _fini_array()
{
size_t count;
size_t i;
count = __fini_array_end - __fini_array_start;
for (i = count; i > 0; i--)
__fini_array_start[i-1] ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment