static void verify_flow_insensitive_alias_info (void) { tree var; bitmap visited = BITMAP_ALLOC (NULL); referenced_var_iterator rvi; FOR_EACH_REFERENCED_VAR (var, rvi) { size_t j; var_ann_t ann; VEC(tree,gc) *may_aliases; tree alias; ann = var_ann (var); may_aliases = ann->may_aliases; for (j = 0; VEC_iterate (tree, may_aliases, j, alias); j++) { bitmap_set_bit (visited, DECL_UID (alias)); if (!may_be_aliased (alias)) { error ("non-addressable variable inside an alias set"); debug_variable (alias); goto err; } } }
static bool ptr_deref_may_alias_decl_p (tree ptr, tree decl) { struct ptr_info_def *pi; gcc_assert ((TREE_CODE (ptr) == SSA_NAME || TREE_CODE (ptr) == ADDR_EXPR || TREE_CODE (ptr) == INTEGER_CST) && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)); /* Non-aliased variables can not be pointed to. */ if (!may_be_aliased (decl)) return false; /* ADDR_EXPR pointers either just offset another pointer or directly specify the pointed-to set. */ if (TREE_CODE (ptr) == ADDR_EXPR) { tree base = get_base_address (TREE_OPERAND (ptr, 0)); if (base && INDIRECT_REF_P (base)) ptr = TREE_OPERAND (base, 0); else if (base && SSA_VAR_P (base)) return operand_equal_p (base, decl, 0); else if (base && CONSTANT_CLASS_P (base)) return false; else return true; } /* We can end up with dereferencing constant pointers. Just bail out in this case. */ if (TREE_CODE (ptr) == INTEGER_CST) return true; /* If we do not have useful points-to information for this pointer we cannot disambiguate anything else. */ pi = SSA_NAME_PTR_INFO (ptr); if (!pi) return true; /* If the decl can be used as a restrict tag and we have a restrict pointer and that pointers points-to set doesn't contain this decl then they can't alias. */ if (DECL_RESTRICTED_P (decl) && TYPE_RESTRICT (TREE_TYPE (ptr)) && pi->pt.vars_contains_restrict) return bitmap_bit_p (pi->pt.vars, DECL_UID (decl)); return pt_solution_includes (&pi->pt, decl); }
void dump_alias_info (FILE *file) { size_t i; const char *funcname = lang_hooks.decl_printable_name (current_function_decl, 2); referenced_var_iterator rvi; tree var; fprintf (file, "\n\nAlias information for %s\n\n", funcname); fprintf (file, "Aliased symbols\n\n"); FOR_EACH_REFERENCED_VAR (var, rvi) { if (may_be_aliased (var)) dump_variable (file, var); } fprintf (file, "\nCall clobber information\n"); fprintf (file, "\nESCAPED"); dump_points_to_solution (file, &cfun->gimple_df->escaped); fprintf (file, "\nCALLUSED"); dump_points_to_solution (file, &cfun->gimple_df->callused); fprintf (file, "\n\nFlow-insensitive points-to information\n\n"); for (i = 1; i < num_ssa_names; i++) { tree ptr = ssa_name (i); struct ptr_info_def *pi; if (ptr == NULL_TREE || SSA_NAME_IN_FREE_LIST (ptr)) continue; pi = SSA_NAME_PTR_INFO (ptr); if (pi) dump_points_to_info_for (file, ptr); } fprintf (file, "\n"); }