annotate gcc/config/i386/x86-tune-sched-bd.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Scheduler hooks for IA-32 which implement bdver1-4 specific logic.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 1988-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify
kono
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
kono
parents:
diff changeset
8 the Free Software Foundation; either version 3, or (at your option)
kono
parents:
diff changeset
9 any later version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful,
kono
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
kono
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
kono
parents:
diff changeset
14 GNU General Public License for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
19
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
20 #define IN_TARGET_CODE 1
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
21
111
kono
parents:
diff changeset
22 #include "config.h"
kono
parents:
diff changeset
23 #include "system.h"
kono
parents:
diff changeset
24 #include "coretypes.h"
kono
parents:
diff changeset
25 #include "backend.h"
kono
parents:
diff changeset
26 #include "rtl.h"
kono
parents:
diff changeset
27 #include "tree.h"
kono
parents:
diff changeset
28 #include "cfghooks.h"
kono
parents:
diff changeset
29 #include "tm_p.h"
kono
parents:
diff changeset
30 #include "insn-config.h"
kono
parents:
diff changeset
31 #include "insn-attr.h"
kono
parents:
diff changeset
32 #include "recog.h"
kono
parents:
diff changeset
33 #include "target.h"
kono
parents:
diff changeset
34 #include "rtl-iter.h"
kono
parents:
diff changeset
35 #include "regset.h"
kono
parents:
diff changeset
36 #include "sched-int.h"
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 /* The size of the dispatch window is the total number of bytes of
kono
parents:
diff changeset
39 object code allowed in a window. */
kono
parents:
diff changeset
40 #define DISPATCH_WINDOW_SIZE 16
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 /* Number of dispatch windows considered for scheduling. */
kono
parents:
diff changeset
43 #define MAX_DISPATCH_WINDOWS 3
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 /* Maximum number of instructions in a window. */
kono
parents:
diff changeset
46 #define MAX_INSN 4
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 /* Maximum number of immediate operands in a window. */
kono
parents:
diff changeset
49 #define MAX_IMM 4
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 /* Maximum number of immediate bits allowed in a window. */
kono
parents:
diff changeset
52 #define MAX_IMM_SIZE 128
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 /* Maximum number of 32 bit immediates allowed in a window. */
kono
parents:
diff changeset
55 #define MAX_IMM_32 4
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 /* Maximum number of 64 bit immediates allowed in a window. */
kono
parents:
diff changeset
58 #define MAX_IMM_64 2
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 /* Maximum total of loads or prefetches allowed in a window. */
kono
parents:
diff changeset
61 #define MAX_LOAD 2
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 /* Maximum total of stores allowed in a window. */
kono
parents:
diff changeset
64 #define MAX_STORE 1
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 #undef BIG
kono
parents:
diff changeset
67 #define BIG 100
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 /* Dispatch groups. Istructions that affect the mix in a dispatch window. */
kono
parents:
diff changeset
71 enum dispatch_group {
kono
parents:
diff changeset
72 disp_no_group = 0,
kono
parents:
diff changeset
73 disp_load,
kono
parents:
diff changeset
74 disp_store,
kono
parents:
diff changeset
75 disp_load_store,
kono
parents:
diff changeset
76 disp_prefetch,
kono
parents:
diff changeset
77 disp_imm,
kono
parents:
diff changeset
78 disp_imm_32,
kono
parents:
diff changeset
79 disp_imm_64,
kono
parents:
diff changeset
80 disp_branch,
kono
parents:
diff changeset
81 disp_cmp,
kono
parents:
diff changeset
82 disp_jcc,
kono
parents:
diff changeset
83 disp_last
kono
parents:
diff changeset
84 };
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 /* Number of allowable groups in a dispatch window. It is an array
kono
parents:
diff changeset
87 indexed by dispatch_group enum. 100 is used as a big number,
kono
parents:
diff changeset
88 because the number of these kind of operations does not have any
kono
parents:
diff changeset
89 effect in dispatch window, but we need them for other reasons in
kono
parents:
diff changeset
90 the table. */
kono
parents:
diff changeset
91 static unsigned int num_allowable_groups[disp_last] = {
kono
parents:
diff changeset
92 0, 2, 1, 1, 2, 4, 4, 2, 1, BIG, BIG
kono
parents:
diff changeset
93 };
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 char group_name[disp_last + 1][16] = {
kono
parents:
diff changeset
96 "disp_no_group", "disp_load", "disp_store", "disp_load_store",
kono
parents:
diff changeset
97 "disp_prefetch", "disp_imm", "disp_imm_32", "disp_imm_64",
kono
parents:
diff changeset
98 "disp_branch", "disp_cmp", "disp_jcc", "disp_last"
kono
parents:
diff changeset
99 };
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 /* Instruction path. */
kono
parents:
diff changeset
102 enum insn_path {
kono
parents:
diff changeset
103 no_path = 0,
kono
parents:
diff changeset
104 path_single, /* Single micro op. */
kono
parents:
diff changeset
105 path_double, /* Double micro op. */
kono
parents:
diff changeset
106 path_multi, /* Instructions with more than 2 micro op.. */
kono
parents:
diff changeset
107 last_path
kono
parents:
diff changeset
108 };
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 /* sched_insn_info defines a window to the instructions scheduled in
kono
parents:
diff changeset
111 the basic block. It contains a pointer to the insn_info table and
kono
parents:
diff changeset
112 the instruction scheduled.
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 Windows are allocated for each basic block and are linked
kono
parents:
diff changeset
115 together. */
kono
parents:
diff changeset
116 typedef struct sched_insn_info_s {
kono
parents:
diff changeset
117 rtx insn;
kono
parents:
diff changeset
118 enum dispatch_group group;
kono
parents:
diff changeset
119 enum insn_path path;
kono
parents:
diff changeset
120 int byte_len;
kono
parents:
diff changeset
121 int imm_bytes;
kono
parents:
diff changeset
122 } sched_insn_info;
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124 /* Linked list of dispatch windows. This is a two way list of
kono
parents:
diff changeset
125 dispatch windows of a basic block. It contains information about
kono
parents:
diff changeset
126 the number of uops in the window and the total number of
kono
parents:
diff changeset
127 instructions and of bytes in the object code for this dispatch
kono
parents:
diff changeset
128 window. */
kono
parents:
diff changeset
129 typedef struct dispatch_windows_s {
kono
parents:
diff changeset
130 int num_insn; /* Number of insn in the window. */
kono
parents:
diff changeset
131 int num_uops; /* Number of uops in the window. */
kono
parents:
diff changeset
132 int window_size; /* Number of bytes in the window. */
kono
parents:
diff changeset
133 int window_num; /* Window number between 0 or 1. */
kono
parents:
diff changeset
134 int num_imm; /* Number of immediates in an insn. */
kono
parents:
diff changeset
135 int num_imm_32; /* Number of 32 bit immediates in an insn. */
kono
parents:
diff changeset
136 int num_imm_64; /* Number of 64 bit immediates in an insn. */
kono
parents:
diff changeset
137 int imm_size; /* Total immediates in the window. */
kono
parents:
diff changeset
138 int num_loads; /* Total memory loads in the window. */
kono
parents:
diff changeset
139 int num_stores; /* Total memory stores in the window. */
kono
parents:
diff changeset
140 int violation; /* Violation exists in window. */
kono
parents:
diff changeset
141 sched_insn_info *window; /* Pointer to the window. */
kono
parents:
diff changeset
142 struct dispatch_windows_s *next;
kono
parents:
diff changeset
143 struct dispatch_windows_s *prev;
kono
parents:
diff changeset
144 } dispatch_windows;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 /* Immediate valuse used in an insn. */
kono
parents:
diff changeset
147 typedef struct imm_info_s
kono
parents:
diff changeset
148 {
kono
parents:
diff changeset
149 int imm;
kono
parents:
diff changeset
150 int imm32;
kono
parents:
diff changeset
151 int imm64;
kono
parents:
diff changeset
152 } imm_info;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 static dispatch_windows *dispatch_window_list;
kono
parents:
diff changeset
155 static dispatch_windows *dispatch_window_list1;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 /* Get dispatch group of insn. */
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 static enum dispatch_group
kono
parents:
diff changeset
160 get_mem_group (rtx_insn *insn)
kono
parents:
diff changeset
161 {
kono
parents:
diff changeset
162 enum attr_memory memory;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 if (INSN_CODE (insn) < 0)
kono
parents:
diff changeset
165 return disp_no_group;
kono
parents:
diff changeset
166 memory = get_attr_memory (insn);
kono
parents:
diff changeset
167 if (memory == MEMORY_STORE)
kono
parents:
diff changeset
168 return disp_store;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 if (memory == MEMORY_LOAD)
kono
parents:
diff changeset
171 return disp_load;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 if (memory == MEMORY_BOTH)
kono
parents:
diff changeset
174 return disp_load_store;
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 return disp_no_group;
kono
parents:
diff changeset
177 }
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 /* Return true if insn is a compare instruction. */
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 static bool
kono
parents:
diff changeset
182 is_cmp (rtx_insn *insn)
kono
parents:
diff changeset
183 {
kono
parents:
diff changeset
184 enum attr_type type;
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 type = get_attr_type (insn);
kono
parents:
diff changeset
187 return (type == TYPE_TEST
kono
parents:
diff changeset
188 || type == TYPE_ICMP
kono
parents:
diff changeset
189 || type == TYPE_FCMP
kono
parents:
diff changeset
190 || GET_CODE (PATTERN (insn)) == COMPARE);
kono
parents:
diff changeset
191 }
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 /* Return true if a dispatch violation encountered. */
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 static bool
kono
parents:
diff changeset
196 dispatch_violation (void)
kono
parents:
diff changeset
197 {
kono
parents:
diff changeset
198 if (dispatch_window_list->next)
kono
parents:
diff changeset
199 return dispatch_window_list->next->violation;
kono
parents:
diff changeset
200 return dispatch_window_list->violation;
kono
parents:
diff changeset
201 }
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 /* Return true if insn is a branch instruction. */
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 static bool
kono
parents:
diff changeset
206 is_branch (rtx_insn *insn)
kono
parents:
diff changeset
207 {
kono
parents:
diff changeset
208 return (CALL_P (insn) || JUMP_P (insn));
kono
parents:
diff changeset
209 }
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 /* Return true if insn is a prefetch instruction. */
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 static bool
kono
parents:
diff changeset
214 is_prefetch (rtx_insn *insn)
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 return NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == PREFETCH;
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218
kono
parents:
diff changeset
219 /* This function initializes a dispatch window and the list container holding a
kono
parents:
diff changeset
220 pointer to the window. */
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 static void
kono
parents:
diff changeset
223 init_window (int window_num)
kono
parents:
diff changeset
224 {
kono
parents:
diff changeset
225 int i;
kono
parents:
diff changeset
226 dispatch_windows *new_list;
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228 if (window_num == 0)
kono
parents:
diff changeset
229 new_list = dispatch_window_list;
kono
parents:
diff changeset
230 else
kono
parents:
diff changeset
231 new_list = dispatch_window_list1;
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 new_list->num_insn = 0;
kono
parents:
diff changeset
234 new_list->num_uops = 0;
kono
parents:
diff changeset
235 new_list->window_size = 0;
kono
parents:
diff changeset
236 new_list->next = NULL;
kono
parents:
diff changeset
237 new_list->prev = NULL;
kono
parents:
diff changeset
238 new_list->window_num = window_num;
kono
parents:
diff changeset
239 new_list->num_imm = 0;
kono
parents:
diff changeset
240 new_list->num_imm_32 = 0;
kono
parents:
diff changeset
241 new_list->num_imm_64 = 0;
kono
parents:
diff changeset
242 new_list->imm_size = 0;
kono
parents:
diff changeset
243 new_list->num_loads = 0;
kono
parents:
diff changeset
244 new_list->num_stores = 0;
kono
parents:
diff changeset
245 new_list->violation = false;
kono
parents:
diff changeset
246
kono
parents:
diff changeset
247 for (i = 0; i < MAX_INSN; i++)
kono
parents:
diff changeset
248 {
kono
parents:
diff changeset
249 new_list->window[i].insn = NULL;
kono
parents:
diff changeset
250 new_list->window[i].group = disp_no_group;
kono
parents:
diff changeset
251 new_list->window[i].path = no_path;
kono
parents:
diff changeset
252 new_list->window[i].byte_len = 0;
kono
parents:
diff changeset
253 new_list->window[i].imm_bytes = 0;
kono
parents:
diff changeset
254 }
kono
parents:
diff changeset
255 return;
kono
parents:
diff changeset
256 }
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 /* This function allocates and initializes a dispatch window and the
kono
parents:
diff changeset
259 list container holding a pointer to the window. */
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 static dispatch_windows *
kono
parents:
diff changeset
262 allocate_window (void)
kono
parents:
diff changeset
263 {
kono
parents:
diff changeset
264 dispatch_windows *new_list = XNEW (struct dispatch_windows_s);
kono
parents:
diff changeset
265 new_list->window = XNEWVEC (struct sched_insn_info_s, MAX_INSN + 1);
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 return new_list;
kono
parents:
diff changeset
268 }
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 /* This routine initializes the dispatch scheduling information. It
kono
parents:
diff changeset
271 initiates building dispatch scheduler tables and constructs the
kono
parents:
diff changeset
272 first dispatch window. */
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 static void
kono
parents:
diff changeset
275 init_dispatch_sched (void)
kono
parents:
diff changeset
276 {
kono
parents:
diff changeset
277 /* Allocate a dispatch list and a window. */
kono
parents:
diff changeset
278 dispatch_window_list = allocate_window ();
kono
parents:
diff changeset
279 dispatch_window_list1 = allocate_window ();
kono
parents:
diff changeset
280 init_window (0);
kono
parents:
diff changeset
281 init_window (1);
kono
parents:
diff changeset
282 }
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 /* This function returns true if a branch is detected. End of a basic block
kono
parents:
diff changeset
285 does not have to be a branch, but here we assume only branches end a
kono
parents:
diff changeset
286 window. */
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 static bool
kono
parents:
diff changeset
289 is_end_basic_block (enum dispatch_group group)
kono
parents:
diff changeset
290 {
kono
parents:
diff changeset
291 return group == disp_branch;
kono
parents:
diff changeset
292 }
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 /* This function is called when the end of a window processing is reached. */
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 static void
kono
parents:
diff changeset
297 process_end_window (void)
kono
parents:
diff changeset
298 {
kono
parents:
diff changeset
299 gcc_assert (dispatch_window_list->num_insn <= MAX_INSN);
kono
parents:
diff changeset
300 if (dispatch_window_list->next)
kono
parents:
diff changeset
301 {
kono
parents:
diff changeset
302 gcc_assert (dispatch_window_list1->num_insn <= MAX_INSN);
kono
parents:
diff changeset
303 gcc_assert (dispatch_window_list->window_size
kono
parents:
diff changeset
304 + dispatch_window_list1->window_size <= 48);
kono
parents:
diff changeset
305 init_window (1);
kono
parents:
diff changeset
306 }
kono
parents:
diff changeset
307 init_window (0);
kono
parents:
diff changeset
308 }
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 /* Allocates a new dispatch window and adds it to WINDOW_LIST.
kono
parents:
diff changeset
311 WINDOW_NUM is either 0 or 1. A maximum of two windows are generated
kono
parents:
diff changeset
312 for 48 bytes of instructions. Note that these windows are not dispatch
kono
parents:
diff changeset
313 windows that their sizes are DISPATCH_WINDOW_SIZE. */
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 static dispatch_windows *
kono
parents:
diff changeset
316 allocate_next_window (int window_num)
kono
parents:
diff changeset
317 {
kono
parents:
diff changeset
318 if (window_num == 0)
kono
parents:
diff changeset
319 {
kono
parents:
diff changeset
320 if (dispatch_window_list->next)
kono
parents:
diff changeset
321 init_window (1);
kono
parents:
diff changeset
322 init_window (0);
kono
parents:
diff changeset
323 return dispatch_window_list;
kono
parents:
diff changeset
324 }
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 dispatch_window_list->next = dispatch_window_list1;
kono
parents:
diff changeset
327 dispatch_window_list1->prev = dispatch_window_list;
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 return dispatch_window_list1;
kono
parents:
diff changeset
330 }
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 /* Compute number of immediate operands of an instruction. */
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 static void
kono
parents:
diff changeset
335 find_constant (rtx in_rtx, imm_info *imm_values)
kono
parents:
diff changeset
336 {
kono
parents:
diff changeset
337 if (INSN_P (in_rtx))
kono
parents:
diff changeset
338 in_rtx = PATTERN (in_rtx);
kono
parents:
diff changeset
339 subrtx_iterator::array_type array;
kono
parents:
diff changeset
340 FOR_EACH_SUBRTX (iter, array, in_rtx, ALL)
kono
parents:
diff changeset
341 if (const_rtx x = *iter)
kono
parents:
diff changeset
342 switch (GET_CODE (x))
kono
parents:
diff changeset
343 {
kono
parents:
diff changeset
344 case CONST:
kono
parents:
diff changeset
345 case SYMBOL_REF:
kono
parents:
diff changeset
346 case CONST_INT:
kono
parents:
diff changeset
347 (imm_values->imm)++;
kono
parents:
diff changeset
348 if (x86_64_immediate_operand (CONST_CAST_RTX (x), SImode))
kono
parents:
diff changeset
349 (imm_values->imm32)++;
kono
parents:
diff changeset
350 else
kono
parents:
diff changeset
351 (imm_values->imm64)++;
kono
parents:
diff changeset
352 break;
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 case CONST_DOUBLE:
kono
parents:
diff changeset
355 case CONST_WIDE_INT:
kono
parents:
diff changeset
356 (imm_values->imm)++;
kono
parents:
diff changeset
357 (imm_values->imm64)++;
kono
parents:
diff changeset
358 break;
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 case CODE_LABEL:
kono
parents:
diff changeset
361 if (LABEL_KIND (x) == LABEL_NORMAL)
kono
parents:
diff changeset
362 {
kono
parents:
diff changeset
363 (imm_values->imm)++;
kono
parents:
diff changeset
364 (imm_values->imm32)++;
kono
parents:
diff changeset
365 }
kono
parents:
diff changeset
366 break;
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 default:
kono
parents:
diff changeset
369 break;
kono
parents:
diff changeset
370 }
kono
parents:
diff changeset
371 }
kono
parents:
diff changeset
372
kono
parents:
diff changeset
373 /* Return total size of immediate operands of an instruction along with number
kono
parents:
diff changeset
374 of corresponding immediate-operands. It initializes its parameters to zero
kono
parents:
diff changeset
375 befor calling FIND_CONSTANT.
kono
parents:
diff changeset
376 INSN is the input instruction. IMM is the total of immediates.
kono
parents:
diff changeset
377 IMM32 is the number of 32 bit immediates. IMM64 is the number of 64
kono
parents:
diff changeset
378 bit immediates. */
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 static int
kono
parents:
diff changeset
381 get_num_immediates (rtx_insn *insn, int *imm, int *imm32, int *imm64)
kono
parents:
diff changeset
382 {
kono
parents:
diff changeset
383 imm_info imm_values = {0, 0, 0};
kono
parents:
diff changeset
384
kono
parents:
diff changeset
385 find_constant (insn, &imm_values);
kono
parents:
diff changeset
386 *imm = imm_values.imm;
kono
parents:
diff changeset
387 *imm32 = imm_values.imm32;
kono
parents:
diff changeset
388 *imm64 = imm_values.imm64;
kono
parents:
diff changeset
389 return imm_values.imm32 * 4 + imm_values.imm64 * 8;
kono
parents:
diff changeset
390 }
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 /* This function indicates if an operand of an instruction is an
kono
parents:
diff changeset
393 immediate. */
kono
parents:
diff changeset
394
kono
parents:
diff changeset
395 static bool
kono
parents:
diff changeset
396 has_immediate (rtx_insn *insn)
kono
parents:
diff changeset
397 {
kono
parents:
diff changeset
398 int num_imm_operand;
kono
parents:
diff changeset
399 int num_imm32_operand;
kono
parents:
diff changeset
400 int num_imm64_operand;
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 if (insn)
kono
parents:
diff changeset
403 return get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
kono
parents:
diff changeset
404 &num_imm64_operand);
kono
parents:
diff changeset
405 return false;
kono
parents:
diff changeset
406 }
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 /* Return single or double path for instructions. */
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 static enum insn_path
kono
parents:
diff changeset
411 get_insn_path (rtx_insn *insn)
kono
parents:
diff changeset
412 {
kono
parents:
diff changeset
413 enum attr_amdfam10_decode path = get_attr_amdfam10_decode (insn);
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 if ((int)path == 0)
kono
parents:
diff changeset
416 return path_single;
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 if ((int)path == 1)
kono
parents:
diff changeset
419 return path_double;
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 return path_multi;
kono
parents:
diff changeset
422 }
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 /* Return insn dispatch group. */
kono
parents:
diff changeset
425
kono
parents:
diff changeset
426 static enum dispatch_group
kono
parents:
diff changeset
427 get_insn_group (rtx_insn *insn)
kono
parents:
diff changeset
428 {
kono
parents:
diff changeset
429 enum dispatch_group group = get_mem_group (insn);
kono
parents:
diff changeset
430 if (group)
kono
parents:
diff changeset
431 return group;
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 if (is_branch (insn))
kono
parents:
diff changeset
434 return disp_branch;
kono
parents:
diff changeset
435
kono
parents:
diff changeset
436 if (is_cmp (insn))
kono
parents:
diff changeset
437 return disp_cmp;
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 if (has_immediate (insn))
kono
parents:
diff changeset
440 return disp_imm;
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 if (is_prefetch (insn))
kono
parents:
diff changeset
443 return disp_prefetch;
kono
parents:
diff changeset
444
kono
parents:
diff changeset
445 return disp_no_group;
kono
parents:
diff changeset
446 }
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 /* Count number of GROUP restricted instructions in a dispatch
kono
parents:
diff changeset
449 window WINDOW_LIST. */
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 static int
kono
parents:
diff changeset
452 count_num_restricted (rtx_insn *insn, dispatch_windows *window_list)
kono
parents:
diff changeset
453 {
kono
parents:
diff changeset
454 enum dispatch_group group = get_insn_group (insn);
kono
parents:
diff changeset
455 int imm_size;
kono
parents:
diff changeset
456 int num_imm_operand;
kono
parents:
diff changeset
457 int num_imm32_operand;
kono
parents:
diff changeset
458 int num_imm64_operand;
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 if (group == disp_no_group)
kono
parents:
diff changeset
461 return 0;
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 if (group == disp_imm)
kono
parents:
diff changeset
464 {
kono
parents:
diff changeset
465 imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
kono
parents:
diff changeset
466 &num_imm64_operand);
kono
parents:
diff changeset
467 if (window_list->imm_size + imm_size > MAX_IMM_SIZE
kono
parents:
diff changeset
468 || num_imm_operand + window_list->num_imm > MAX_IMM
kono
parents:
diff changeset
469 || (num_imm32_operand > 0
kono
parents:
diff changeset
470 && (window_list->num_imm_32 + num_imm32_operand > MAX_IMM_32
kono
parents:
diff changeset
471 || window_list->num_imm_64 * 2 + num_imm32_operand > MAX_IMM_32))
kono
parents:
diff changeset
472 || (num_imm64_operand > 0
kono
parents:
diff changeset
473 && (window_list->num_imm_64 + num_imm64_operand > MAX_IMM_64
kono
parents:
diff changeset
474 || window_list->num_imm_32 + num_imm64_operand * 2 > MAX_IMM_32))
kono
parents:
diff changeset
475 || (window_list->imm_size + imm_size == MAX_IMM_SIZE
kono
parents:
diff changeset
476 && num_imm64_operand > 0
kono
parents:
diff changeset
477 && ((window_list->num_imm_64 > 0
kono
parents:
diff changeset
478 && window_list->num_insn >= 2)
kono
parents:
diff changeset
479 || window_list->num_insn >= 3)))
kono
parents:
diff changeset
480 return BIG;
kono
parents:
diff changeset
481
kono
parents:
diff changeset
482 return 1;
kono
parents:
diff changeset
483 }
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 if ((group == disp_load_store
kono
parents:
diff changeset
486 && (window_list->num_loads >= MAX_LOAD
kono
parents:
diff changeset
487 || window_list->num_stores >= MAX_STORE))
kono
parents:
diff changeset
488 || ((group == disp_load
kono
parents:
diff changeset
489 || group == disp_prefetch)
kono
parents:
diff changeset
490 && window_list->num_loads >= MAX_LOAD)
kono
parents:
diff changeset
491 || (group == disp_store
kono
parents:
diff changeset
492 && window_list->num_stores >= MAX_STORE))
kono
parents:
diff changeset
493 return BIG;
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 return 1;
kono
parents:
diff changeset
496 }
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 /* This function returns true if insn satisfies dispatch rules on the
kono
parents:
diff changeset
499 last window scheduled. */
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 static bool
kono
parents:
diff changeset
502 fits_dispatch_window (rtx_insn *insn)
kono
parents:
diff changeset
503 {
kono
parents:
diff changeset
504 dispatch_windows *window_list = dispatch_window_list;
kono
parents:
diff changeset
505 dispatch_windows *window_list_next = dispatch_window_list->next;
kono
parents:
diff changeset
506 unsigned int num_restrict;
kono
parents:
diff changeset
507 enum dispatch_group group = get_insn_group (insn);
kono
parents:
diff changeset
508 enum insn_path path = get_insn_path (insn);
kono
parents:
diff changeset
509 int sum;
kono
parents:
diff changeset
510
kono
parents:
diff changeset
511 /* Make disp_cmp and disp_jcc get scheduled at the latest. These
kono
parents:
diff changeset
512 instructions should be given the lowest priority in the
kono
parents:
diff changeset
513 scheduling process in Haifa scheduler to make sure they will be
kono
parents:
diff changeset
514 scheduled in the same dispatch window as the reference to them. */
kono
parents:
diff changeset
515 if (group == disp_jcc || group == disp_cmp)
kono
parents:
diff changeset
516 return false;
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518 /* Check nonrestricted. */
kono
parents:
diff changeset
519 if (group == disp_no_group || group == disp_branch)
kono
parents:
diff changeset
520 return true;
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 /* Get last dispatch window. */
kono
parents:
diff changeset
523 if (window_list_next)
kono
parents:
diff changeset
524 window_list = window_list_next;
kono
parents:
diff changeset
525
kono
parents:
diff changeset
526 if (window_list->window_num == 1)
kono
parents:
diff changeset
527 {
kono
parents:
diff changeset
528 sum = window_list->prev->window_size + window_list->window_size;
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 if (sum == 32
kono
parents:
diff changeset
531 || (ix86_min_insn_size (insn) + sum) >= 48)
kono
parents:
diff changeset
532 /* Window 1 is full. Go for next window. */
kono
parents:
diff changeset
533 return true;
kono
parents:
diff changeset
534 }
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536 num_restrict = count_num_restricted (insn, window_list);
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 if (num_restrict > num_allowable_groups[group])
kono
parents:
diff changeset
539 return false;
kono
parents:
diff changeset
540
kono
parents:
diff changeset
541 /* See if it fits in the first window. */
kono
parents:
diff changeset
542 if (window_list->window_num == 0)
kono
parents:
diff changeset
543 {
kono
parents:
diff changeset
544 /* The first widow should have only single and double path
kono
parents:
diff changeset
545 uops. */
kono
parents:
diff changeset
546 if (path == path_double
kono
parents:
diff changeset
547 && (window_list->num_uops + 2) > MAX_INSN)
kono
parents:
diff changeset
548 return false;
kono
parents:
diff changeset
549 else if (path != path_single)
kono
parents:
diff changeset
550 return false;
kono
parents:
diff changeset
551 }
kono
parents:
diff changeset
552 return true;
kono
parents:
diff changeset
553 }
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 /* Add an instruction INSN with NUM_UOPS micro-operations to the
kono
parents:
diff changeset
556 dispatch window WINDOW_LIST. */
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 static void
kono
parents:
diff changeset
559 add_insn_window (rtx_insn *insn, dispatch_windows *window_list, int num_uops)
kono
parents:
diff changeset
560 {
kono
parents:
diff changeset
561 int byte_len = ix86_min_insn_size (insn);
kono
parents:
diff changeset
562 int num_insn = window_list->num_insn;
kono
parents:
diff changeset
563 int imm_size;
kono
parents:
diff changeset
564 sched_insn_info *window = window_list->window;
kono
parents:
diff changeset
565 enum dispatch_group group = get_insn_group (insn);
kono
parents:
diff changeset
566 enum insn_path path = get_insn_path (insn);
kono
parents:
diff changeset
567 int num_imm_operand;
kono
parents:
diff changeset
568 int num_imm32_operand;
kono
parents:
diff changeset
569 int num_imm64_operand;
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 if (!window_list->violation && group != disp_cmp
kono
parents:
diff changeset
572 && !fits_dispatch_window (insn))
kono
parents:
diff changeset
573 window_list->violation = true;
kono
parents:
diff changeset
574
kono
parents:
diff changeset
575 imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
kono
parents:
diff changeset
576 &num_imm64_operand);
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 /* Initialize window with new instruction. */
kono
parents:
diff changeset
579 window[num_insn].insn = insn;
kono
parents:
diff changeset
580 window[num_insn].byte_len = byte_len;
kono
parents:
diff changeset
581 window[num_insn].group = group;
kono
parents:
diff changeset
582 window[num_insn].path = path;
kono
parents:
diff changeset
583 window[num_insn].imm_bytes = imm_size;
kono
parents:
diff changeset
584
kono
parents:
diff changeset
585 window_list->window_size += byte_len;
kono
parents:
diff changeset
586 window_list->num_insn = num_insn + 1;
kono
parents:
diff changeset
587 window_list->num_uops = window_list->num_uops + num_uops;
kono
parents:
diff changeset
588 window_list->imm_size += imm_size;
kono
parents:
diff changeset
589 window_list->num_imm += num_imm_operand;
kono
parents:
diff changeset
590 window_list->num_imm_32 += num_imm32_operand;
kono
parents:
diff changeset
591 window_list->num_imm_64 += num_imm64_operand;
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 if (group == disp_store)
kono
parents:
diff changeset
594 window_list->num_stores += 1;
kono
parents:
diff changeset
595 else if (group == disp_load
kono
parents:
diff changeset
596 || group == disp_prefetch)
kono
parents:
diff changeset
597 window_list->num_loads += 1;
kono
parents:
diff changeset
598 else if (group == disp_load_store)
kono
parents:
diff changeset
599 {
kono
parents:
diff changeset
600 window_list->num_stores += 1;
kono
parents:
diff changeset
601 window_list->num_loads += 1;
kono
parents:
diff changeset
602 }
kono
parents:
diff changeset
603 }
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 /* Adds a scheduled instruction, INSN, to the current dispatch window.
kono
parents:
diff changeset
606 If the total bytes of instructions or the number of instructions in
kono
parents:
diff changeset
607 the window exceed allowable, it allocates a new window. */
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 static void
kono
parents:
diff changeset
610 add_to_dispatch_window (rtx_insn *insn)
kono
parents:
diff changeset
611 {
kono
parents:
diff changeset
612 int byte_len;
kono
parents:
diff changeset
613 dispatch_windows *window_list;
kono
parents:
diff changeset
614 dispatch_windows *next_list;
kono
parents:
diff changeset
615 dispatch_windows *window0_list;
kono
parents:
diff changeset
616 enum insn_path path;
kono
parents:
diff changeset
617 enum dispatch_group insn_group;
kono
parents:
diff changeset
618 bool insn_fits;
kono
parents:
diff changeset
619 int num_insn;
kono
parents:
diff changeset
620 int num_uops;
kono
parents:
diff changeset
621 int window_num;
kono
parents:
diff changeset
622 int insn_num_uops;
kono
parents:
diff changeset
623 int sum;
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 if (INSN_CODE (insn) < 0)
kono
parents:
diff changeset
626 return;
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 byte_len = ix86_min_insn_size (insn);
kono
parents:
diff changeset
629 window_list = dispatch_window_list;
kono
parents:
diff changeset
630 next_list = window_list->next;
kono
parents:
diff changeset
631 path = get_insn_path (insn);
kono
parents:
diff changeset
632 insn_group = get_insn_group (insn);
kono
parents:
diff changeset
633
kono
parents:
diff changeset
634 /* Get the last dispatch window. */
kono
parents:
diff changeset
635 if (next_list)
kono
parents:
diff changeset
636 window_list = dispatch_window_list->next;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 if (path == path_single)
kono
parents:
diff changeset
639 insn_num_uops = 1;
kono
parents:
diff changeset
640 else if (path == path_double)
kono
parents:
diff changeset
641 insn_num_uops = 2;
kono
parents:
diff changeset
642 else
kono
parents:
diff changeset
643 insn_num_uops = (int) path;
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 /* If current window is full, get a new window.
kono
parents:
diff changeset
646 Window number zero is full, if MAX_INSN uops are scheduled in it.
kono
parents:
diff changeset
647 Window number one is full, if window zero's bytes plus window
kono
parents:
diff changeset
648 one's bytes is 32, or if the bytes of the new instruction added
kono
parents:
diff changeset
649 to the total makes it greater than 48, or it has already MAX_INSN
kono
parents:
diff changeset
650 instructions in it. */
kono
parents:
diff changeset
651 num_insn = window_list->num_insn;
kono
parents:
diff changeset
652 num_uops = window_list->num_uops;
kono
parents:
diff changeset
653 window_num = window_list->window_num;
kono
parents:
diff changeset
654 insn_fits = fits_dispatch_window (insn);
kono
parents:
diff changeset
655
kono
parents:
diff changeset
656 if (num_insn >= MAX_INSN
kono
parents:
diff changeset
657 || num_uops + insn_num_uops > MAX_INSN
kono
parents:
diff changeset
658 || !(insn_fits))
kono
parents:
diff changeset
659 {
kono
parents:
diff changeset
660 window_num = ~window_num & 1;
kono
parents:
diff changeset
661 window_list = allocate_next_window (window_num);
kono
parents:
diff changeset
662 }
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 if (window_num == 0)
kono
parents:
diff changeset
665 {
kono
parents:
diff changeset
666 add_insn_window (insn, window_list, insn_num_uops);
kono
parents:
diff changeset
667 if (window_list->num_insn >= MAX_INSN
kono
parents:
diff changeset
668 && insn_group == disp_branch)
kono
parents:
diff changeset
669 {
kono
parents:
diff changeset
670 process_end_window ();
kono
parents:
diff changeset
671 return;
kono
parents:
diff changeset
672 }
kono
parents:
diff changeset
673 }
kono
parents:
diff changeset
674 else if (window_num == 1)
kono
parents:
diff changeset
675 {
kono
parents:
diff changeset
676 window0_list = window_list->prev;
kono
parents:
diff changeset
677 sum = window0_list->window_size + window_list->window_size;
kono
parents:
diff changeset
678 if (sum == 32
kono
parents:
diff changeset
679 || (byte_len + sum) >= 48)
kono
parents:
diff changeset
680 {
kono
parents:
diff changeset
681 process_end_window ();
kono
parents:
diff changeset
682 window_list = dispatch_window_list;
kono
parents:
diff changeset
683 }
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 add_insn_window (insn, window_list, insn_num_uops);
kono
parents:
diff changeset
686 }
kono
parents:
diff changeset
687 else
kono
parents:
diff changeset
688 gcc_unreachable ();
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690 if (is_end_basic_block (insn_group))
kono
parents:
diff changeset
691 {
kono
parents:
diff changeset
692 /* End of basic block is reached do end-basic-block process. */
kono
parents:
diff changeset
693 process_end_window ();
kono
parents:
diff changeset
694 return;
kono
parents:
diff changeset
695 }
kono
parents:
diff changeset
696 }
kono
parents:
diff changeset
697
kono
parents:
diff changeset
698 /* Print the dispatch window, WINDOW_NUM, to FILE. */
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 DEBUG_FUNCTION static void
kono
parents:
diff changeset
701 debug_dispatch_window_file (FILE *file, int window_num)
kono
parents:
diff changeset
702 {
kono
parents:
diff changeset
703 dispatch_windows *list;
kono
parents:
diff changeset
704 int i;
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 if (window_num == 0)
kono
parents:
diff changeset
707 list = dispatch_window_list;
kono
parents:
diff changeset
708 else
kono
parents:
diff changeset
709 list = dispatch_window_list1;
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 fprintf (file, "Window #%d:\n", list->window_num);
kono
parents:
diff changeset
712 fprintf (file, " num_insn = %d, num_uops = %d, window_size = %d\n",
kono
parents:
diff changeset
713 list->num_insn, list->num_uops, list->window_size);
kono
parents:
diff changeset
714 fprintf (file, " num_imm = %d, num_imm_32 = %d, num_imm_64 = %d, imm_size = %d\n",
kono
parents:
diff changeset
715 list->num_imm, list->num_imm_32, list->num_imm_64, list->imm_size);
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 fprintf (file, " num_loads = %d, num_stores = %d\n", list->num_loads,
kono
parents:
diff changeset
718 list->num_stores);
kono
parents:
diff changeset
719 fprintf (file, " insn info:\n");
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 for (i = 0; i < MAX_INSN; i++)
kono
parents:
diff changeset
722 {
kono
parents:
diff changeset
723 if (!list->window[i].insn)
kono
parents:
diff changeset
724 break;
kono
parents:
diff changeset
725 fprintf (file, " group[%d] = %s, insn[%d] = %p, path[%d] = %d byte_len[%d] = %d, imm_bytes[%d] = %d\n",
kono
parents:
diff changeset
726 i, group_name[list->window[i].group],
kono
parents:
diff changeset
727 i, (void *)list->window[i].insn,
kono
parents:
diff changeset
728 i, list->window[i].path,
kono
parents:
diff changeset
729 i, list->window[i].byte_len,
kono
parents:
diff changeset
730 i, list->window[i].imm_bytes);
kono
parents:
diff changeset
731 }
kono
parents:
diff changeset
732 }
kono
parents:
diff changeset
733
kono
parents:
diff changeset
734 /* Print to stdout a dispatch window. */
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 DEBUG_FUNCTION void
kono
parents:
diff changeset
737 debug_dispatch_window (int window_num)
kono
parents:
diff changeset
738 {
kono
parents:
diff changeset
739 debug_dispatch_window_file (stdout, window_num);
kono
parents:
diff changeset
740 }
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 /* Print INSN dispatch information to FILE. */
kono
parents:
diff changeset
743
kono
parents:
diff changeset
744 DEBUG_FUNCTION static void
kono
parents:
diff changeset
745 debug_insn_dispatch_info_file (FILE *file, rtx_insn *insn)
kono
parents:
diff changeset
746 {
kono
parents:
diff changeset
747 int byte_len;
kono
parents:
diff changeset
748 enum insn_path path;
kono
parents:
diff changeset
749 enum dispatch_group group;
kono
parents:
diff changeset
750 int imm_size;
kono
parents:
diff changeset
751 int num_imm_operand;
kono
parents:
diff changeset
752 int num_imm32_operand;
kono
parents:
diff changeset
753 int num_imm64_operand;
kono
parents:
diff changeset
754
kono
parents:
diff changeset
755 if (INSN_CODE (insn) < 0)
kono
parents:
diff changeset
756 return;
kono
parents:
diff changeset
757
kono
parents:
diff changeset
758 byte_len = ix86_min_insn_size (insn);
kono
parents:
diff changeset
759 path = get_insn_path (insn);
kono
parents:
diff changeset
760 group = get_insn_group (insn);
kono
parents:
diff changeset
761 imm_size = get_num_immediates (insn, &num_imm_operand, &num_imm32_operand,
kono
parents:
diff changeset
762 &num_imm64_operand);
kono
parents:
diff changeset
763
kono
parents:
diff changeset
764 fprintf (file, " insn info:\n");
kono
parents:
diff changeset
765 fprintf (file, " group = %s, path = %d, byte_len = %d\n",
kono
parents:
diff changeset
766 group_name[group], path, byte_len);
kono
parents:
diff changeset
767 fprintf (file, " num_imm = %d, num_imm_32 = %d, num_imm_64 = %d, imm_size = %d\n",
kono
parents:
diff changeset
768 num_imm_operand, num_imm32_operand, num_imm64_operand, imm_size);
kono
parents:
diff changeset
769 }
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 /* Print to STDERR the status of the ready list with respect to
kono
parents:
diff changeset
772 dispatch windows. */
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 DEBUG_FUNCTION void
kono
parents:
diff changeset
775 debug_ready_dispatch (void)
kono
parents:
diff changeset
776 {
kono
parents:
diff changeset
777 int i;
kono
parents:
diff changeset
778 int no_ready = number_in_ready ();
kono
parents:
diff changeset
779
kono
parents:
diff changeset
780 fprintf (stdout, "Number of ready: %d\n", no_ready);
kono
parents:
diff changeset
781
kono
parents:
diff changeset
782 for (i = 0; i < no_ready; i++)
kono
parents:
diff changeset
783 debug_insn_dispatch_info_file (stdout, get_ready_element (i));
kono
parents:
diff changeset
784 }
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 /* This routine is the driver of the dispatch scheduler. */
kono
parents:
diff changeset
787
kono
parents:
diff changeset
788 void
kono
parents:
diff changeset
789 ix86_bd_do_dispatch (rtx_insn *insn, int mode)
kono
parents:
diff changeset
790 {
kono
parents:
diff changeset
791 if (mode == DISPATCH_INIT)
kono
parents:
diff changeset
792 init_dispatch_sched ();
kono
parents:
diff changeset
793 else if (mode == ADD_TO_DISPATCH_WINDOW)
kono
parents:
diff changeset
794 add_to_dispatch_window (insn);
kono
parents:
diff changeset
795 }
kono
parents:
diff changeset
796
kono
parents:
diff changeset
797 /* Return TRUE if Dispatch Scheduling is supported. */
kono
parents:
diff changeset
798
kono
parents:
diff changeset
799 bool
kono
parents:
diff changeset
800 ix86_bd_has_dispatch (rtx_insn *insn, int action)
kono
parents:
diff changeset
801 {
kono
parents:
diff changeset
802 /* Current implementation of dispatch scheduler models buldozer only. */
kono
parents:
diff changeset
803 if ((TARGET_BDVER1 || TARGET_BDVER2 || TARGET_BDVER3
kono
parents:
diff changeset
804 || TARGET_BDVER4) && flag_dispatch_scheduler)
kono
parents:
diff changeset
805 switch (action)
kono
parents:
diff changeset
806 {
kono
parents:
diff changeset
807 default:
kono
parents:
diff changeset
808 return false;
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 case IS_DISPATCH_ON:
kono
parents:
diff changeset
811 return true;
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 case IS_CMP:
kono
parents:
diff changeset
814 return is_cmp (insn);
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816 case DISPATCH_VIOLATION:
kono
parents:
diff changeset
817 return dispatch_violation ();
kono
parents:
diff changeset
818
kono
parents:
diff changeset
819 case FITS_DISPATCH_WINDOW:
kono
parents:
diff changeset
820 return fits_dispatch_window (insn);
kono
parents:
diff changeset
821 }
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 return false;
kono
parents:
diff changeset
824 }