@@ -55,6 +55,48 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tree-pass.h"
#include "cgraph.h"
+#include "tree-pretty-print.h"
+
+tree
+merge_comdat_group (tree *val2, tree newgroup,
+ symtab_node *symbol,
+ hash_map<tree, symtab_node *>& comdat_head_map)
+{
+ /* *val2 is TOP. */
+ if (val2 == NULL || *val2 == NULL)
+ return newgroup;
+
+ /* *val2 is BOTTOM. */
+ else if (*val2 == error_mark_node)
+ return error_mark_node;
+
+ /* *val2 is COMDAT. */
+ else
+ {
+ /* COMDAT meet TOP == COMDAT. */
+ if (newgroup == NULL)
+ return *val2;
+
+ /* COMDAT meet BOTTOM == BOTTOM. */
+ else if (newgroup == error_mark_node)
+ return error_mark_node;
+
+ /* COMDAT meet COMDAT == COMDAT if both are equal else
+ create new comdat group and assign it to symbol. */
+ else
+ {
+ if (newgroup == *val2)
+ return newgroup;
+
+ /* FIXME: using DECL_NAME (symbol->decl) as name of comdat section. */
+ newgroup = DECL_NAME (symbol->decl);
+ DECL_COMDAT (symbol->decl) = 1;
+ symbol->set_comdat_group (newgroup);
+ comdat_head_map.put (newgroup, symbol);
+ return newgroup;
+ }
+ }
+}
/* Main dataflow loop propagating comdat groups across
the symbol table. All references to SYMBOL are examined
@@ -63,7 +105,8 @@ along with GCC; see the file COPYING3. If not see
tree
propagate_comdat_group (struct symtab_node *symbol,
- tree newgroup, hash_map<symtab_node *, tree> &map)
+ tree newgroup, hash_map<symtab_node *, tree> &map,
+ hash_map<tree, symtab_node *>& comdat_head_map)
{
int i;
struct ipa_ref *ref;
@@ -78,7 +121,7 @@ propagate_comdat_group (struct symtab_node *symbol,
if (ref->use == IPA_REF_ALIAS)
{
- newgroup = propagate_comdat_group (symbol2, newgroup, map);
+ newgroup = propagate_comdat_group (symbol2, newgroup, map, comdat_head_map);
continue;
}
@@ -105,7 +148,8 @@ propagate_comdat_group (struct symtab_node *symbol,
/* The actual merge operation. */
tree *val2 = map.get (symbol2);
-
+ newgroup = merge_comdat_group (val2, newgroup, symbol, comdat_head_map);
+#if 0
if (val2 && *val2 != newgroup)
{
if (!newgroup)
@@ -113,6 +157,7 @@ propagate_comdat_group (struct symtab_node *symbol,
else
newgroup = error_mark_node;
}
+#endif
}
/* If we analyze function, walk also callers. */
@@ -129,7 +174,7 @@ propagate_comdat_group (struct symtab_node *symbol,
{
/* Thunks can not call across section boundary. */
if (cn->thunk.thunk_p)
- newgroup = propagate_comdat_group (symbol2, newgroup, map);
+ newgroup = propagate_comdat_group (symbol2, newgroup, map, comdat_head_map);
/* If we see inline clone, its comdat group actually
corresponds to the comdat group of the function it
is inlined to. */
@@ -140,7 +185,8 @@ propagate_comdat_group (struct symtab_node *symbol,
/* The actual merge operation. */
tree *val2 = map.get (symbol2);
-
+ newgroup = merge_comdat_group (val2, newgroup, symbol, comdat_head_map);
+#if 0
if (val2 && *val2 != newgroup)
{
if (!newgroup)
@@ -148,6 +194,7 @@ propagate_comdat_group (struct symtab_node *symbol,
else
newgroup = error_mark_node;
}
+#endif
}
return newgroup;
}
@@ -310,7 +357,7 @@ ipa_comdats (void)
if (group == error_mark_node)
continue;
- newgroup = propagate_comdat_group (symbol, group, map);
+ newgroup = propagate_comdat_group (symbol, group, map, comdat_head_map);
/* If nothing changed, proceed to next symbol. */
if (newgroup == group)