/* Support routines for Splitting Paths to loop backedges
- Copyright (C) 2015-2017 Free Software Foundation, Inc.
+ Copyright (C) 2015-2020 Free Software Foundation, Inc.
Contributed by Ajit Kumar Agarwal <ajitkum@xilinx.com>.
This file is part of GCC.
#include "gimple-iterator.h"
#include "tracer.h"
#include "predict.h"
-#include "params.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
}
}
+ /* Canonicalize the form. */
+ if (num_stmts_in_pred1 == 0 && num_stmts_in_pred2 == 1)
+ {
+ std::swap (pred1, pred2);
+ std::swap (num_stmts_in_pred1, num_stmts_in_pred2);
+ }
+
+ /* Another variant. This one is half-diamond. */
+ if (num_stmts_in_pred1 == 1 && num_stmts_in_pred2 == 0
+ && dominated_by_p (CDI_DOMINATORS, pred1, pred2))
+ {
+ gimple *stmt1 = last_and_only_stmt (pred1);
+
+ /* The only statement in PRED1 must be an assignment that is
+ not a good candidate for if-conversion. This may need some
+ generalization. */
+ if (stmt1 && gimple_code (stmt1) == GIMPLE_ASSIGN)
+ {
+ enum tree_code code1 = gimple_assign_rhs_code (stmt1);
+
+ if (!poor_ifcvt_candidate_code (code1))
+ {
+ tree lhs1 = gimple_assign_lhs (stmt1);
+ tree rhs1 = gimple_assign_rhs1 (stmt1);
+
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *phi = gsi_stmt (gsi);
+ if ((gimple_phi_arg_def (phi, 0) == lhs1
+ && gimple_phi_arg_def (phi, 1) == rhs1)
+ || (gimple_phi_arg_def (phi, 1) == lhs1
+ && gimple_phi_arg_def (phi, 0) == rhs1))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Block %d appears to be a join point for "
+ "if-convertable half-diamond.\n",
+ bb->index);
+ return false;
+ }
+ }
+ }
+ }
+ }
+
/* If the joiner has no PHIs with useful uses there is zero chance
of CSE/DCE/jump-threading possibilities exposed by duplicating it. */
bool found_useful_phi = false;
if (is_gimple_debug (stmt))
continue;
/* If there's a use in the joiner this might be a CSE/DCE
- opportunity. */
- if (gimple_bb (stmt) == bb)
+ opportunity, but not if the use is in a conditional
+ which makes this a likely if-conversion candidate. */
+ if (gimple_bb (stmt) == bb
+ && (!is_gimple_assign (stmt)
+ || (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+ != tcc_comparison)))
{
found_useful_phi = true;
break;
imm_use_iterator iter2;
FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result (stmt))
{
- if (is_gimple_debug (USE_STMT (use2_p)))
+ gimple *use_stmt = USE_STMT (use2_p);
+ if (is_gimple_debug (use_stmt))
continue;
- basic_block use_bb = gimple_bb (USE_STMT (use2_p));
+ basic_block use_bb = gimple_bb (use_stmt);
if (use_bb != bb
&& dominated_by_p (CDI_DOMINATORS, bb, use_bb))
{
- found_useful_phi = true;
+ if (gcond *cond = dyn_cast <gcond *> (use_stmt))
+ if (gimple_cond_code (cond) == EQ_EXPR
+ || gimple_cond_code (cond) == NE_EXPR)
+ found_useful_phi = true;
break;
}
}
/* Upper Hard limit on the number statements to copy. */
if (num_stmts_in_join
- >= PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS))
+ >= param_max_jump_thread_duplication_stmts)
return false;
return true;