static void tree_ssa_phiopt (void);
static bool conditional_replacement (basic_block bb, tree phi, tree arg0,
- tree arg1);
-
+ tree arg1);
+
/* This pass eliminates PHI nodes which can be trivially implemented as
an assignment from a conditional expression. ie if we have something
like:
bb2:
x = PHI (0 (bb1), 1 (bb0)
- We can rewrite that as:
+ We can rewrite that as:
- bb0:
- bb1:
- bb2:
+ bb0:
+ bb1:
+ bb2:
x = cond;
- bb1 will become unreachable and bb0 and bb2 will almost always
- be merged into a single block. This occurs often due to gimplification
- of conditionals. */
+ bb1 will become unreachable and bb0 and bb2 will almost always
+ be merged into a single block. This occurs often due to gimplification
+ of conditionals. */
static void
tree_ssa_phiopt (void)
phi = phi_nodes (bb);
if (phi && TREE_CHAIN (phi) == NULL
&& PHI_NUM_ARGS (phi) == 2)
- {
-
- arg0 = PHI_ARG_DEF (phi, 0);
- arg1 = PHI_ARG_DEF (phi, 1);
-
- /* Do the replacement of conditional if it can be done. */
- if (conditional_replacement (bb, phi, arg0, arg1))
- {
- /* We have done the replacement so we need to rebuild the cfg. */
- removed_phis = true;
- continue;
- }
- }
+ {
+ arg0 = PHI_ARG_DEF (phi, 0);
+ arg1 = PHI_ARG_DEF (phi, 1);
+
+ /* Do the replacement of conditional if it can be done. */
+ if (conditional_replacement (bb, phi, arg0, arg1))
+ {
+ /* We have done the replacement so we need to rebuild the cfg. */
+ removed_phis = true;
+ continue;
+ }
+ }
}
/* If we removed any PHIs, then we have unreachable blocks and blocks
cleanup_tree_cfg ();
}
-/* The function conditional_replacement does the main work of doing the conditional
- replacement. Return true if the replacement is done. Otherwise return false.
- bb is the basic block where the replacement is going to be done on. arg0
- is argument 0 from the phi. Likewise for arg1. */
+/* The function conditional_replacement does the main work of doing the
+ conditional replacement. Return true if the replacement is done.
+ Otherwise return false.
+ BB is the basic block where the replacement is going to be done on. ARG0
+ is argument 0 from PHI. Likewise for ARG1. */
static bool
conditional_replacement (basic_block bb, tree phi, tree arg0, tree arg1)
tree new_var = NULL;
/* The PHI arguments have the constants 0 and 1, then convert
- it to the conditional. */
+ it to the conditional. */
if ((integer_zerop (arg0) && integer_onep (arg1))
|| (integer_zerop (arg1) && integer_onep (arg0)))
;
return false;
/* One of the alternatives must come from a block ending with
- a COND_EXPR. The other block must be entirely empty, except
- for labels. */
+ a COND_EXPR. The other block must be entirely empty, except
+ for labels. */
last0 = last_stmt (bb->pred->src);
last1 = last_stmt (bb->pred->pred_next->src);
if (last0 && TREE_CODE (last0) == COND_EXPR)
return false;
/* COND_BLOCK must have precisely two successors. We indirectly
- verify that those successors are BB and OTHER_BLOCK. */
+ verify that those successors are BB and OTHER_BLOCK. */
if (!cond_block->succ
|| !cond_block->succ->succ_next
|| cond_block->succ->succ_next->succ_next
return false;
/* OTHER_BLOCK must have a single predecessor which is COND_BLOCK,
- OTHER_BLOCK must have a single successor which is BB and
- OTHER_BLOCK must have no PHI nodes. */
+ OTHER_BLOCK must have a single successor which is BB and
+ OTHER_BLOCK must have no PHI nodes. */
if (!other_block->pred
|| other_block->pred->src != cond_block
|| other_block->pred->pred_next
/* OTHER_BLOCK must have no executable statements. */
bsi = bsi_start (other_block);
while (!bsi_end_p (bsi)
- && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
- || IS_EMPTY_STMT (bsi_stmt (bsi))))
+ && (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR
+ || IS_EMPTY_STMT (bsi_stmt (bsi))))
bsi_next (&bsi);
if (!bsi_end_p (bsi))
return false;
/* If the condition is not a naked SSA_NAME and its type does not
- match the type of the result, then we have to create a new
- variable to optimize this case as it would likely create
- non-gimple code when the condition was converted to the
- result's type. */
-
+ match the type of the result, then we have to create a new
+ variable to optimize this case as it would likely create
+ non-gimple code when the condition was converted to the
+ result's type. */
cond = COND_EXPR_COND (last_stmt (cond_block));
result = PHI_RESULT (phi);
if (TREE_CODE (cond) != SSA_NAME
}
/* If the condition was a naked SSA_NAME and the type is not the
- same as the type of the result, then convert the type of the
- condition. */
+ same as the type of the result, then convert the type of the
+ condition. */
if (!lang_hooks.types_compatible_p (TREE_TYPE (cond), TREE_TYPE (result)))
cond = fold_convert (TREE_TYPE (result), cond);
/* We need to know which is the true edge and which is the false
- edge so that we know when to invert the condition below. */
+ edge so that we know when to invert the condition below. */
extract_true_false_edges_from_block (cond_block, &true_edge, &false_edge);
/* Insert our new statement at the head of our block. */
{
tree new1;
if (TREE_CODE_CLASS (TREE_CODE (old_result)) != '<')
- return false;
+ return false;
new1 = build (TREE_CODE (old_result), TREE_TYPE (result),
- TREE_OPERAND (old_result, 0),
- TREE_OPERAND (old_result, 1));
+ TREE_OPERAND (old_result, 0),
+ TREE_OPERAND (old_result, 1));
new1 = build (MODIFY_EXPR, TREE_TYPE (result),
- new_var, new1);
+ new_var, new1);
bsi_insert_after (&bsi, new1, BSI_NEW_STMT);
}
-
/* At this point we know we have a COND_EXPR with two successors.
- One successor is BB, the other successor is an empty block which
- falls through into BB.
-
- There is a single PHI node at the join point (BB) and its arguments
- are constants (0, 1).
+ One successor is BB, the other successor is an empty block which
+ falls through into BB.
- So, given the condition COND, and the two PHI arguments, we can
- rewrite this PHI into non-branching code:
+ There is a single PHI node at the join point (BB) and its arguments
+ are constants (0, 1).
- dest = (COND) or dest = COND'
+ So, given the condition COND, and the two PHI arguments, we can
+ rewrite this PHI into non-branching code:
- We use the condition as-is if the argument associated with the
- true edge has the value one or the argument associated with the
- false edge as the value zero. Note that those conditions are not
- the same since only one of the outgoing edges from the COND_EXPR
- will directly reach BB and thus be associated with an argument. */
+ dest = (COND) or dest = COND'
+ We use the condition as-is if the argument associated with the
+ true edge has the value one or the argument associated with the
+ false edge as the value zero. Note that those conditions are not
+ the same since only one of the outgoing edges from the COND_EXPR
+ will directly reach BB and thus be associated with an argument. */
if ((PHI_ARG_EDGE (phi, 0) == true_edge && integer_onep (arg0))
|| (PHI_ARG_EDGE (phi, 0) == false_edge && integer_zerop (arg0))
|| (PHI_ARG_EDGE (phi, 1) == true_edge && integer_onep (arg1))
|| (PHI_ARG_EDGE (phi, 1) == false_edge && integer_zerop (arg1)))
{
new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
- PHI_RESULT (phi), cond);
+ PHI_RESULT (phi), cond);
}
else
{
return false;
/* If what we get back is not gimple try to create it as gimple by
- using a temporary variable. */
+ using a temporary variable. */
if (is_gimple_cast (cond)
&& !is_gimple_val (TREE_OPERAND (cond, 0)))
- {
- tree temp = TREE_OPERAND (cond, 0);
- tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
- new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
- bsi_insert_after (&bsi, new, BSI_NEW_STMT);
- cond = fold_convert (TREE_TYPE (result), new_var_1);
- }
+ {
+ tree temp = TREE_OPERAND (cond, 0);
+ tree new_var_1 = make_rename_temp (TREE_TYPE (temp), NULL);
+ new = build (MODIFY_EXPR, TREE_TYPE (new_var_1), new_var_1, temp);
+ bsi_insert_after (&bsi, new, BSI_NEW_STMT);
+ cond = fold_convert (TREE_TYPE (result), new_var_1);
+ }
if (TREE_CODE (cond) == TRUTH_NOT_EXPR
- && !is_gimple_val (TREE_OPERAND (cond, 0)))
- return false;
+ && !is_gimple_val (TREE_OPERAND (cond, 0)))
+ return false;
new = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
- PHI_RESULT (phi), cond);
+ PHI_RESULT (phi), cond);
}
bsi_insert_after (&bsi, new, BSI_NEW_STMT);
/* Register our new statement as the defining statement for
- the result. */
+ the result. */
SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new;
/* Remove the now useless PHI node.
- We do not want to use remove_phi_node since that releases the
- SSA_NAME as well and the SSA_NAME is still being used. */
+ We do not want to use remove_phi_node since that releases the
+ SSA_NAME as well and the SSA_NAME is still being used. */
release_phi_node (phi);
bb_ann (bb)->phi_nodes = NULL;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
- "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
- cond_block->index,
- bb->index);
-
+ "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
+ cond_block->index,
+ bb->index);
+
/* Note that we optimized this PHI. */
return true;
}