[gcn] mkoffload.cc: Print fatal error if -march has no multilib but generic has
Assume that a distro has configured, e.g., a gfx9-generic multilib but not for gfx902. In that case, mkoffload would fail to link with "error: incompatible mach". With this commit, an error is printed suggesting to try the associated generic architecture instead. The behavior is unchanged if there is a multilib available for the specific ISA or when there is also no multilib for the generic ICA. Note: The build of generic multilibs are currently not enabled by default; they also require the linker/assembler of LLVM 19 or newer and, in particular, for the execution a future ROCm release. (The next one? In any case, 6.3.2 does not support generic ISAs, yet.) gcc/ChangeLog: * config/gcn/mkoffload.cc (enum elf_arch_code): Add EF_AMDGPU_MACH_AMDGCN_NONE. (elf_arch): Use enum elf_arch_code as type. (tool_cleanup): Silence warning by removing tailing '.' from error. (get_arch_name): Return enum elf_arch_code. (check_for_missing_lib): New; print fatal error if the multilib is not available but it is for the associate generic ISA. (main): Call it.
This commit is contained in:
parent
7037fdf6bd
commit
4ce8ad684b
1 changed files with 94 additions and 7 deletions
|
@ -53,6 +53,7 @@
|
|||
|
||||
/* Extract the EF_AMDGPU_MACH_AMDGCN_GFXnnn from the def file. */
|
||||
enum elf_arch_code {
|
||||
EF_AMDGPU_MACH_AMDGCN_NONE = -1, /* For generic handling. */
|
||||
#define GCN_DEVICE(name, NAME, ELF_ARCH, ...) \
|
||||
EF_AMDGPU_MACH_AMDGCN_ ## NAME = ELF_ARCH,
|
||||
#include "gcn-devices.def"
|
||||
|
@ -135,9 +136,8 @@ static struct obstack files_to_cleanup;
|
|||
enum offload_abi offload_abi = OFFLOAD_ABI_UNSET;
|
||||
const char *offload_abi_host_opts = NULL;
|
||||
|
||||
uint32_t elf_arch = EF_AMDGPU_MACH_AMDGCN_GFX900; // Default GPU architecture.
|
||||
enum elf_arch_code elf_arch = EF_AMDGPU_MACH_AMDGCN_GFX900; // Default GPU architecture.
|
||||
uint32_t elf_flags = EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4;
|
||||
|
||||
static int gcn_stack_size = 0; /* Zero means use default. */
|
||||
|
||||
/* Delete tempfiles. */
|
||||
|
@ -782,7 +782,7 @@ compile_native (const char *infile, const char *outfile, const char *compiler,
|
|||
obstack_ptr_grow (&argv_obstack, ".c");
|
||||
if (!offload_abi_host_opts)
|
||||
fatal_error (input_location,
|
||||
"%<-foffload-abi-host-opts%> not specified.");
|
||||
"%<-foffload-abi-host-opts%> not specified");
|
||||
obstack_ptr_grow (&argv_obstack, offload_abi_host_opts);
|
||||
obstack_ptr_grow (&argv_obstack, infile);
|
||||
obstack_ptr_grow (&argv_obstack, "-c");
|
||||
|
@ -796,16 +796,15 @@ compile_native (const char *infile, const char *outfile, const char *compiler,
|
|||
obstack_free (&argv_obstack, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
static enum elf_arch_code
|
||||
get_arch (const char *str, const char *with_arch_str)
|
||||
{
|
||||
/* Use the def file to map the name to the elf_arch_code. */
|
||||
if (!str) ;
|
||||
#define GCN_DEVICE(name, NAME, ELF, ...) \
|
||||
else if (strcmp (str, #name) == 0) \
|
||||
return ELF;
|
||||
return (enum elf_arch_code) ELF;
|
||||
#include "gcn-devices.def"
|
||||
#undef GCN_DEVICE
|
||||
|
||||
/* else */
|
||||
error ("unrecognized argument in option %<-march=%s%>", str);
|
||||
|
@ -839,7 +838,91 @@ get_arch (const char *str, const char *with_arch_str)
|
|||
|
||||
exit (FATAL_EXIT_CODE);
|
||||
|
||||
return 0;
|
||||
return EF_AMDGPU_MACH_AMDGCN_NONE;
|
||||
}
|
||||
|
||||
static const char*
|
||||
get_arch_name (enum elf_arch_code arch_code)
|
||||
{
|
||||
switch (arch_code)
|
||||
{
|
||||
#define GCN_DEVICE(name, NAME, ELF, ...) \
|
||||
case EF_AMDGPU_MACH_AMDGCN_ ## NAME: \
|
||||
return #name;
|
||||
#include "../../gcc/config/gcn/gcn-devices.def"
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* If an generic arch exists and for the chosen arch no (multi)lib is
|
||||
available, print a fatal error - and suggest to compile for the generic
|
||||
version instead. */
|
||||
|
||||
static void
|
||||
check_for_missing_lib (enum elf_arch_code elf_arch,
|
||||
enum elf_arch_code default_arch)
|
||||
{
|
||||
enum elf_arch_code generic_arch;
|
||||
switch (elf_arch)
|
||||
{
|
||||
#define GCN_DEVICE(name, NAME, ELF, ISA, XNACK, SRAM, WAVE64, CU, \
|
||||
MAX_ISA_VGPRS, GEN_VER, ARCH_FAM, GEN_MACH, ...) \
|
||||
case EF_AMDGPU_MACH_AMDGCN_ ## NAME: \
|
||||
generic_arch = EF_AMDGPU_MACH_AMDGCN_ ## GEN_MACH; break;
|
||||
#include "../../gcc/config/gcn/gcn-devices.def"
|
||||
default: generic_arch = EF_AMDGPU_MACH_AMDGCN_NONE;
|
||||
}
|
||||
|
||||
/* If not generic or the default arch, the library version exists. */
|
||||
if (generic_arch == EF_AMDGPU_MACH_AMDGCN_NONE || elf_arch == default_arch)
|
||||
return;
|
||||
|
||||
/* Search gcn_arch in the multilib config, which might look like
|
||||
"march=gfx900/march=gfx906". */
|
||||
const char *p = multilib_options;
|
||||
const char *q = NULL;
|
||||
const char *isa_name = get_arch_name (elf_arch);
|
||||
while ((q = strstr (p, isa_name)) != NULL)
|
||||
{
|
||||
if (multilib_options + strlen ("march=") <= q
|
||||
&& startswith (&q[-strlen ("march=")], "march="))
|
||||
{
|
||||
const char r = q[strlen (isa_name)];
|
||||
if (r != '\0' && r != '/')
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Specified -march= exists in the multilib. */
|
||||
if (q != NULL)
|
||||
return;
|
||||
|
||||
/* If no lib, try to find one for the generic arch. */
|
||||
const char *gen_name = get_arch_name (generic_arch);
|
||||
if (generic_arch != default_arch)
|
||||
{
|
||||
p = multilib_options;
|
||||
while ((q = strstr (p, gen_name)) != NULL)
|
||||
{
|
||||
if (multilib_options + strlen ("march=") <= q
|
||||
&& startswith (&q[-strlen ("march=")], "march="))
|
||||
{
|
||||
const char r = q[strlen (gen_name)];
|
||||
if (r != '\0' && r != '/')
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (q == NULL)
|
||||
return;
|
||||
}
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"GCC was built without library support for %<-march=%s%>; "
|
||||
"consider compiling for the associated generic architecture "
|
||||
"%<-march=%s%> instead", isa_name, gen_name);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -864,6 +947,7 @@ main (int argc, char **argv)
|
|||
elf_arch = get_arch (configure_default_options[0].value, NULL);
|
||||
break;
|
||||
}
|
||||
enum elf_arch_code default_arch = elf_arch;
|
||||
|
||||
obstack_init (&files_to_cleanup);
|
||||
if (atexit (mkoffload_cleanup) != 0)
|
||||
|
@ -998,6 +1082,8 @@ main (int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
check_for_missing_lib (elf_arch, default_arch);
|
||||
|
||||
if (!(fopenacc ^ fopenmp))
|
||||
fatal_error (input_location,
|
||||
"either %<-fopenacc%> or %<-fopenmp%> must be set");
|
||||
|
@ -1056,6 +1142,7 @@ main (int argc, char **argv)
|
|||
case ELF: if (GEN_VER) SET_GENERIC_VERSION (elf_flags, GEN_VER); break;
|
||||
#include "gcn-devices.def"
|
||||
#undef GCN_DEVICE
|
||||
case EF_AMDGPU_MACH_AMDGCN_NONE: gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Build arguments for compiler pass. */
|
||||
|
|
Loading…
Add table
Reference in a new issue