1 /* Scheduler hooks for IA-32 which implement bdver1-4 specific logic.
2 Copyright (C) 1988-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #define IN_TARGET_CODE 1
24 #include "coretypes.h"
30 #include "insn-config.h"
31 #include "insn-attr.h"
36 #include "sched-int.h"
39 /* Model decoder of Core 2/i7.
40 Below hooks for multipass scheduling (see haifa-sched.c:max_issue)
41 track the instruction fetch block boundaries and make sure that long
42 (9+ bytes) instructions are assigned to D0. */
44 /* Maximum length of an insn that can be handled by
45 a secondary decoder unit. '8' for Core 2/i7. */
46 static int core2i7_secondary_decoder_max_insn_size
;
48 /* Ifetch block size, i.e., number of bytes decoder reads per cycle.
49 '16' for Core 2/i7. */
50 static int core2i7_ifetch_block_size
;
52 /* Maximum number of instructions decoder can handle per cycle.
54 static int core2i7_ifetch_block_max_insns
;
56 typedef struct ix86_first_cycle_multipass_data_
*
57 ix86_first_cycle_multipass_data_t
;
58 typedef const struct ix86_first_cycle_multipass_data_
*
59 const_ix86_first_cycle_multipass_data_t
;
61 /* A variable to store target state across calls to max_issue within
63 static struct ix86_first_cycle_multipass_data_ _ix86_first_cycle_multipass_data
,
64 *ix86_first_cycle_multipass_data
= &_ix86_first_cycle_multipass_data
;
66 /* Initialize DATA. */
68 core2i7_first_cycle_multipass_init (void *_data
)
70 ix86_first_cycle_multipass_data_t data
71 = (ix86_first_cycle_multipass_data_t
) _data
;
73 data
->ifetch_block_len
= 0;
74 data
->ifetch_block_n_insns
= 0;
75 data
->ready_try_change
= NULL
;
76 data
->ready_try_change_size
= 0;
79 /* Advancing the cycle; reset ifetch block counts. */
81 core2i7_dfa_post_advance_cycle (void)
83 ix86_first_cycle_multipass_data_t data
= ix86_first_cycle_multipass_data
;
85 gcc_assert (data
->ifetch_block_n_insns
<= core2i7_ifetch_block_max_insns
);
87 data
->ifetch_block_len
= 0;
88 data
->ifetch_block_n_insns
= 0;
91 /* Filter out insns from ready_try that the core will not be able to issue
92 on current cycle due to decoder. */
94 core2i7_first_cycle_multipass_filter_ready_try
95 (const_ix86_first_cycle_multipass_data_t data
,
96 signed char *ready_try
, int n_ready
, bool first_cycle_insn_p
)
103 if (ready_try
[n_ready
])
106 insn
= get_ready_element (n_ready
);
107 insn_size
= ix86_min_insn_size (insn
);
109 if (/* If this is a too long an insn for a secondary decoder ... */
111 && insn_size
> core2i7_secondary_decoder_max_insn_size
)
112 /* ... or it would not fit into the ifetch block ... */
113 || data
->ifetch_block_len
+ insn_size
> core2i7_ifetch_block_size
114 /* ... or the decoder is full already ... */
115 || data
->ifetch_block_n_insns
+ 1 > core2i7_ifetch_block_max_insns
)
116 /* ... mask the insn out. */
118 ready_try
[n_ready
] = 1;
120 if (data
->ready_try_change
)
121 bitmap_set_bit (data
->ready_try_change
, n_ready
);
126 /* Prepare for a new round of multipass lookahead scheduling. */
128 core2i7_first_cycle_multipass_begin (void *_data
,
129 signed char *ready_try
, int n_ready
,
130 bool first_cycle_insn_p
)
132 ix86_first_cycle_multipass_data_t data
133 = (ix86_first_cycle_multipass_data_t
) _data
;
134 const_ix86_first_cycle_multipass_data_t prev_data
135 = ix86_first_cycle_multipass_data
;
137 /* Restore the state from the end of the previous round. */
138 data
->ifetch_block_len
= prev_data
->ifetch_block_len
;
139 data
->ifetch_block_n_insns
= prev_data
->ifetch_block_n_insns
;
141 /* Filter instructions that cannot be issued on current cycle due to
142 decoder restrictions. */
143 core2i7_first_cycle_multipass_filter_ready_try (data
, ready_try
, n_ready
,
147 /* INSN is being issued in current solution. Account for its impact on
148 the decoder model. */
150 core2i7_first_cycle_multipass_issue (void *_data
,
151 signed char *ready_try
, int n_ready
,
152 rtx_insn
*insn
, const void *_prev_data
)
154 ix86_first_cycle_multipass_data_t data
155 = (ix86_first_cycle_multipass_data_t
) _data
;
156 const_ix86_first_cycle_multipass_data_t prev_data
157 = (const_ix86_first_cycle_multipass_data_t
) _prev_data
;
159 int insn_size
= ix86_min_insn_size (insn
);
161 data
->ifetch_block_len
= prev_data
->ifetch_block_len
+ insn_size
;
162 data
->ifetch_block_n_insns
= prev_data
->ifetch_block_n_insns
+ 1;
163 gcc_assert (data
->ifetch_block_len
<= core2i7_ifetch_block_size
164 && data
->ifetch_block_n_insns
<= core2i7_ifetch_block_max_insns
);
166 /* Allocate or resize the bitmap for storing INSN's effect on ready_try. */
167 if (!data
->ready_try_change
)
169 data
->ready_try_change
= sbitmap_alloc (n_ready
);
170 data
->ready_try_change_size
= n_ready
;
172 else if (data
->ready_try_change_size
< n_ready
)
174 data
->ready_try_change
= sbitmap_resize (data
->ready_try_change
,
176 data
->ready_try_change_size
= n_ready
;
178 bitmap_clear (data
->ready_try_change
);
180 /* Filter out insns from ready_try that the core will not be able to issue
181 on current cycle due to decoder. */
182 core2i7_first_cycle_multipass_filter_ready_try (data
, ready_try
, n_ready
,
186 /* Revert the effect on ready_try. */
188 core2i7_first_cycle_multipass_backtrack (const void *_data
,
189 signed char *ready_try
,
190 int n_ready ATTRIBUTE_UNUSED
)
192 const_ix86_first_cycle_multipass_data_t data
193 = (const_ix86_first_cycle_multipass_data_t
) _data
;
195 sbitmap_iterator sbi
;
197 gcc_assert (bitmap_last_set_bit (data
->ready_try_change
) < n_ready
);
198 EXECUTE_IF_SET_IN_BITMAP (data
->ready_try_change
, 0, i
, sbi
)
204 /* Save the result of multipass lookahead scheduling for the next round. */
206 core2i7_first_cycle_multipass_end (const void *_data
)
208 const_ix86_first_cycle_multipass_data_t data
209 = (const_ix86_first_cycle_multipass_data_t
) _data
;
210 ix86_first_cycle_multipass_data_t next_data
211 = ix86_first_cycle_multipass_data
;
215 next_data
->ifetch_block_len
= data
->ifetch_block_len
;
216 next_data
->ifetch_block_n_insns
= data
->ifetch_block_n_insns
;
220 /* Deallocate target data. */
222 core2i7_first_cycle_multipass_fini (void *_data
)
224 ix86_first_cycle_multipass_data_t data
225 = (ix86_first_cycle_multipass_data_t
) _data
;
227 if (data
->ready_try_change
)
229 sbitmap_free (data
->ready_try_change
);
230 data
->ready_try_change
= NULL
;
231 data
->ready_try_change_size
= 0;
236 ix86_core2i7_init_hooks (void)
238 targetm
.sched
.dfa_post_advance_cycle
239 = core2i7_dfa_post_advance_cycle
;
240 targetm
.sched
.first_cycle_multipass_init
241 = core2i7_first_cycle_multipass_init
;
242 targetm
.sched
.first_cycle_multipass_begin
243 = core2i7_first_cycle_multipass_begin
;
244 targetm
.sched
.first_cycle_multipass_issue
245 = core2i7_first_cycle_multipass_issue
;
246 targetm
.sched
.first_cycle_multipass_backtrack
247 = core2i7_first_cycle_multipass_backtrack
;
248 targetm
.sched
.first_cycle_multipass_end
249 = core2i7_first_cycle_multipass_end
;
250 targetm
.sched
.first_cycle_multipass_fini
251 = core2i7_first_cycle_multipass_fini
;
253 /* Set decoder parameters. */
254 core2i7_secondary_decoder_max_insn_size
= 8;
255 core2i7_ifetch_block_size
= 16;
256 core2i7_ifetch_block_max_insns
= 6;