+2015-09-18 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/47679
+ * tree-ssa-dom.c (avail_exprs): No longer file scoped. Bury
+ it into the avail_exprs_stack class.
+ (pass_dominator::execute): Corresponding changes to declaration
+ and initialization of avail_exprs. Pass avail_exprs to
+ dump_dominator_optimization_stats.
+ (record_cond): Extract avail_exprs from avail_exprs_stack.
+ (lookup_avail_expr): Similarly.
+ (htab_staticstics): Remove unnecessary prototype. Move to earlier
+ position in file.
+ (dump_dominator_optimization_stats): Make static and prototype.
+ Add argument for the hash table to dump.
+ (debug_dominator_optimization_stats): Remove.
+ * tree-ssa-dom.h (dump_dominator_optimization_stats): Remove
+ prototype.
+ (debug_dominator_optimization_stats): Similarly.
+ * tree-ssa-scopedtables.h (class avail_exprs_stack): Add missing
+ "void" in prototype for pop_to_marker method. Add accessor method
+ for the underlying avail_exprs table.
+
+ * tree-ssa-threadedge.c: Remove trailing whitespace.
+
2014-09-18 John David Anglin <danglin@gcc.gnu.org>
* config/pa/pa-protos.h (pa_cint_ok_for_move): Change argument type to
vec<cond_equivalence> cond_equivalences;
};
-/* Hash table with expressions made available during the renaming process.
- When an assignment of the form X_i = EXPR is found, the statement is
- stored in this table. If the same expression EXPR is later found on the
- RHS of another statement, it is replaced with X_i (thus performing
- global redundancy elimination). Similarly as we pass through conditionals
- we record the conditional itself as having either a true or false value
- in this table. */
-static hash_table<expr_elt_hasher> *avail_exprs;
-
/* Unwindable equivalences, both const/copy and expression varieties. */
static const_and_copies *const_and_copies;
static avail_exprs_stack *avail_exprs_stack;
/* Local functions. */
static void optimize_stmt (basic_block, gimple_stmt_iterator);
static tree lookup_avail_expr (gimple, bool);
-static void htab_statistics (FILE *,
- const hash_table<expr_elt_hasher> &);
static void record_cond (cond_equivalence *);
static void record_equality (tree, tree);
static void record_equivalences_from_phis (basic_block);
static void eliminate_redundant_computations (gimple_stmt_iterator *);
static void record_equivalences_from_stmt (gimple, int);
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
+static void dump_dominator_optimization_stats (FILE *file,
+ hash_table<expr_elt_hasher> *);
+
/* Free the edge_info data attached to E, if it exists. */
memset (&opt_stats, 0, sizeof (opt_stats));
/* Create our hash tables. */
- avail_exprs = new hash_table<expr_elt_hasher> (1024);
+ hash_table<expr_elt_hasher> *avail_exprs
+ = new hash_table<expr_elt_hasher> (1024);
avail_exprs_stack = new class avail_exprs_stack (avail_exprs);
const_and_copies = new class const_and_copies ();
need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Debugging dumps. */
if (dump_file && (dump_flags & TDF_STATS))
- dump_dominator_optimization_stats (dump_file);
+ dump_dominator_optimization_stats (dump_file, avail_exprs);
loop_optimizer_finalize ();
record_temporary_equivalences (e);
}
+/* Dump statistics for the hash table HTAB. */
+
+static void
+htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
+{
+ fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
+ (long) htab.size (),
+ (long) htab.elements (),
+ htab.collisions ());
+}
+
/* Dump SSA statistics on FILE. */
-void
-dump_dominator_optimization_stats (FILE *file)
+static void
+dump_dominator_optimization_stats (FILE *file,
+ hash_table<expr_elt_hasher> *avail_exprs)
{
fprintf (file, "Total number of statements: %6ld\n\n",
opt_stats.num_stmts);
}
-/* Dump SSA statistics on stderr. */
-
-DEBUG_FUNCTION void
-debug_dominator_optimization_stats (void)
-{
- dump_dominator_optimization_stats (stderr);
-}
-
-
-/* Dump statistics for the hash table HTAB. */
-
-static void
-htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab)
-{
- fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
- (long) htab.size (),
- (long) htab.elements (),
- htab.collisions ());
-}
-
-
/* Enter condition equivalence into the expression hash table.
This indicates that a conditional expression has a known
boolean value. */
class expr_hash_elt *element = new expr_hash_elt (&p->cond, p->value);
expr_hash_elt **slot;
+ hash_table<expr_elt_hasher> *avail_exprs = avail_exprs_stack->avail_exprs ();
slot = avail_exprs->find_slot_with_hash (element, element->hash (), INSERT);
if (*slot == NULL)
{
return NULL_TREE;
/* Finally try to find the expression in the main expression hash table. */
+ hash_table<expr_elt_hasher> *avail_exprs = avail_exprs_stack->avail_exprs ();
slot = avail_exprs->find_slot (&element, (insert ? INSERT : NO_INSERT));
if (slot == NULL)
{
#ifndef GCC_TREE_SSA_DOM_H
#define GCC_TREE_SSA_DOM_H
-extern void dump_dominator_optimization_stats (FILE *);
-extern void debug_dominator_optimization_stats (void);
extern bool simple_iv_increment_p (gimple);
#endif /* GCC_TREE_SSA_DOM_H */
/* Restore the AVAIL_EXPRs table to its state when the last marker
was pushed. */
- void pop_to_marker ();
+ void pop_to_marker (void);
/* Record a single available expression that can be unwound. */
void record_expr (expr_hash_elt_t, expr_hash_elt_t, char);
+ /* Get the underlying hash table. Would this be better as
+ class inheritance? */
+ hash_table<expr_elt_hasher> *avail_exprs (void)
+ { return m_avail_exprs; }
+
private:
vec<std::pair<expr_hash_elt_t, expr_hash_elt_t> > m_stack;
hash_table<expr_elt_hasher> *m_avail_exprs;
/* Special case. We can get blocks that are forwarders, but are
not optimized away because they forward from outside a loop
to the loop header. We want to thread through them as we can
- sometimes thread to the loop exit, which is obviously profitable.
+ sometimes thread to the loop exit, which is obviously profitable.
the interesting case here is when the block has PHIs. */
if (gsi_end_p (gsi_start_nondebug_bb (bb))
&& !gsi_end_p (gsi_start_phis (bb)))
return true;
-
+
/* If BB has a single successor or a single predecessor, then
there is no threading opportunity. */
if (single_succ_p (bb) || single_pred_p (bb))
edge E. Record unwind information for the equivalences onto STACK.
If a PHI which prevents threading is encountered, then return FALSE
- indicating we should not thread this edge, else return TRUE.
+ indicating we should not thread this edge, else return TRUE.
If SRC_MAP/DST_MAP exist, then mark the source and destination SSA_NAMEs
of any equivalences recorded. We use this to make invalidation after
}
/* Record the context sensitive equivalence if we were able
- to simplify this statement.
+ to simplify this statement.
If we have traversed a backedge at some point during threading,
- then always enter something here. Either a real equivalence,
+ then always enter something here. Either a real equivalence,
or a NULL_TREE equivalence which is effectively invalidation of
prior equivalences. */
if (cached_lhs
/* Second case. */
return -1;
}
-
+
/* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm
will be taken. */
if (gimple_code (stmt) == GIMPLE_COND
/* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or
- VRP.
+ VRP.
We don't want to thread back to a block we have already
visited. This may be overly conservative. */
const_and_copies->push_marker ();
if (avail_exprs_stack)
avail_exprs_stack->push_marker ();
-
+
/* Avoid threading to any block we have already visited. */
bitmap_clear (visited);
bitmap_set_bit (visited, e->src->index);