return m_hash;
}
-/* Set all points-to UIDs of aliases pointing to node N as UID. */
-
-static void
-set_alias_uids (symtab_node *n, int uid)
-{
- ipa_ref *ref;
- FOR_EACH_ALIAS (n, ref)
- {
- if (dump_file)
- fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
- xstrdup_for_dump (ref->referring->asm_name ()), uid);
-
- SET_DECL_PT_UID (ref->referring->decl, uid);
- set_alias_uids (ref->referring, uid);
- }
-}
-
/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
be applied. */
if (dump_file)
fprintf (dump_file, "Unified; Variable alias has been created.\n");
- set_alias_uids (original, DECL_UID (original->decl));
return true;
}
}
sem_item_optimizer::sem_item_optimizer ()
: worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
- m_varpool_node_hooks (NULL)
+ m_varpool_node_hooks (NULL), m_merged_variables ()
{
m_items.create (0);
bitmap_obstack_initialize (&m_bmstack);
m_items.release ();
bitmap_obstack_release (&m_bmstack);
+ m_merged_variables.release ();
}
/* Write IPA ICF summary for symbols. */
}
if (dbg_cnt (merged_ipa_icf))
- merged_p |= source->merge (alias);
+ {
+ bool merged = source->merge (alias);
+ merged_p |= merged;
+
+ if (merged && alias->type == VAR)
+ {
+ symtab_pair p = symtab_pair (source->node, alias->node);
+ m_merged_variables.safe_push (p);
+ }
+ }
}
}
+ if (!m_merged_variables.is_empty ())
+ fixup_points_to_sets ();
+
return merged_p;
}
+/* Fixup points to set PT. */
+
+void
+sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
+{
+ if (pt->vars == NULL)
+ return;
+
+ unsigned i;
+ symtab_pair *item;
+ FOR_EACH_VEC_ELT (m_merged_variables, i, item)
+ if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
+ bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
+}
+
+/* Set all points-to UIDs of aliases pointing to node N as UID. */
+
+static void
+set_alias_uids (symtab_node *n, int uid)
+{
+ ipa_ref *ref;
+ FOR_EACH_ALIAS (n, ref)
+ {
+ if (dump_file)
+ fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
+ xstrdup_for_dump (ref->referring->asm_name ()), uid);
+
+ SET_DECL_PT_UID (ref->referring->decl, uid);
+ set_alias_uids (ref->referring, uid);
+ }
+}
+
+/* Fixup points to analysis info. */
+
+void
+sem_item_optimizer::fixup_points_to_sets (void)
+{
+ /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
+
+ cgraph_node *cnode;
+ return;
+
+ FOR_EACH_DEFINED_FUNCTION (cnode)
+ {
+ tree name;
+ unsigned i;
+ function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
+ FOR_EACH_SSA_NAME (i, name, fn)
+ if (POINTER_TYPE_P (TREE_TYPE (name))
+ && SSA_NAME_PTR_INFO (name))
+ fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
+ fixup_pt_set (&fn->gimple_df->escaped);
+
+ /* The above get's us to 99% I guess, at least catching the
+ address compares. Below also gets us aliasing correct
+ but as said we're giving leeway to the situation with
+ readonly vars anyway, so ... */
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fn)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
+ if (call)
+ {
+ fixup_pt_set (gimple_call_use_set (call));
+ fixup_pt_set (gimple_call_clobber_set (call));
+ }
+ }
+ }
+
+ unsigned i;
+ symtab_pair *item;
+ FOR_EACH_VEC_ELT (m_merged_variables, i, item)
+ set_alias_uids (item->first, DECL_UID (item->first->decl));
+}
+
/* Dump function prints all class members to a FILE with an INDENT. */
void
unsigned int index;
};
+typedef std::pair<symtab_node *, symtab_node *> symtab_pair;
+
/* Semantic item is a base class that encapsulates all shared functionality
for both semantic function and variable items. */
class sem_item
processed. */
bool merge_classes (unsigned int prev_class_count);
+ /* Fixup points to analysis info. */
+ void fixup_points_to_sets (void);
+
+ /* Fixup points to set PT. */
+ void fixup_pt_set (struct pt_solution *pt);
+
/* Adds a newly created congruence class CLS to worklist. */
void worklist_push (congruence_class *cls);
/* Bitmap stack. */
bitmap_obstack m_bmstack;
+
+ /* Vector of merged variables. Needed for fixup of points-to-analysis
+ info. */
+ vec <symtab_pair> m_merged_variables;
}; // class sem_item_optimizer
} // ipa_icf namespace
--- /dev/null
+/* PR ipa/84658 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fmerge-all-constants -std=c++11" } */
+
+const int kTestCasesFoo[] = { 0, 1, 2, 3, 4, 5, 8, 15, 16, 17, 512, 1020, 1021, 1022, 1023, 1024 };
+const int kTestCasesBar[] = { 0, 1, 2, 3, 4, 5, 8, 15, 16, 17, 512, 1020, 1021, 1022, 1023, 1024 };
+
+void Foo() {
+ __builtin_printf("foo:");
+ for (int count : kTestCasesFoo) {
+ __builtin_printf("%d,", count);
+ }
+ __builtin_printf(";\n");
+}
+
+void Bar() {
+ __builtin_printf("bar:");
+ for (int count : kTestCasesBar) {
+ __builtin_printf("%d,", count);
+ }
+ __builtin_printf(";\n");
+}
+
+int main() {
+ Foo();
+ Bar();
+}
+
+/* { dg-output "foo:0,1,2,3,4,5,8,15,16,17,512,1020,1021,1022,1023,1024,;(\n|\n\r|\r)*" } */
+/* { dg-output "bar:0,1,2,3,4,5,8,15,16,17,512,1020,1021,1022,1023,1024,;(\n|\n\r|\r)*" } */