<L18>:;
*/
+#define INCLUDE_ALGORITHM
#include "config.h"
#include "system.h"
#include "coretypes.h"
recorded here, in order to avoid the duplication of computations
that occur in previous conditions. See PR44483. */
gimple_seq predicate_gimplified_stmts;
+
+ /* Records the number of statements recorded into
+ PREDICATE_GIMPLIFIED_STMTS. */
+ unsigned no_predicate_stmts;
};
/* Returns true when the basic block BB has a predicate. */
static inline void
set_bb_predicate (basic_block bb, tree cond)
{
+ auto aux = (struct bb_predicate *) bb->aux;
gcc_assert ((TREE_CODE (cond) == TRUTH_NOT_EXPR
&& is_gimple_val (TREE_OPERAND (cond, 0)))
|| is_gimple_val (cond));
- ((struct bb_predicate *) bb->aux)->predicate = cond;
+ aux->predicate = cond;
+ aux->no_predicate_stmts++;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Recording block %d value %d\n", bb->index,
+ aux->no_predicate_stmts);
}
/* Returns the sequence of statements of the gimplification of the
}
/* Sets the sequence of statements STMTS of the gimplification of the
- predicate for basic block BB. */
+ predicate for basic block BB. If PRESERVE_COUNTS then don't clear the predicate
+ counts. */
static inline void
-set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
+set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts,
+ bool preserve_counts)
{
((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts = stmts;
+ if (stmts == NULL && !preserve_counts)
+ ((struct bb_predicate *) bb->aux)->no_predicate_stmts = 0;
}
/* Adds the sequence of statements STMTS to the sequence of statements
gimple *stmt = gsi_stmt (gsi);
delink_stmt_imm_use (stmt);
gimple_set_modified (stmt, true);
+ ((struct bb_predicate *) bb->aux)->no_predicate_stmts++;
}
gimple_seq_add_seq_without_update
(&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
}
+/* Return the number of statements the predicate of the basic block consists
+ of. */
+
+static inline unsigned
+get_bb_num_predicate_stmts (basic_block bb)
+{
+ return ((struct bb_predicate *) bb->aux)->no_predicate_stmts;
+}
+
/* Initializes to TRUE the predicate of basic block BB. */
static inline void
init_bb_predicate (basic_block bb)
{
bb->aux = XNEW (struct bb_predicate);
- set_bb_predicate_gimplified_stmts (bb, NULL);
+ set_bb_predicate_gimplified_stmts (bb, NULL, false);
set_bb_predicate (bb, boolean_true_node);
}
/* Discard them. */
gimple_seq_discard (stmts);
- set_bb_predicate_gimplified_stmts (bb, NULL);
+ set_bb_predicate_gimplified_stmts (bb, NULL, false);
}
}
tree rhs, res, arg0, arg1, op0, op1, scev;
tree cond;
unsigned int index0;
- unsigned int max, args_len;
edge e;
basic_block bb;
unsigned int i;
bool swap = false;
hash_map<tree_operand_hash, auto_vec<int> > phi_arg_map;
unsigned int num_args = gimple_phi_num_args (phi);
- int max_ind = -1;
/* Vector of different PHI argument values. */
auto_vec<tree> args (num_args);
phi_arg_map.get_or_insert (arg).safe_push (i);
}
- /* Determine element with max number of occurrences. */
- max_ind = -1;
- max = 1;
- args_len = args.length ();
- for (i = 0; i < args_len; i++)
+ /* Determine element with max number of occurrences and complexity. Looking at only
+ number of occurrences as a measure for complexity isn't enough as all usages can
+ be unique but the comparisons to reach the PHI node differ per branch. */
+ typedef std::pair <tree, std::pair <unsigned, unsigned>> ArgEntry;
+ auto_vec<ArgEntry> argsKV;
+ for (i = 0; i < args.length (); i++)
{
- unsigned int len;
- if ((len = phi_arg_map.get (args[i])->length ()) > max)
+ unsigned int len = 0;
+ for (int index : phi_arg_map.get (args[i]))
{
- max_ind = (int) i;
- max = len;
+ edge e = gimple_phi_arg_edge (phi, index);
+ len += get_bb_num_predicate_stmts (e->src);
}
+
+ unsigned occur = phi_arg_map.get (args[i])->length ();
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Ranking %d as len=%d, idx=%d\n", i, len, occur);
+ argsKV.safe_push ({ args[i], { len, occur }});
}
- /* Put element with max number of occurences to the end of ARGS. */
- if (max_ind != -1 && max_ind + 1 != (int) args_len)
- std::swap (args[args_len - 1], args[max_ind]);
+ /* Sort elements based on rankings ARGS. */
+ std::sort(argsKV.begin(), argsKV.end(), [](ArgEntry &left, ArgEntry &right) {
+ return left.second < right.second;
+ });
+
+ for (i = 0; i < args.length (); i++)
+ args[i] = argsKV[i].first;
/* Handle one special case when number of arguments with different values
is equal 2 and one argument has the only occurrence. Such PHI can be
handled as if would have only 2 arguments. */
- if (args_len == 2 && phi_arg_map.get (args[0])->length () == 1)
+ if (args.length () == 2 && phi_arg_map.get (args[0])->length () == 1)
{
vec<int> *indexes;
indexes = phi_arg_map.get (args[0]);
}
/* Once the sequence is code generated, set it to NULL. */
- set_bb_predicate_gimplified_stmts (bb, NULL);
+ set_bb_predicate_gimplified_stmts (bb, NULL, true);
}
}
}