attr-alias.c: New testcase.
authorJan Hubicka <jh@suse.cz>
Tue, 4 Jun 2013 19:44:51 +0000 (21:44 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 4 Jun 2013 19:44:51 +0000 (19:44 +0000)
* gcc.dg/tree-ssa/attr-alias.c: New testcase.

* ipa-inline.c (update_caller_keys): Fix availability test.
(update_callee_keys): Likewise.
* symtab.c (symtab_alias_ultimate_target): Make availaiblity logic
to follow ELF standard.

From-SVN: r199670

gcc/ChangeLog
gcc/ipa-inline.c
gcc/symtab.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c [new file with mode: 0644]

index dfe2f8854c0af2258a4c338cbd7bb69bfe591876..690c9680e613018092054d2bbfbd06cfd0f54848 100644 (file)
@@ -1,3 +1,10 @@
+2013-06-04  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-inline.c (update_caller_keys): Fix availability test.
+       (update_callee_keys): Likewise.
+       * symtab.c (symtab_alias_ultimate_target): Make availaiblity logic
+       to follow ELF standard.
+
 2013-06-04  Jürgen Urban  <JuergenUrban@gmx.de>
 
        * config.gcc (mipsr5900-*-elf*, mipsr5900el-*-elf*, mips64r5900-*-elf*)
index a378c08f42f7ab538377633bb97a3164cdea85f9..283e517c6dc3f0c2b4ee1c5c5b3bf6d26ba28f90 100644 (file)
@@ -1101,7 +1101,6 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
   struct ipa_ref *ref;
 
   if ((!node->symbol.alias && !inline_summary (node)->inlinable)
-      || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
       || node->global.inlined_to)
     return;
   if (!bitmap_set_bit (updated_nodes, node->uid))
@@ -1162,7 +1161,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
        if (e->inline_failed
            && (callee = cgraph_function_or_thunk_node (e->callee, &avail))
            && inline_summary (callee)->inlinable
-           && cgraph_function_body_availability (callee) >= AVAIL_AVAILABLE
+           && avail >= AVAIL_AVAILABLE
            && !bitmap_bit_p (updated_nodes, callee->uid))
          {
            if (can_inline_edge_p (e, false)
index af8e70bb02cb609487c4abe0c5dd0b2dccc28f91..02d3da170ab22e267a1addaf05a3002758ed664d 100644 (file)
@@ -834,19 +834,64 @@ symtab_node_availability (symtab_node node)
 symtab_node
 symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
 {
+  bool weakref_p = false;
+
+  if (!node->symbol.alias)
+    {
+      if (availability)
+        *availability = symtab_node_availability (node);
+      return node;
+    }
+
+  /* To determine visibility of the target, we follow ELF semantic of aliases.
+     Here alias is an alternative assembler name of a given definition. Its
+     availablity prevails the availablity of its target (i.e. static alias of
+     weak definition is available.
+
+     Weakref is a different animal (and not part of ELF per se). It is just
+     alternative name of a given symbol used within one complation unit
+     and is translated prior hitting the object file.  It inherits the
+     visibility of its target (i.e. weakref of non-overwritable definition
+     is non-overwritable, while weakref of weak definition is weak).
+
+     If we ever get into supporting targets with different semantics, a target
+     hook will be needed here.  */
+
   if (availability)
-    *availability = symtab_node_availability (node);
+    {
+      weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
+      if (!weakref_p)
+        *availability = symtab_node_availability (node);
+      else
+       *availability = AVAIL_LOCAL;
+    }
   while (node)
     {
       if (node->symbol.alias && node->symbol.analyzed)
        node = symtab_alias_target (node);
       else
-       return node;
-      if (node && availability)
+       {
+         if (!availability)
+           ;
+         else if (node->symbol.analyzed)
+           {
+             if (weakref_p)
+               {
+                 enum availability a = symtab_node_availability (node);
+                 if (a < *availability)
+                   *availability = a;
+               }
+           }
+         else
+           *availability = AVAIL_NOT_AVAILABLE;
+         return node;
+       }
+      if (node && availability && weakref_p)
        {
          enum availability a = symtab_node_availability (node);
          if (a < *availability)
            *availability = a;
+          weakref_p = DECL_EXTERNAL (node->symbol.decl) && node->symbol.alias;
        }
     }
   if (availability)
index d0b4700db3fa08905e34cf3fff9158c567d73b1a..399d85eb7ddac1a3c17da404328a32b551ee9eb9 100644 (file)
@@ -1,3 +1,7 @@
+2013-06-04  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.dg/tree-ssa/attr-alias.c: New testcase.
+
 2013-06-04  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
        * c-c++-common/cilk-plus/AN/array_test1.c (main): Replaced argc, argv
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c b/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
new file mode 100644 (file)
index 0000000..a9b1d07
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-require-alias "" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+void abort (void);
+__attribute__ ((weak))
+int test() 
+{
+   return 0;
+}
+static int test2() __attribute__ ((alias("test")));
+static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
+static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test")));
+main()
+{
+  test();
+  test2();
+  test3();
+  test4();
+}
+
+/* calls to test1 and test2 can be inlined and optmized away. Calls
+   to test and test4 are overwritable.  */
+
+/* { dg-final { scan-tree-dump-times "test (" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "test4 (" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test1 (" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test2 (" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
+/* { dg-do compile } */
+/* { dg-require-alias "" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+void abort (void);
+__attribute__ ((weak))
+int test() 
+{
+   return 0;
+}
+static int test2() __attribute__ ((alias("test")));
+static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
+static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test")));
+main()
+{
+  test();
+  test2();
+  test3();
+  test4();
+}
+
+/* calls to test1 and test2 can be inlined and optmized away. Calls
+   to test and test4 are overwritable.  */
+
+/* { dg-final { scan-tree-dump-times "test (" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "test4 (" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test1 (" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "test2 (" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+