summaryrefslogtreecommitdiff
path: root/0290-Add-ipa-prefetch-test-for-gcc-s-case.patch
blob: 4545420167bc764595b22b12d7ce486786325429 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
From 0534ae05fc313c0d449b48ffe3e01642b644e6d2 Mon Sep 17 00:00:00 2001
From: Diachkov Ilia <diachkov.ilial@huawei-partners.com>
Date: Fri, 6 Sep 2024 10:40:50 +0800
Subject: [PATCH 1/2] Add ipa-prefetch test for gcc's case

---
 gcc/ipa-prefetch.cc                         |   4 +-
 gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c | 167 ++++++++++++++++++++
 2 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c

diff --git a/gcc/ipa-prefetch.cc b/gcc/ipa-prefetch.cc
index b000d4d75..8e628390b 100644
--- a/gcc/ipa-prefetch.cc
+++ b/gcc/ipa-prefetch.cc
@@ -1668,6 +1668,8 @@ static gimple *
 insert_page_check (tree addr, tree_poly_offset_map &offset_map,
 		   gimple_seq &stmts)
 {
+  if (dump_file)
+    fprintf (dump_file, "Insert page check.\n");
   poly_offset_int offset = 0;
   if (offset_map.count (addr))
     offset = offset_map[addr];
@@ -1783,7 +1785,7 @@ static gimple *
 insert_index_check (tree mem, gimple_seq &stmts)
 {
   if (dump_file)
-    fprintf (dump_file, "Insert array index check\n");
+    fprintf (dump_file, "Insert array index check.\n");
   tree atype = TREE_TYPE (TREE_OPERAND (mem, 0));
   tree ind = TREE_OPERAND (mem, 1);
   if (decl_map->count (ind))
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c b/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c
new file mode 100644
index 000000000..f1001c350
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-prefetch-gcc.c
@@ -0,0 +1,167 @@
+/* { dg-do link } */
+/* { dg-options "-O3 -fipa-prefetch -flto -flto-partition=one -fdump-ipa-ipa_prefetch" } */
+/* { dg-require-effective-target lto } */
+
+/* Based on opensource gcc code.  */
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#define SPARSESET_ELT_TYPE unsigned int
+#define ALLOCNO_NUM(A) ((A)->num)
+
+typedef struct sparseset_def
+{
+  SPARSESET_ELT_TYPE *dense;	/* Dense array.  */
+  SPARSESET_ELT_TYPE *sparse;	/* Sparse array.  */
+  SPARSESET_ELT_TYPE members;	/* Number of elements.  */
+  SPARSESET_ELT_TYPE size;	/* Maximum number of elements.  */
+  SPARSESET_ELT_TYPE iter;	/* Iterator index.  */
+  unsigned char iter_inc;	/* Iteration increment amount.  */
+  bool iterating;
+  SPARSESET_ELT_TYPE elms[2];   /* Combined dense and sparse arrays.  */
+} *sparseset;
+
+struct ira_allocno
+{
+  /* The allocno order number starting with 0.  Each allocno has an
+     unique number and the number is never changed for the
+     allocno.  */
+  int num;
+  /* Regno for allocno or cap.  */
+  int regno;
+  /*...*/
+};
+
+typedef struct ira_allocno_live_range *allocno_live_range_t;
+typedef struct ira_allocno *ira_allocno_t;
+
+struct ira_allocno_live_range
+{
+  /* Allocno whose live range is described by given structure.  */
+  ira_allocno_t allocno;
+  /* Program point range.  */
+  int start, finish;
+  /* Next structure describing program points where the allocno
+     lives.  */
+  allocno_live_range_t next;
+  /* Pointer to structures with the same start/finish.  */
+  allocno_live_range_t start_next, finish_next;
+};
+
+bool
+sparseset_bit_p (sparseset s, SPARSESET_ELT_TYPE e)
+{
+  SPARSESET_ELT_TYPE idx;
+
+  idx = s->sparse[e];
+
+  return idx < s->members && s->dense[idx] == e;
+}
+
+bool new_pseudos_p;
+int ira_max_point, ira_allocnos_num;
+allocno_live_range_t *ira_finish_point_ranges;
+
+static inline void
+sparseset_clear (sparseset s)
+{
+  s->members = 0;
+  s->iterating = false;
+}
+
+sparseset
+sparseset_alloc (SPARSESET_ELT_TYPE n_elms)
+{
+  unsigned int n_bytes = sizeof (struct sparseset_def)
+			 + ((n_elms - 1) * 2 * sizeof (SPARSESET_ELT_TYPE));
+
+  /* We use xcalloc rather than xmalloc to silence some valgrind uninitialized
+     read errors when accessing set->sparse[n] when "n" is not, and never has
+     been, in the set.  These uninitialized reads are expected, by design and
+     harmless.  If this turns into a performance problem due to some future
+     additional users of sparseset, we can revisit this decision.  */
+  sparseset set = (sparseset) calloc (1, n_bytes);
+  set->dense = &(set->elms[0]);
+  set->sparse = &(set->elms[n_elms]);
+  set->size = n_elms;
+  sparseset_clear (set);
+  return set;
+}
+
+void
+sparseset_insert_bit (sparseset s, SPARSESET_ELT_TYPE e, SPARSESET_ELT_TYPE idx)
+{
+  s->sparse[e] = idx;
+  s->dense[idx] = e;
+}
+
+void
+sparseset_swap (sparseset s, SPARSESET_ELT_TYPE idx1, SPARSESET_ELT_TYPE idx2)
+{
+  SPARSESET_ELT_TYPE tmp = s->dense[idx2];
+  sparseset_insert_bit (s, s->dense[idx1], idx2);
+  sparseset_insert_bit (s, tmp, idx1);
+}
+
+void __attribute__ ((noinline))
+sparseset_clear_bit (sparseset s, SPARSESET_ELT_TYPE e)
+{
+  if (sparseset_bit_p (s, e))
+    {
+      SPARSESET_ELT_TYPE idx = s->sparse[e];
+      SPARSESET_ELT_TYPE iter = s->iter;
+      SPARSESET_ELT_TYPE mem = s->members - 1;
+
+      /* If we are iterating over this set and we want to delete a
+	 member we've already visited, then we swap the element we
+	 want to delete with the element at the current iteration
+	 index so that it plays well together with the code below
+	 that actually removes the element.  */
+      if (s->iterating && idx <= iter)
+	{
+	  if (idx < iter)
+	    {
+	      sparseset_swap (s, idx, iter);
+	      idx = iter;
+	    }
+	  s->iter_inc = 0;
+	}
+
+      /* Replace the element we want to delete with the last element
+	 in the dense array and then decrement s->members, effectively
+	 removing the element we want to delete.  */
+      sparseset_insert_bit (s, s->dense[mem], idx);
+      s->members = mem;
+    }
+}
+
+allocno_live_range_t r;
+sparseset allocnos_live;
+
+void
+ira_flattening ()
+{
+  int i;
+
+  if (new_pseudos_p)
+    {
+      allocnos_live = sparseset_alloc (ira_allocnos_num);
+      for (i = 0; i < ira_max_point; i++)
+	{
+	  for (r = ira_finish_point_ranges[i]; r != NULL; r = r->finish_next)
+	    sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (r->allocno));
+	}
+    }
+}
+
+int main()
+{
+  ira_flattening ();
+  return 0;
+}
+
+/* { dg-final { scan-wpa-ipa-dump-times "Insert page check" 1 "ipa_prefetch"} } */
+/* { dg-final { scan-wpa-ipa-dump-times "Insert 0 prefetch stmt:" 1 "ipa_prefetch"} } */
+/* { dg-final { scan-wpa-ipa-dump-times "Split dom_bb after condition stmts:" 1 "ipa_prefetch"} } */
-- 
2.33.0