コード例 #1
0
static bool
tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
{
  basic_block then_bb = NULL, else_bb = NULL;

  if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
    return false;

  /* Recognize && and || of two conditions with a common
     then/else block which entry edges we can merge.  That is:
       if (a || b)
	 ;
     and
       if (a && b)
	 ;
     This requires a single predecessor of the inner cond_bb.  */
  if (single_pred_p (inner_cond_bb)
      && bb_no_side_effects_p (inner_cond_bb))
    {
      basic_block outer_cond_bb = single_pred (inner_cond_bb);

      if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb,
				   then_bb, else_bb, inner_cond_bb))
	return true;

      if (forwarder_block_to (else_bb, then_bb))
	{
	  /* Other possibilities for the && form, if else_bb is
	     empty forwarder block to then_bb.  Compared to the above simpler
	     forms this can be treated as if then_bb and else_bb were swapped,
	     and the corresponding inner_cond_bb not inverted because of that.
	     For same_phi_args_p we look at equality of arguments between
	     edge from outer_cond_bb and the forwarder block.  */
	  if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb,
				       then_bb, else_bb))
	    return true;
	}
      else if (forwarder_block_to (then_bb, else_bb))
	{
	  /* Other possibilities for the || form, if then_bb is
	     empty forwarder block to else_bb.  Compared to the above simpler
	     forms this can be treated as if then_bb and else_bb were swapped,
	     and the corresponding inner_cond_bb not inverted because of that.
	     For same_phi_args_p we look at equality of arguments between
	     edge from outer_cond_bb and the forwarder block.  */
	  if (tree_ssa_ifcombine_bb_1 (inner_cond_bb, outer_cond_bb, else_bb,
				       then_bb, then_bb))
	    return true;
	}
    }

  return false;
}
コード例 #2
0
static bool
tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
{
  basic_block then_bb = NULL, else_bb = NULL;

  if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
    return false;

  /* Recognize && and || of two conditions with a common
     then/else block which entry edges we can merge.  That is:
       if (a || b)
	 ;
     and
       if (a && b)
	 ;
     This requires a single predecessor of the inner cond_bb.  */
  if (single_pred_p (inner_cond_bb))
    {
      basic_block outer_cond_bb = single_pred (inner_cond_bb);

      /* The && form is characterized by a common else_bb with
	 the two edges leading to it mergable.  The latter is
	 guaranteed by matching PHI arguments in the else_bb and
	 the inner cond_bb having no side-effects.  */
      if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
	  && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
	  && bb_no_side_effects_p (inner_cond_bb))
	{
	  /* We have
	       <outer_cond_bb>
		 if (q) goto inner_cond_bb; else goto else_bb;
	       <inner_cond_bb>
		 if (p) goto ...; else goto else_bb;
		 ...
	       <else_bb>
		 ...
	   */
	  return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
	}

      /* The || form is characterized by a common then_bb with the
	 two edges leading to it mergable.  The latter is guaranteed
         by matching PHI arguments in the then_bb and the inner cond_bb
	 having no side-effects.  */
      if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
	  && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
	  && bb_no_side_effects_p (inner_cond_bb))
	{
	  /* We have
	       <outer_cond_bb>
		 if (q) goto then_bb; else goto inner_cond_bb;
	       <inner_cond_bb>
		 if (q) goto then_bb; else goto ...;
	       <then_bb>
		 ...
	   */
	  return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
	}
    }

  return false;
}
コード例 #3
0
ファイル: tree-ssa-ifcombine.c プロジェクト: Gurgel100/gcc
static bool
tree_ssa_ifcombine_bb_1 (basic_block inner_cond_bb, basic_block outer_cond_bb,
			 basic_block then_bb, basic_block else_bb,
			 basic_block phi_pred_bb)
{
  /* The && form is characterized by a common else_bb with
     the two edges leading to it mergable.  The latter is
     guaranteed by matching PHI arguments in the else_bb and
     the inner cond_bb having no side-effects.  */
  if (phi_pred_bb != else_bb
      && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
      && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb)
      && bb_no_side_effects_p (inner_cond_bb))
    {
      /* We have
	   <outer_cond_bb>
	     if (q) goto inner_cond_bb; else goto else_bb;
	   <inner_cond_bb>
	     if (p) goto ...; else goto else_bb;
	     ...
	   <else_bb>
	     ...
       */
      return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, false,
				false);
    }

  /* And a version where the outer condition is negated.  */
  if (phi_pred_bb != else_bb
      && recognize_if_then_else (outer_cond_bb, &else_bb, &inner_cond_bb)
      && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb)
      && bb_no_side_effects_p (inner_cond_bb))
    {
      /* We have
	   <outer_cond_bb>
	     if (q) goto else_bb; else goto inner_cond_bb;
	   <inner_cond_bb>
	     if (p) goto ...; else goto else_bb;
	     ...
	   <else_bb>
	     ...
       */
      return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, true,
				false);
    }

  /* The || form is characterized by a common then_bb with the
     two edges leading to it mergable.  The latter is guaranteed
     by matching PHI arguments in the then_bb and the inner cond_bb
     having no side-effects.  */
  if (phi_pred_bb != then_bb
      && recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
      && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb)
      && bb_no_side_effects_p (inner_cond_bb))
    {
      /* We have
	   <outer_cond_bb>
	     if (q) goto then_bb; else goto inner_cond_bb;
	   <inner_cond_bb>
	     if (q) goto then_bb; else goto ...;
	   <then_bb>
	     ...
       */
      return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, true,
				true);
    }

  /* And a version where the outer condition is negated.  */
  if (phi_pred_bb != then_bb
      && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &then_bb)
      && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb)
      && bb_no_side_effects_p (inner_cond_bb))
    {
      /* We have
	   <outer_cond_bb>
	     if (q) goto inner_cond_bb; else goto then_bb;
	   <inner_cond_bb>
	     if (q) goto then_bb; else goto ...;
	   <then_bb>
	     ...
       */
      return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, false,
				true);
    }

  return false;
}