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

Collapse All | Expand All

(-)gcc/gimple-ssa-store-merging.c.jj (-34 / +94 lines)
Lines 1429-1434 struct merged_store_group Link Here
1429
  unsigned int first_order;
1429
  unsigned int first_order;
1430
  unsigned int last_order;
1430
  unsigned int last_order;
1431
  bool bit_insertion;
1431
  bool bit_insertion;
1432
  bool only_constants;
1433
  unsigned int first_nonmergeable_order;
1432
1434
1433
  auto_vec<store_immediate_info *> stores;
1435
  auto_vec<store_immediate_info *> stores;
1434
  /* We record the first and last original statements in the sequence because
1436
  /* We record the first and last original statements in the sequence because
Lines 1821-1826 merged_store_group::merged_store_group ( Link Here
1821
  val = NULL;
1823
  val = NULL;
1822
  mask = NULL;
1824
  mask = NULL;
1823
  bit_insertion = false;
1825
  bit_insertion = false;
1826
  only_constants = info->rhs_code == INTEGER_CST;
1827
  first_nonmergeable_order = ~0U;
1824
  unsigned HOST_WIDE_INT align_bitpos = 0;
1828
  unsigned HOST_WIDE_INT align_bitpos = 0;
1825
  get_object_alignment_1 (gimple_assign_lhs (info->stmt),
1829
  get_object_alignment_1 (gimple_assign_lhs (info->stmt),
1826
			  &align, &align_bitpos);
1830
			  &align, &align_bitpos);
Lines 1936-1941 merged_store_group::do_merge (store_imme Link Here
1936
      first_order = info->order;
1940
      first_order = info->order;
1937
      first_stmt = stmt;
1941
      first_stmt = stmt;
1938
    }
1942
    }
1943
  if (info->rhs_code != INTEGER_CST)
1944
    only_constants = false;
1939
}
1945
}
1940
1946
1941
/* Merge a store recorded by INFO into this merged store.
1947
/* Merge a store recorded by INFO into this merged store.
Lines 2696-2727 imm_store_chain_info::coalesce_immediate Link Here
2696
	    }
2702
	    }
2697
	}
2703
	}
2698
2704
2705
      if (info->order >= merged_store->first_nonmergeable_order)
2706
	;
2707
2699
      /* |---store 1---|
2708
      /* |---store 1---|
2700
	       |---store 2---|
2709
	       |---store 2---|
2701
	 Overlapping stores.  */
2710
	 Overlapping stores.  */
2702
      if (IN_RANGE (info->bitpos, merged_store->start,
2711
      else if (IN_RANGE (info->bitpos, merged_store->start,
2703
		    merged_store->start + merged_store->width - 1))
2712
			 merged_store->start + merged_store->width - 1))
