Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/i386/x86-tune-sched-atom.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Scheduler hooks for IA-32 which implement atom+ specific logic. | |
2 Copyright (C) 1988-2017 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GCC. | |
5 | |
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) | |
9 any later version. | |
10 | |
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. | |
15 | |
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/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
23 #include "backend.h" | |
24 #include "rtl.h" | |
25 #include "tree.h" | |
26 #include "cfghooks.h" | |
27 #include "tm_p.h" | |
28 #include "insn-config.h" | |
29 #include "insn-attr.h" | |
30 #include "recog.h" | |
31 #include "target.h" | |
32 #include "rtl-iter.h" | |
33 #include "regset.h" | |
34 #include "sched-int.h" | |
35 | |
36 /* Try to reorder ready list to take advantage of Atom pipelined IMUL | |
37 execution. It is applied if | |
38 (1) IMUL instruction is on the top of list; | |
39 (2) There exists the only producer of independent IMUL instruction in | |
40 ready list. | |
41 Return index of IMUL producer if it was found and -1 otherwise. */ | |
42 static int | |
43 do_reorder_for_imul (rtx_insn **ready, int n_ready) | |
44 { | |
45 rtx_insn *insn; | |
46 rtx set, insn1, insn2; | |
47 sd_iterator_def sd_it; | |
48 dep_t dep; | |
49 int index = -1; | |
50 int i; | |
51 | |
52 if (!TARGET_BONNELL) | |
53 return index; | |
54 | |
55 /* Check that IMUL instruction is on the top of ready list. */ | |
56 insn = ready[n_ready - 1]; | |
57 set = single_set (insn); | |
58 if (!set) | |
59 return index; | |
60 if (!(GET_CODE (SET_SRC (set)) == MULT | |
61 && GET_MODE (SET_SRC (set)) == SImode)) | |
62 return index; | |
63 | |
64 /* Search for producer of independent IMUL instruction. */ | |
65 for (i = n_ready - 2; i >= 0; i--) | |
66 { | |
67 insn = ready[i]; | |
68 if (!NONDEBUG_INSN_P (insn)) | |
69 continue; | |
70 /* Skip IMUL instruction. */ | |
71 insn2 = PATTERN (insn); | |
72 if (GET_CODE (insn2) == PARALLEL) | |
73 insn2 = XVECEXP (insn2, 0, 0); | |
74 if (GET_CODE (insn2) == SET | |
75 && GET_CODE (SET_SRC (insn2)) == MULT | |
76 && GET_MODE (SET_SRC (insn2)) == SImode) | |
77 continue; | |
78 | |
79 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep) | |
80 { | |
81 rtx con; | |
82 con = DEP_CON (dep); | |
83 if (!NONDEBUG_INSN_P (con)) | |
84 continue; | |
85 insn1 = PATTERN (con); | |
86 if (GET_CODE (insn1) == PARALLEL) | |
87 insn1 = XVECEXP (insn1, 0, 0); | |
88 | |
89 if (GET_CODE (insn1) == SET | |
90 && GET_CODE (SET_SRC (insn1)) == MULT | |
91 && GET_MODE (SET_SRC (insn1)) == SImode) | |
92 { | |
93 sd_iterator_def sd_it1; | |
94 dep_t dep1; | |
95 /* Check if there is no other dependee for IMUL. */ | |
96 index = i; | |
97 FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1) | |
98 { | |
99 rtx pro; | |
100 pro = DEP_PRO (dep1); | |
101 if (!NONDEBUG_INSN_P (pro)) | |
102 continue; | |
103 if (pro != insn) | |
104 index = -1; | |
105 } | |
106 if (index >= 0) | |
107 break; | |
108 } | |
109 } | |
110 if (index >= 0) | |
111 break; | |
112 } | |
113 return index; | |
114 } | |
115 | |
116 /* Try to find the best candidate on the top of ready list if two insns | |
117 have the same priority - candidate is best if its dependees were | |
118 scheduled earlier. Applied for Silvermont only. | |
119 Return true if top 2 insns must be interchanged. */ | |
120 static bool | |
121 swap_top_of_ready_list (rtx_insn **ready, int n_ready) | |
122 { | |
123 rtx_insn *top = ready[n_ready - 1]; | |
124 rtx_insn *next = ready[n_ready - 2]; | |
125 rtx set; | |
126 sd_iterator_def sd_it; | |
127 dep_t dep; | |
128 int clock1 = -1; | |
129 int clock2 = -1; | |
130 #define INSN_TICK(INSN) (HID (INSN)->tick) | |
131 | |
132 if (!TARGET_SILVERMONT && !TARGET_INTEL) | |
133 return false; | |
134 | |
135 if (!NONDEBUG_INSN_P (top)) | |
136 return false; | |
137 if (!NONJUMP_INSN_P (top)) | |
138 return false; | |
139 if (!NONDEBUG_INSN_P (next)) | |
140 return false; | |
141 if (!NONJUMP_INSN_P (next)) | |
142 return false; | |
143 set = single_set (top); | |
144 if (!set) | |
145 return false; | |
146 set = single_set (next); | |
147 if (!set) | |
148 return false; | |
149 | |
150 if (INSN_PRIORITY_KNOWN (top) && INSN_PRIORITY_KNOWN (next)) | |
151 { | |
152 if (INSN_PRIORITY (top) != INSN_PRIORITY (next)) | |
153 return false; | |
154 /* Determine winner more precise. */ | |
155 FOR_EACH_DEP (top, SD_LIST_RES_BACK, sd_it, dep) | |
156 { | |
157 rtx pro; | |
158 pro = DEP_PRO (dep); | |
159 if (!NONDEBUG_INSN_P (pro)) | |
160 continue; | |
161 if (INSN_TICK (pro) > clock1) | |
162 clock1 = INSN_TICK (pro); | |
163 } | |
164 FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep) | |
165 { | |
166 rtx pro; | |
167 pro = DEP_PRO (dep); | |
168 if (!NONDEBUG_INSN_P (pro)) | |
169 continue; | |
170 if (INSN_TICK (pro) > clock2) | |
171 clock2 = INSN_TICK (pro); | |
172 } | |
173 | |
174 if (clock1 == clock2) | |
175 { | |
176 /* Determine winner - load must win. */ | |
177 enum attr_memory memory1, memory2; | |
178 memory1 = get_attr_memory (top); | |
179 memory2 = get_attr_memory (next); | |
180 if (memory2 == MEMORY_LOAD && memory1 != MEMORY_LOAD) | |
181 return true; | |
182 } | |
183 return (bool) (clock2 < clock1); | |
184 } | |
185 return false; | |
186 #undef INSN_TICK | |
187 } | |
188 | |
189 /* Perform possible reodering of ready list for Atom/Silvermont only. | |
190 Return issue rate. */ | |
191 int | |
192 ix86_atom_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready, | |
193 int *pn_ready, int clock_var) | |
194 { | |
195 int issue_rate = -1; | |
196 int n_ready = *pn_ready; | |
197 int i; | |
198 rtx_insn *insn; | |
199 int index = -1; | |
200 | |
201 /* Set up issue rate. */ | |
202 issue_rate = ix86_issue_rate (); | |
203 | |
204 /* Do reodering for BONNELL/SILVERMONT only. */ | |
205 if (!TARGET_BONNELL && !TARGET_SILVERMONT && !TARGET_INTEL) | |
206 return issue_rate; | |
207 | |
208 /* Nothing to do if ready list contains only 1 instruction. */ | |
209 if (n_ready <= 1) | |
210 return issue_rate; | |
211 | |
212 /* Do reodering for post-reload scheduler only. */ | |
213 if (!reload_completed) | |
214 return issue_rate; | |
215 | |
216 if ((index = do_reorder_for_imul (ready, n_ready)) >= 0) | |
217 { | |
218 if (sched_verbose > 1) | |
219 fprintf (dump, ";;\tatom sched_reorder: put %d insn on top\n", | |
220 INSN_UID (ready[index])); | |
221 | |
222 /* Put IMUL producer (ready[index]) at the top of ready list. */ | |
223 insn = ready[index]; | |
224 for (i = index; i < n_ready - 1; i++) | |
225 ready[i] = ready[i + 1]; | |
226 ready[n_ready - 1] = insn; | |
227 return issue_rate; | |
228 } | |
229 | |
230 /* Skip selective scheduling since HID is not populated in it. */ | |
231 if (clock_var != 0 | |
232 && !sel_sched_p () | |
233 && swap_top_of_ready_list (ready, n_ready)) | |
234 { | |
235 if (sched_verbose > 1) | |
236 fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n", | |
237 INSN_UID (ready[n_ready - 1]), INSN_UID (ready[n_ready - 2])); | |
238 /* Swap 2 top elements of ready list. */ | |
239 insn = ready[n_ready - 1]; | |
240 ready[n_ready - 1] = ready[n_ready - 2]; | |
241 ready[n_ready - 2] = insn; | |
242 } | |
243 return issue_rate; | |
244 } |