===================================================================
@@ -165,6 +165,7 @@
extern int function_ok_for_sibcall (tree);
extern int rs6000_reg_parm_stack_space (tree, bool);
extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree);
+extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree);
extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
extern bool rs6000_elf_in_small_data_p (const_tree);
#ifdef ARGS_SIZE_RTX
===================================================================
@@ -29156,7 +29156,11 @@
sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
SYMBOL_REF_BLOCK_OFFSET (symbol));
- ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
+ fprintf (asm_out_file, "%s", SET_ASM_OP);
+ RS6000_OUTPUT_BASENAME (asm_out_file, XSTR (symbol, 0));
+ fprintf (asm_out_file, ",");
+ RS6000_OUTPUT_BASENAME (asm_out_file, buffer);
+ fprintf (asm_out_file, "\n");
}
static void
@@ -29453,6 +29457,82 @@
asm_out_file);
}
+struct declare_alias_data
+{
+ FILE *file;
+ bool function_descriptor;
+};
+
+/* Declare alias N. A helper function for for_node_and_aliases. */
+
+static bool
+rs6000_declare_alias (struct symtab_node *n, void *d)
+{
+ struct declare_alias_data *data = (struct declare_alias_data *)d;
+ /* Main symbol is output specially, because varasm machinery does part of
+ the job for us - we do not need to declare .globl/lglobs and such. */
+ if (!n->alias || n->weakref)
+ return false;
+
+ /* Prevent assemble_alias from trying to use .set pseudo operation
+ that does not behave as expected by the middle-end. */
+ TREE_ASM_WRITTEN (n->decl) = true;
+
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl));
+ char *buffer = (char *) alloca (strlen (name) + 2);
+ char *p;
+ int dollar_inside = 0;
+
+ strcpy (buffer, name);
+ p = strchr (buffer, '$');
+ while (p) {
+ *p = '_';
+ dollar_inside++;
+ p = strchr (p + 1, '$');
+ }
+ if (TREE_PUBLIC (n->decl))
+ {
+ if (!RS6000_WEAK || !DECL_WEAK (n->decl))
+ {
+ if (dollar_inside) {
+ if (data->function_descriptor)
+ fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name);
+ else
+ fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name);
+ }
+ if (data->function_descriptor)
+ fputs ("\t.globl .", data->file);
+ else
+ fputs ("\t.globl ", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ putc ('\n', data->file);
+ }
+ else if (DECL_WEAK (n->decl) && !data->function_descriptor)
+ ASM_WEAKEN_DECL (data->file, n->decl, name, NULL);
+ }
+ else
+ {
+ if (dollar_inside)
+ {
+ if (data->function_descriptor)
+ fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name);
+ else
+ fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name);
+ }
+ if (data->function_descriptor)
+ fputs ("\t.lglobl .", data->file);
+ else
+ fputs ("\t.lglobl ", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ putc ('\n', data->file);
+ }
+ if (data->function_descriptor)
+ fputs (".", data->file);
+ RS6000_OUTPUT_BASENAME (data->file, buffer);
+ fputs (":\n", data->file);
+ return false;
+}
+
/* This macro produces the initial definition of a function name.
On the RS/6000, we need to place an extra '.' in the function name and
output the function descriptor.
@@ -29462,14 +29542,19 @@
text_section was selected. We do have to go back to that csect, however.
The third and fourth parameters to the .function pseudo-op (16 and 044)
- are placeholders which no longer have any use. */
+ are placeholders which no longer have any use.
+ Because AIX assembler's .set command has unexpected semantics, we output
+ all aliases as alternative labels in front of the definition. */
+
void
rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl)
{
char *buffer = (char *) alloca (strlen (name) + 1);
char *p;
int dollar_inside = 0;
+ struct declare_alias_data data = {file, false};
+
strcpy (buffer, name);
p = strchr (buffer, '$');
while (p) {
@@ -29505,6 +29590,7 @@
fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (":\n", file);
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (", TOC[tc0], 0\n", file);
@@ -29513,11 +29599,26 @@
putc ('.', file);
RS6000_OUTPUT_BASENAME (file, buffer);
fputs (":\n", file);
+ data.function_descriptor = true;
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (decl))
xcoffout_declare_function (file, decl, buffer);
return;
}
+/* This macro produces the initial definition of a object (variable) name.
+ Because AIX assembler's .set command has unexpected semantics, we output
+ all aliases as alternative labels in front of the definition. */
+
+void
+rs6000_xcoff_declare_object_name (FILE *file, const char *name, tree decl)
+{
+ struct declare_alias_data data = {file, false};
+ RS6000_OUTPUT_BASENAME (file, name);
+ fputs (":\n", file);
+ symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true);
+}
+
#ifdef HAVE_AS_TLS
static void
rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
===================================================================
@@ -139,6 +139,9 @@
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
rs6000_xcoff_declare_function_name ((FILE), (NAME), (DECL))
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ rs6000_xcoff_declare_object_name ((FILE), (NAME), (DECL))
/* Output a reference to SYM on FILE. */
@@ -280,16 +283,18 @@
/* This is how we tell the assembler that two symbols have the same value. */
#define SET_ASM_OP "\t.set "
-/* This is how we tell the assembler to equate two values. */
-#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
- do { fprintf ((FILE), "%s", SET_ASM_OP); \
- RS6000_OUTPUT_BASENAME (FILE, LABEL1); \
- fprintf (FILE, ","); \
- RS6000_OUTPUT_BASENAME (FILE, LABEL2); \
- fprintf (FILE, "\n"); \
- } while (0)
+/* This is how we tell the assembler to equate two values.
+ The semantic of AIX assembler's .set do not correspond to middle-end expectations.
+ We output aliases as alternative symbols in the front of the definition
+ via DECLARE_FUNCTION_NAME and DECLARE_OBJECT_NAME.
+ We still need to define this macro to let middle-end know that aliases are
+ supported.
+ */
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0)
/* Used by rs6000_assemble_integer, among others. */
+
+/* Used by rs6000_assemble_integer, among others. */
#define DOUBLE_INT_ASM_OP "\t.llong\t"
/* Output before instructions. */
===================================================================
@@ -567,9 +567,6 @@
TODO: We can also update virtual tables. */
if (node->callers
- /* FIXME: currently this optimization breaks on AIX. Disable it for targets
- without comdat support for now. */
- && SUPPORTS_ONE_ONLY
&& can_replace_by_local_alias (node))
{
struct cgraph_node *alias = cgraph (symtab_nonoverwritable_alias (node));
@@ -672,10 +669,7 @@
/* Update virtual tables to point to local aliases where possible. */
if (DECL_VIRTUAL_P (vnode->decl)
- && !DECL_EXTERNAL (vnode->decl)
- /* FIXME: currently this optimization breaks on AIX. Disable it for targets
- without comdat support for now. */
- && SUPPORTS_ONE_ONLY)
+ && !DECL_EXTERNAL (vnode->decl))
{
int i;
struct ipa_ref *ref;
===================================================================
@@ -8,7 +8,6 @@
/* { dg-do run }
{ dg-options "-O2" }
{ dg-require-alias "" }
- { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } }
{ dg-additional-sources "globalalias-2.c" } */
extern int test2count;
extern void abort (void);
===================================================================
@@ -9,7 +9,6 @@
/* { dg-do run }
{ dg-options "-Wstrict-aliasing=2 -fstrict-aliasing" }
{ dg-require-alias "" }
- { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } }
{ dg-additional-sources "localalias-2.c" } */
extern void abort (void);
extern int test2count;