View | Details | Return to bug 54146 | Differences between
and this patch

Collapse All | Expand All

(-)ifcvt.c (-63 / +60 lines)
Lines 43-48 Link Here
43
#include "tree-pass.h"
43
#include "tree-pass.h"
44
#include "df.h"
44
#include "df.h"
45
#include "vec.h"
45
#include "vec.h"
46
#include "pointer-set.h"
46
#include "vecprim.h"
47
#include "vecprim.h"
47
#include "dbgcnt.h"
48
#include "dbgcnt.h"
48
49
Lines 2687-2698 noce_process_if_block (struct noce_if_in Link Here
2687
2688
2688
/* Check whether a block is suitable for conditional move conversion.
2689
/* Check whether a block is suitable for conditional move conversion.
2689
   Every insn must be a simple set of a register to a constant or a
2690
   Every insn must be a simple set of a register to a constant or a
2690
   register.  For each assignment, store the value in the array VALS,
2691
   register.  For each assignment, store the value in the pointer map
2691
   indexed by register number, then store the register number in
2692
   VALS, keyed indexed by register pointer, then store the register
2692
   REGS.  COND is the condition we will test.  */
2693
   pointer in REGS.  COND is the condition we will test.  */
2693
2694
2694
static int
2695
static int
2695
check_cond_move_block (basic_block bb, rtx *vals, VEC (int, heap) **regs,
2696
check_cond_move_block (basic_block bb,
2697
		       struct pointer_map_t *vals,
2698
		       VEC (rtx, heap) **regs,
2696
		       rtx cond)
2699
		       rtx cond)
2697
{
2700
{
2698
  rtx insn;
2701
  rtx insn;
Lines 2706-2711 check_cond_move_block (basic_block bb, r Link Here
2706
  FOR_BB_INSNS (bb, insn)
2709
  FOR_BB_INSNS (bb, insn)
2707
    {
2710
    {
2708
      rtx set, dest, src;
2711
      rtx set, dest, src;
2712
      void **slot;
2709
2713
2710
      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
2714
      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
2711
	continue;
2715
	continue;
Lines 2732-2745 check_cond_move_block (basic_block bb, r Link Here
2732
      /* Don't try to handle this if the source register was
2736
      /* Don't try to handle this if the source register was
2733
	 modified earlier in the block.  */
2737
	 modified earlier in the block.  */
2734
      if ((REG_P (src)
2738
      if ((REG_P (src)
2735
	   && vals[REGNO (src)] != NULL)
2739
	   && pointer_map_contains (vals, src))
2736
	  || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
2740
	  || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
2737
	      && vals[REGNO (SUBREG_REG (src))] != NULL))
2741
	      && pointer_map_contains (vals, SUBREG_REG (src))))
2738
	return FALSE;
2742
	return FALSE;
2739
2743
2740
      /* Don't try to handle this if the destination register was
2744
      /* Don't try to handle this if the destination register was
2741
	 modified earlier in the block.  */
2745
	 modified earlier in the block.  */
2742
      if (vals[REGNO (dest)] != NULL)
2746
      if (pointer_map_contains (vals, dest))
2743
	return FALSE;
2747
	return FALSE;
2744
2748
2745
      /* Don't try to handle this if the condition uses the
2749
      /* Don't try to handle this if the condition uses the
Lines 2753-2769 check_cond_move_block (basic_block bb, r Link Here
2753
	  && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
2757
	  && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
2754
	return FALSE;
2758
	return FALSE;
2755
2759
2756
      vals[REGNO (dest)] = src;
2760
      slot = pointer_map_insert (vals, (void *) dest);
2761
      *slot = (void *) src;
2757
2762
2758
      VEC_safe_push (int, heap, *regs, REGNO (dest));
2763
      VEC_safe_push (rtx, heap, *regs, dest);
2759
    }
2764
    }
2760
2765
2761
  return TRUE;
2766
  return TRUE;
2762
}
2767
}
2763
2768
2764
/* Given a basic block BB suitable for conditional move conversion,
2769
/* Given a basic block BB suitable for conditional move conversion,
2765
   a condition COND, and arrays THEN_VALS and ELSE_VALS containing the
2770
   a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
2766
   register values depending on COND, emit the insns in the block as
2771
   the register values depending on COND, emit the insns in the block as
2767
   conditional moves.  If ELSE_BLOCK is true, THEN_BB was already
2772
   conditional moves.  If ELSE_BLOCK is true, THEN_BB was already
2768
   processed.  The caller has started a sequence for the conversion.
2773
   processed.  The caller has started a sequence for the conversion.
2769
   Return true if successful, false if something goes wrong.  */
2774
   Return true if successful, false if something goes wrong.  */
Lines 2771-2777 check_cond_move_block (basic_block bb, r Link Here
2771
static bool
2776
static bool
2772
cond_move_convert_if_block (struct noce_if_info *if_infop,
2777
cond_move_convert_if_block (struct noce_if_info *if_infop,
2773
			    basic_block bb, rtx cond,
2778
			    basic_block bb, rtx cond,
2774
			    rtx *then_vals, rtx *else_vals,
2779
			    struct pointer_map_t *then_vals,
2780
			    struct pointer_map_t *else_vals,
2775
			    bool else_block_p)
2781
			    bool else_block_p)
2776
{
2782
{
2777
  enum rtx_code code;
2783
  enum rtx_code code;
Lines 2784-2790 cond_move_convert_if_block (struct noce_ Link Here
2784
  FOR_BB_INSNS (bb, insn)
2790
  FOR_BB_INSNS (bb, insn)
2785
    {
2791
    {
2786
      rtx set, target, dest, t, e;
2792
      rtx set, target, dest, t, e;
2787
      unsigned int regno;
2793
      void **then_slot, **else_slot;
2788
2794
2789
      /* ??? Maybe emit conditional debug insn?  */
2795
      /* ??? Maybe emit conditional debug insn?  */
2790
      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
2796
      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
Lines 2793-2802 cond_move_convert_if_block (struct noce_ Link Here
2793
      gcc_assert (set && REG_P (SET_DEST (set)));
2799
      gcc_assert (set && REG_P (SET_DEST (set)));
2794
2800
2795
      dest = SET_DEST (set);
2801
      dest = SET_DEST (set);
2796
      regno = REGNO (dest);
2797
2802
2798
      t = then_vals[regno];
2803
      then_slot = pointer_map_contains (then_vals, dest);
2799
      e = else_vals[regno];
2804
      else_slot = pointer_map_contains (else_vals, dest);
2805
      t = then_slot ? (rtx) *then_slot : NULL_RTX;
2806
      e = else_slot ? (rtx) *else_slot : NULL_RTX;
2800
2807
2801
      if (else_block_p)
2808
      if (else_block_p)
2802
	{
2809
	{
Lines 2840-2870 cond_move_process_if_block (struct noce_ Link Here
2840
  rtx jump = if_info->jump;
2847
  rtx jump = if_info->jump;
2841
  rtx cond = if_info->cond;
2848
  rtx cond = if_info->cond;
2842
  rtx seq, loc_insn;
2849
  rtx seq, loc_insn;
2843
  int max_reg, size, c, reg;
2850
  rtx reg;
2844
  rtx *then_vals;
2851
  int c;
2845
  rtx *else_vals;
2852
  struct pointer_map_t *then_vals;
2846
  VEC (int, heap) *then_regs = NULL;
2853
  struct pointer_map_t *else_vals;
2847
  VEC (int, heap) *else_regs = NULL;
2854
  VEC (rtx, heap) *then_regs = NULL;
2855
  VEC (rtx, heap) *else_regs = NULL;
2848
  unsigned int i;
2856
  unsigned int i;
2857
  int success_p = FALSE;
2849
2858
2850
  /* Build a mapping for each block to the value used for each
2859
  /* Build a mapping for each block to the value used for each
2851
     register.  */
2860
     register.  */
2852
  max_reg = max_reg_num ();
2861
  then_vals = pointer_map_create ();
2853
  size = (max_reg + 1) * sizeof (rtx);
2862
  else_vals = pointer_map_create ();
2854
  then_vals = (rtx *) alloca (size);
2855
  else_vals = (rtx *) alloca (size);
2856
  memset (then_vals, 0, size);
2857
  memset (else_vals, 0, size);
2858
2863
2859
  /* Make sure the blocks are suitable.  */
2864
  /* Make sure the blocks are suitable.  */
2860
  if (!check_cond_move_block (then_bb, then_vals, &then_regs, cond)
2865
  if (!check_cond_move_block (then_bb, then_vals, &then_regs, cond)
2861
      || (else_bb
2866
      || (else_bb
2862
	  && !check_cond_move_block (else_bb, else_vals, &else_regs, cond)))
2867
	  && !check_cond_move_block (else_bb, else_vals, &else_regs, cond)))
2863
    {
2868
    goto done;
2864
      VEC_free (int, heap, then_regs);
2865
      VEC_free (int, heap, else_regs);
2866
      return FALSE;
2867
    }
2868
2869
2869
  /* Make sure the blocks can be used together.  If the same register
2870
  /* Make sure the blocks can be used together.  If the same register
2870
     is set in both blocks, and is not set to a constant in both
2871
     is set in both blocks, and is not set to a constant in both
Lines 2873-2913 cond_move_process_if_block (struct noce_ Link Here
2873
     source register does not change after the assignment.  Also count
2874
     source register does not change after the assignment.  Also count
2874
     the number of registers set in only one of the blocks.  */
2875
     the number of registers set in only one of the blocks.  */
2875
  c = 0;
2876
  c = 0;
2876
  FOR_EACH_VEC_ELT (int, then_regs, i, reg)
2877
  FOR_EACH_VEC_ELT (rtx, then_regs, i, reg)
2877
    {
2878
    {
2878
      if (!then_vals[reg] && !else_vals[reg])
2879
      void **then_slot = pointer_map_contains (then_vals, reg);
2879
	continue;
2880
      void **else_slot = pointer_map_contains (else_vals, reg);
2880
2881
2881
      if (!else_vals[reg])
2882
      gcc_checking_assert (then_slot);
2883
      if (!else_slot)
2882
	++c;
2884
	++c;
2883
      else
2885
      else
2884
	{
2886
	{
2885
	  if (!CONSTANT_P (then_vals[reg])
2887
	  rtx then_val = (rtx) *then_slot;
2886
	      && !CONSTANT_P (else_vals[reg])
2888
	  rtx else_val = (rtx) *else_slot;
2887
	      && !rtx_equal_p (then_vals[reg], else_vals[reg]))
2889
	  if (!CONSTANT_P (then_val) && !CONSTANT_P (else_val)
2888
	    {
2890
	      && !rtx_equal_p (then_val, else_val))
2889
	      VEC_free (int, heap, then_regs);
2891
	    goto done;
2890
	      VEC_free (int, heap, else_regs);
2891
	      return FALSE;
2892
	    }
2893
	}
2892
	}
2894
    }
2893
    }
2895
2894
2896
  /* Finish off c for MAX_CONDITIONAL_EXECUTE.  */
2895
  /* Finish off c for MAX_CONDITIONAL_EXECUTE.  */
2897
  FOR_EACH_VEC_ELT (int, else_regs, i, reg)
2896
  FOR_EACH_VEC_ELT (rtx, else_regs, i, reg)
2898
    if (!then_vals[reg])
2897
    {
2899
      ++c;
2898
      gcc_checking_assert (pointer_map_contains (else_vals, reg));
2899
      if (!pointer_map_contains (then_vals, reg))
2900
	++c;
2901
    }
2900
2902
2901
  /* Make sure it is reasonable to convert this block.  What matters
2903
  /* Make sure it is reasonable to convert this block.  What matters
2902
     is the number of assignments currently made in only one of the
2904
     is the number of assignments currently made in only one of the
2903
     branches, since if we convert we are going to always execute
2905
     branches, since if we convert we are going to always execute
2904
     them.  */
2906
     them.  */
2905
  if (c > MAX_CONDITIONAL_EXECUTE)
2907
  if (c > MAX_CONDITIONAL_EXECUTE)
2906
    {
2908
    goto done;
2907
      VEC_free (int, heap, then_regs);
2908
      VEC_free (int, heap, else_regs);
2909
      return FALSE;
2910
    }
2911
2909
2912
  /* Try to emit the conditional moves.  First do the then block,
2910
  /* Try to emit the conditional moves.  First do the then block,
2913
     then do anything left in the else blocks.  */
2911
     then do anything left in the else blocks.  */
Lines 2919-2935 cond_move_process_if_block (struct noce_ Link Here
2919
					  then_vals, else_vals, true)))
2917
					  then_vals, else_vals, true)))
2920
    {
2918
    {
2921
      end_sequence ();
2919
      end_sequence ();
2922
      VEC_free (int, heap, then_regs);
2920
      goto done;
2923
      VEC_free (int, heap, else_regs);
2924
      return FALSE;
2925
    }
2921
    }
2926
  seq = end_ifcvt_sequence (if_info);
2922
  seq = end_ifcvt_sequence (if_info);
2927
  if (!seq)
2923
  if (!seq)
2928
    {
2924
    goto done;
2929
      VEC_free (int, heap, then_regs);
2930
      VEC_free (int, heap, else_regs);
2931
      return FALSE;
2932
    }
2933
2925
2934
  loc_insn = first_active_insn (then_bb);
2926
  loc_insn = first_active_insn (then_bb);
2935
  if (!loc_insn)
2927
  if (!loc_insn)
Lines 2960-2968 cond_move_process_if_block (struct noce_ Link Here
2960
2952
2961
  num_updated_if_blocks++;
2953
  num_updated_if_blocks++;
2962
2954
2963
  VEC_free (int, heap, then_regs);
2955
  success_p = TRUE;
2964
  VEC_free (int, heap, else_regs);
2956
2965
  return TRUE;
2957
done:
2958
  pointer_map_destroy (then_vals);
2959
  pointer_map_destroy (else_vals);
2960
  VEC_free (rtx, heap, then_regs);
2961
  VEC_free (rtx, heap, else_regs);
2962
  return success_p;
2966
}
2963
}
2967
2964
2968
2965
(-)gimplify.c (+2 lines)
Lines 8200-8207 gimplify_body (tree fndecl, bool do_parm Link Here
8200
  pop_gimplify_context (outer_bind);
8200
  pop_gimplify_context (outer_bind);
8201
  gcc_assert (gimplify_ctxp == NULL);
8201
  gcc_assert (gimplify_ctxp == NULL);
8202
8202
8203
#ifdef ENABLE_CHECKING
8203
  if (!seen_error ())
8204
  if (!seen_error ())
8204
    verify_gimple_in_seq (gimple_bind_body (outer_bind));
8205
    verify_gimple_in_seq (gimple_bind_body (outer_bind));
8206
#endif
8205
8207
8206
  timevar_pop (TV_TREE_GIMPLIFY);
8208
  timevar_pop (TV_TREE_GIMPLIFY);
8207
  input_location = saved_location;
8209
  input_location = saved_location;

Return to bug 54146