2704
	{
2713
	{
2705
	  /* Only allow overlapping stores of constants.  */
2714
	  /* Only allow overlapping stores of constants.  */
2706
	  if (info->rhs_code == INTEGER_CST)
2715
	  if (info->rhs_code == INTEGER_CST && merged_store->only_constants)
2707
	    {
2716
	    {
2708
	      bool only_constants = true;
2709
	      store_immediate_info *infoj;
2710
	      unsigned int j;
2711
	      FOR_EACH_VEC_ELT (merged_store->stores, j, infoj)
2712
		if (infoj->rhs_code != INTEGER_CST)
2713
		  {
2714
		    only_constants = false;
2715
		    break;
2716
		  }
2717
	      unsigned int last_order
2717
	      unsigned int last_order
2718
		= MAX (merged_store->last_order, info->order);
2718
		= MAX (merged_store->last_order, info->order);
2719
	      unsigned HOST_WIDE_INT end
2719
	      unsigned HOST_WIDE_INT end
2720
		= MAX (merged_store->start + merged_store->width,
2720
		= MAX (merged_store->start + merged_store->width,
2721
		       info->bitpos + info->bitsize);
2721
		       info->bitpos + info->bitsize);
2722
	      if (only_constants
2722
	      if (check_no_overlap (m_store_info, i, INTEGER_CST,
2723
		  && check_no_overlap (m_store_info, i, INTEGER_CST,
2723
				    last_order, end))
2724
				       last_order, end))
2725
		{
2724
		{
2726
		  /* check_no_overlap call above made sure there are no
2725
		  /* check_no_overlap call above made sure there are no
2727
		     overlapping stores with non-INTEGER_CST rhs_code
2726
		     overlapping stores with non-INTEGER_CST rhs_code
Lines 2741-2776 imm_store_chain_info::coalesce_immediate Link Here
2741
		     store_by_bitpos order it comes after the last store that
2740
		     store_by_bitpos order it comes after the last store that
2742
		     we can't merge with them.  We can merge the first 3 stores
2741
		     we can't merge with them.  We can merge the first 3 stores
2743
		     and keep the last store as is though.  */
2742
		     and keep the last store as is though.  */
2744
		  unsigned int len = m_store_info.length (), k = i;
2743
		  unsigned int len = m_store_info.length ();
2745
		  for (unsigned int j = i + 1; j < len; ++j)
2744
		  unsigned int try_order = last_order;
2745
		  unsigned int first_nonmergeable_order;
2746
		  unsigned int k;
2747
		  bool last_iter = false;
2748
		  int attempts = 0;
2749
		  do
2746
		    {
2750
		    {
2747
		      store_immediate_info *info2 = m_store_info[j];
2751
		      unsigned int max_order = 0;
2748
		      if (info2->bitpos >= end)
2752
		      unsigned first_nonmergeable_int_order = ~0U;
2749
			break;
2753
		      unsigned HOST_WIDE_INT this_end = end;
2750
		      if (info2->order < last_order)
2754
		      k = i;
2755
		      first_nonmergeable_order = ~0U;
2756
		      for (unsigned int j = i + 1; j < len; ++j)
2751
			{
2757
			{
2752
			  if (info2->rhs_code != INTEGER_CST)
2758
			  store_immediate_info *info2 = m_store_info[j];
2759
			  if (info2->bitpos >= this_end)
2760
			    break;
2761
			  if (info2->order < try_order)
2762
			    {
2763
			      if (info2->rhs_code != INTEGER_CST)
2764
				{
2765
				  /* Normally check_no_overlap makes sure this
2766
				     doesn't happen, but if end grows below,
2767
				     then we need to process more stores than
2768
				     check_no_overlap verified.  Example:
2769
				      MEM[(int *)p_5] = 0;
2770
				      MEM[(short *)p_5 + 3B] = 1;
2771
				      MEM[(char *)p_5 + 4B] = _9;
2772
				      MEM[(char *)p_5 + 2B] = 2;  */
2773
				  k = 0;
2774
				  break;
2775
				}
2776
			      k = j;
2777
			      this_end = MAX (this_end,
2778
					      info2->bitpos + info2->bitsize);
2779
			    }
2780
			  else if (info2->rhs_code == INTEGER_CST
2781
				   && !last_iter)
2753
			    {
2782
			    {
2754
			      /* Normally check_no_overlap makes sure this
2783
			      max_order = MAX (max_order, info2->order + 1);
2755
				 doesn't happen, but if end grows below, then
2784
			      first_nonmergeable_int_order
2756
				 we need to process more stores than
2785
				= MIN (first_nonmergeable_int_order,
2757
				 check_no_overlap verified.  Example:
2786
				       info2->order);
2758
				    MEM[(int *)p_5] = 0;
2759
				    MEM[(short *)p_5 + 3B] = 1;
2760
				    MEM[(char *)p_5 + 4B] = _9;
2761
				    MEM[(char *)p_5 + 2B] = 2;  */
2762
			      k = 0;
2763
			      break;
2764
			    }
2787
			    }
2765
			  k = j;
2788
			  else
2766
			  end = MAX (end, info2->bitpos + info2->bitsize);
2789
			    first_nonmergeable_order
2790
			      = MIN (first_nonmergeable_order, info2->order);
2791
			}
2792
		      if (k == 0)
2793
			{
2794
			  if (last_order == try_order)
2795
			    break;
2796
			  /* If this failed, but only because we grew
2797
			     try_order, retry with the last working one,
2798
			     so that we merge at least something.  */
2799
			  try_order = last_order;
2800
			  last_iter = true;
2801
			  continue;
2802
			}
2803
		      last_order = try_order;
2804
		      /* Retry with a larger try_order to see if we could
2805
			 merge some further INTEGER_CST stores.  */
2806
		      if (max_order
2807
			  && (first_nonmergeable_int_order
2808
			      < first_nonmergeable_order))
2809
			{
2810
			  try_order = MIN (max_order,
2811
					   first_nonmergeable_order);
2812
			  try_order
2813
			    = MIN (try_order,
2814
				   merged_store->first_nonmergeable_order);
2815
			  if (try_order > last_order && ++attempts < 16)
2816
			    continue;
2767
			}
2817
			}
2818
		      first_nonmergeable_order
2819
			= MIN (first_nonmergeable_order,
2820
			       first_nonmergeable_int_order);
2821
		      end = this_end;
2822
		      break;
2768
		    }
2823
		    }
2824
		  while (1);
2769
2825
2770
		  if (k != 0)
2826
		  if (k != 0)
2771
		    {
2827
		    {
2772
		      merged_store->merge_overlapping (info);
2828
		      merged_store->merge_overlapping (info);
2773
2829
2830
		      merged_store->first_nonmergeable_order
2831
			= MIN (merged_store->first_nonmergeable_order,
2832
			       first_nonmergeable_order);
2833
2774
		      for (unsigned int j = i + 1; j <= k; j++)
2834
		      for (unsigned int j = i + 1; j <= k; j++)
2775
			{
2835
			{
2776
			  store_immediate_info *info2 = m_store_info[j];
2836
			  store_immediate_info *info2 = m_store_info[j];
(-)gcc/testsuite/gcc.dg/store_merging_24.c.jj (+75 lines)
Line 0 Link Here
1
/* PR tree-optimization/87859 */
2
/* { dg-do run } */
3
/* { dg-options "-O2 -fdump-tree-store-merging-details" } */
4
/* { dg-final { scan-tree-dump "New sequence of \[23] stores to replace old one of 19 stores" "store-merging" { target i?86-*-* x86_64-*-* } } } */
5
/* { dg-final { scan-tree-dump "New sequence of 1 stores to replace old one of 6 stores" "store-merging" { target i?86-*-* x86_64-*-* } } } */
6
7
struct S {
8
  union F {
9
    struct T {
10
#define A(n) unsigned n:1;
11
#define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) \
12
	     A(n##5) A(n##6) A(n##7) A(n##8) A(n##9)
13
      B(f) B(f1) B(f2) B(f3) B(f4) B(f5)
14
      A(f60) A(f61) A(f62) A(f63) A(f64) A(f65) A(f66)
15
    } q;
16
    unsigned int i[3];
17
  } f;
18
};
19
20
struct S s = {
21
  .f.q.f0 = 1, .f.q.f1 = 1, .f.q.f2 = 1, .f.q.f5 = 1, .f.q.f6 = 1,
22
  .f.q.f7 = 1, .f.q.f8 = 1, .f.q.f9 = 1, .f.q.f13 = 1, .f.q.f14 = 1,
23
  .f.q.f15 = 1, .f.q.f16 = 1, .f.q.f17 = 1, .f.q.f19 = 1, .f.q.f21 = 1,
24
  .f.q.f66 = 1
25
};
26
27
__attribute__((noipa)) void
28
bar (unsigned *x)
29
{
30
  if (x[0] != s.f.i[0] || x[1] != s.f.i[1] || x[2] != s.f.i[2])
31
    __builtin_abort ();
32
}
33
34
__attribute__((noipa)) void
35
foo (unsigned char *state)
36
{
37
  struct S i;
38
  i.f.i[0] = 0;
39
  i.f.i[1] = 0;
40
  i.f.i[2] = 0;
41
  i.f.q.f7 = 1;
42
  i.f.q.f2 = 1;
43
  i.f.q.f21 = 1;
44
  i.f.q.f19 = 1;
45
  i.f.q.f14 = 1;
46
  i.f.q.f5 = 1;
47
  i.f.q.f0 = 1;
48
  i.f.q.f15 = 1;
49
  i.f.q.f16 = 1;
50
  i.f.q.f6 = 1;
51
  i.f.q.f9 = 1;
52
  i.f.q.f17 = 1;
53
  i.f.q.f1 = 1;
54
  i.f.q.f8 = 1;
55
  i.f.q.f13 = 1;
56
  i.f.q.f66 = 1;
57
  if (*state)
58
    {
59
      i.f.q.f37 = 1;
60
      i.f.q.f38 = 1;
61
      i.f.q.f39 = 1;
62
      i.f.q.f40 = 1;
63
      i.f.q.f41 = 1;
64
      i.f.q.f36 = 1;
65
    }
66
  bar (i.f.i);
67
}
68
69
int
70
main ()
71
{
72
  unsigned char z = 0;
73
  foo (&z);
74
  return 0;
75
}

Return to bug 87859