]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-18.c
Fix profile update in tree_transform_and_unroll_loop
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / tree-ssa / ssa-sink-18.c
CommitLineData
de56f95a
XL
1/* { dg-do compile } */
2/* { dg-options "-O2 -fdump-tree-sink-stats" } */
42d6b7d5 3/* { dg-require-effective-target int32plus } */
de56f95a
XL
4
5#include <stdint.h>
6
7#define HLOG 16
8#define MAX_LIT (1 << 5)
9typedef const uint8_t *LZF_HSLOT;
10typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
11
12int
13compute_on_bytes (uint8_t *in_data, int in_len, uint8_t *out_data, int out_len)
14{
15 LZF_STATE htab;
16
17 uint8_t *ip = in_data;
18 uint8_t *op = out_data;
19 uint8_t *in_end = ip + in_len;
20 uint8_t *out_end = op + out_len;
21 uint8_t *ref;
22
23 unsigned long off;
24 unsigned int hval;
25 int lit;
26
27 if (!in_len || !out_len)
28 return 0;
29
30 lit = 0;
31 op++;
32 hval = (((ip[0]) << 8) | ip[1]);
33
34 while (ip < in_end - 2)
35 {
36 uint8_t *hslot;
37
38 hval = (((hval) << 8) | ip[2]);
39 hslot = (uint8_t*)(htab + (((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1)));
40
41 ref = *hslot + in_data;
42 *hslot = ip - in_data;
43
44 if (1 && (off = ip - ref - 1) < (1 << 13) && ref > in_data
45 && ref[2] == ip[2]
46 && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0]))
47 {
48 unsigned int len = 2;
49 unsigned int maxlen = in_end - ip - len;
50 maxlen
51 = maxlen > ((1 << 8) + (1 << 3)) ? ((1 << 8) + (1 << 3)) : maxlen;
52
53 if ((op + 3 + 1 >= out_end) != 0)
54 if (op - !lit + 3 + 1 >= out_end)
55 return 0;
56
57 op[-lit - 1] = lit - 1;
58 op -= !lit;
59
60 for (;;)
61 {
62 if (maxlen > 16)
63 {
64 len++;
65 if (ref[len] != ip[len])
66 break;
67 len++;
68 if (ref[len] != ip[len])
69 break;
70 len++;
71 if (ref[len] != ip[len])
72 break;
73 len++;
74 if (ref[len] != ip[len])
75 break;
76
77 len++;
78 if (ref[len] != ip[len])
79 break;
80 len++;
81 if (ref[len] != ip[len])
82 break;
83 len++;
84 if (ref[len] != ip[len])
85 break;
86 len++;
87 if (ref[len] != ip[len])
88 break;
89
90 len++;
91 if (ref[len] != ip[len])
92 break;
93 len++;
94 if (ref[len] != ip[len])
95 break;
96 len++;
97 if (ref[len] != ip[len])
98 break;
99 len++;
100 if (ref[len] != ip[len])
101 break;
102
103 len++;
104 if (ref[len] != ip[len])
105 break;
106 len++;
107 if (ref[len] != ip[len])
108 break;
109 len++;
110 if (ref[len] != ip[len])
111 break;
112 len++;
113 if (ref[len] != ip[len])
114 break;
115 }
116
117 do
118 {
119 len++;
120 }
121 while (len < maxlen && ip[len] == ref[len]);
122
123 break;
124 }
125
126 len -= 2;
127 ip++;
128
129 if (len < 7)
130 {
131 *op++ = (off >> 8) + (len << 5);
132 }
133 else
134 {
135 *op++ = (off >> 8) + (7 << 5);
136 *op++ = len - 7;
137 }
138 *op++ = off;
139 lit = 0;
140 op++;
141 ip += len + 1;
142
143 if (ip >= in_end - 2)
144 break;
145
146 --ip;
147 --ip;
148
149 hval = (((ip[0]) << 8) | ip[1]);
150 hval = (((hval) << 8) | ip[2]);
151 htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))]
152 = (LZF_HSLOT)(ip - in_data);
153 ip++;
154
155 hval = (((hval) << 8) | ip[2]);
156 htab[(((hval >> (3 * 8 - 16)) - hval * 5) & ((1 << (16)) - 1))]
157 = (LZF_HSLOT)(ip - in_data);
158 ip++;
159 }
160 else
161 {
162 if (op >= out_end)
163 return 0;
164
165 lit++;
166 *op++ = *ip++;
167
168 if (lit == (1 << 5))
169 {
170 op[-lit - 1] = lit - 1;
171 lit = 0;
172 op++;
173 }
174 }
175 }
176 if (op + 3 > out_end) /* at most 3 bytes can be missing here */
177 return 0;
178
179 while (ip < in_end)
180 {
181 lit++;
182 *op++ = *ip++;
183 if (lit == MAX_LIT)
184 {
185 op[-lit - 1] = lit - 1; /* stop run */
186 lit = 0;
187 op++; /* start run */
188 }
189 }
190
191 op[-lit - 1] = lit - 1; /* end run */
192 op -= !lit; /* undo run if length is zero */
193
194 return op - out_data;
195 }
196
197 /* For this case, pass sink2 sinks statements from hot loop header to loop
198 exits after gimple loop optimizations, which generates instructions executed
199 each iteration in loop, but the results are used outside of loop:
200 With -m64,
201 "Sinking _367 = (uint8_t *) _320;
202 from bb 31 to bb 90
203 Sinking _320 = _321 + ivtmp.25_326;
204 from bb 31 to bb 90
205 Sinking _321 = (unsigned long) ip_229;
206 from bb 31 to bb 90
207 Sinking len_158 = _322 + 4294967295;
208 from bb 31 to bb 33"
209 When -m32, Power and X86 will sink 3 instructions, but arm ilp32 couldn't
210 sink due to ivopts chooses two IV candidates instead of one, which is
93574914
AO
211 expected, so this case is restricted to lp64 only so far. This different
212 ivopts choice affects riscv64 as well, probably because it also lacks
213 base+index addressing modes, so the ip[len] address computation can't be
214 made from the IV computation above. */
de56f95a 215
93574914 216 /* { dg-final { scan-tree-dump-times "Sunk statements: 4" 1 "sink2" { target lp64 xfail { riscv64-*-* } } } } */