]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/sel-sched.c
sel-sched.c (choose_best_reg_1): Loop over all regs for mode.
[thirdparty/gcc.git] / gcc / sel-sched.c
CommitLineData
e855c69d 1/* Instruction scheduling pass. Selective scheduler and pipeliner.
66647d44 2 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
e855c69d
AB
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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 "tm.h"
24#include "toplev.h"
25#include "rtl.h"
26#include "tm_p.h"
27#include "hard-reg-set.h"
28#include "regs.h"
29#include "function.h"
30#include "flags.h"
31#include "insn-config.h"
32#include "insn-attr.h"
33#include "except.h"
34#include "toplev.h"
35#include "recog.h"
36#include "params.h"
37#include "target.h"
38#include "output.h"
39#include "timevar.h"
40#include "tree-pass.h"
41#include "sched-int.h"
42#include "ggc.h"
43#include "tree.h"
44#include "vec.h"
45#include "langhooks.h"
46#include "rtlhooks-def.h"
47#include "output.h"
48
49#ifdef INSN_SCHEDULING
50#include "sel-sched-ir.h"
51#include "sel-sched-dump.h"
52#include "sel-sched.h"
53#include "dbgcnt.h"
54
55/* Implementation of selective scheduling approach.
56 The below implementation follows the original approach with the following
57 changes:
58
b8698a0f 59 o the scheduler works after register allocation (but can be also tuned
e855c69d
AB
60 to work before RA);
61 o some instructions are not copied or register renamed;
62 o conditional jumps are not moved with code duplication;
63 o several jumps in one parallel group are not supported;
64 o when pipelining outer loops, code motion through inner loops
65 is not supported;
66 o control and data speculation are supported;
67 o some improvements for better compile time/performance were made.
68
69 Terminology
70 ===========
71
b8698a0f
L
72 A vinsn, or virtual insn, is an insn with additional data characterizing
73 insn pattern, such as LHS, RHS, register sets used/set/clobbered, etc.
74 Vinsns also act as smart pointers to save memory by reusing them in
e855c69d
AB
75 different expressions. A vinsn is described by vinsn_t type.
76
77 An expression is a vinsn with additional data characterizing its properties
b8698a0f 78 at some point in the control flow graph. The data may be its usefulness,
e855c69d
AB
79 priority, speculative status, whether it was renamed/subsituted, etc.
80 An expression is described by expr_t type.
81
b8698a0f 82 Availability set (av_set) is a set of expressions at a given control flow
e855c69d 83 point. It is represented as av_set_t. The expressions in av sets are kept
b8698a0f 84 sorted in the terms of expr_greater_p function. It allows to truncate
e855c69d 85 the set while leaving the best expressions.
b8698a0f 86
e855c69d
AB
87 A fence is a point through which code motion is prohibited. On each step,
88 we gather a parallel group of insns at a fence. It is possible to have
89 multiple fences. A fence is represented via fence_t.
90
91 A boundary is the border between the fence group and the rest of the code.
92 Currently, we never have more than one boundary per fence, as we finalize
b8698a0f 93 the fence group when a jump is scheduled. A boundary is represented
e855c69d
AB
94 via bnd_t.
95
96 High-level overview
97 ===================
98
99 The scheduler finds regions to schedule, schedules each one, and finalizes.
b8698a0f 100 The regions are formed starting from innermost loops, so that when the inner
e855c69d 101 loop is pipelined, its prologue can be scheduled together with yet unprocessed
b8698a0f 102 outer loop. The rest of acyclic regions are found using extend_rgns:
e855c69d 103 the blocks that are not yet allocated to any regions are traversed in top-down
b8698a0f 104 order, and a block is added to a region to which all its predecessors belong;
e855c69d
AB
105 otherwise, the block starts its own region.
106
107 The main scheduling loop (sel_sched_region_2) consists of just
108 scheduling on each fence and updating fences. For each fence,
109 we fill a parallel group of insns (fill_insns) until some insns can be added.
b8698a0f
L
110 First, we compute available exprs (av-set) at the boundary of the current
111 group. Second, we choose the best expression from it. If the stall is
e855c69d 112 required to schedule any of the expressions, we advance the current cycle
b8698a0f 113 appropriately. So, the final group does not exactly correspond to a VLIW
e855c69d
AB
114 word. Third, we move the chosen expression to the boundary (move_op)
115 and update the intermediate av sets and liveness sets. We quit fill_insns
116 when either no insns left for scheduling or we have scheduled enough insns
b8698a0f 117 so we feel like advancing a scheduling point.
e855c69d
AB
118
119 Computing available expressions
120 ===============================
121
122 The computation (compute_av_set) is a bottom-up traversal. At each insn,
b8698a0f
L
123 we're moving the union of its successors' sets through it via
124 moveup_expr_set. The dependent expressions are removed. Local
125 transformations (substitution, speculation) are applied to move more
e855c69d
AB
126 exprs. Then the expr corresponding to the current insn is added.
127 The result is saved on each basic block header.
128
129 When traversing the CFG, we're moving down for no more than max_ws insns.
130 Also, we do not move down to ineligible successors (is_ineligible_successor),
131 which include moving along a back-edge, moving to already scheduled code,
b8698a0f 132 and moving to another fence. The first two restrictions are lifted during
e855c69d
AB
133 pipelining, which allows us to move insns along a back-edge. We always have
134 an acyclic region for scheduling because we forbid motion through fences.
135
136 Choosing the best expression
137 ============================
138
139 We sort the final availability set via sel_rank_for_schedule, then we remove
140 expressions which are not yet ready (tick_check_p) or which dest registers
b8698a0f
L
141 cannot be used. For some of them, we choose another register via
142 find_best_reg. To do this, we run find_used_regs to calculate the set of
e855c69d
AB
143 registers which cannot be used. The find_used_regs function performs
144 a traversal of code motion paths for an expr. We consider for renaming
b8698a0f 145 only registers which are from the same regclass as the original one and
e855c69d
AB
146 using which does not interfere with any live ranges. Finally, we convert
147 the resulting set to the ready list format and use max_issue and reorder*
148 hooks similarly to the Haifa scheduler.
149
150 Scheduling the best expression
151 ==============================
152
b8698a0f 153 We run the move_op routine to perform the same type of code motion paths
e855c69d
AB
154 traversal as in find_used_regs. (These are working via the same driver,
155 code_motion_path_driver.) When moving down the CFG, we look for original
b8698a0f 156 instruction that gave birth to a chosen expression. We undo
e855c69d 157 the transformations performed on an expression via the history saved in it.
b8698a0f
L
158 When found, we remove the instruction or leave a reg-reg copy/speculation
159 check if needed. On a way up, we insert bookkeeping copies at each join
160 point. If a copy is not needed, it will be removed later during this
e855c69d
AB
161 traversal. We update the saved av sets and liveness sets on the way up, too.
162
163 Finalizing the schedule
164 =======================
165
b8698a0f
L
166 When pipelining, we reschedule the blocks from which insns were pipelined
167 to get a tighter schedule. On Itanium, we also perform bundling via
168 the same routine from ia64.c.
e855c69d
AB
169
170 Dependence analysis changes
171 ===========================
172
173 We augmented the sched-deps.c with hooks that get called when a particular
174 dependence is found in a particular part of an insn. Using these hooks, we
175 can do several actions such as: determine whether an insn can be moved through
b8698a0f
L
176 another (has_dependence_p, moveup_expr); find out whether an insn can be
177 scheduled on the current cycle (tick_check_p); find out registers that
178 are set/used/clobbered by an insn and find out all the strange stuff that
179 restrict its movement, like SCHED_GROUP_P or CANT_MOVE (done in
e855c69d
AB
180 init_global_and_expr_for_insn).
181
182 Initialization changes
183 ======================
184
b8698a0f 185 There are parts of haifa-sched.c, sched-deps.c, and sched-rgn.c that are
e855c69d 186 reused in all of the schedulers. We have split up the initialization of data
b8698a0f 187 of such parts into different functions prefixed with scheduler type and
e855c69d
AB
188 postfixed with the type of data initialized: {,sel_,haifa_}sched_{init,finish},
189 sched_rgn_init/finish, sched_deps_init/finish, sched_init_{luids/bbs}, etc.
b8698a0f
L
190 The same splitting is done with current_sched_info structure:
191 dependence-related parts are in sched_deps_info, common part is in
e855c69d 192 common_sched_info, and haifa/sel/etc part is in current_sched_info.
b8698a0f 193
e855c69d
AB
194 Target contexts
195 ===============
196
197 As we now have multiple-point scheduling, this would not work with backends
b8698a0f
L
198 which save some of the scheduler state to use it in the target hooks.
199 For this purpose, we introduce a concept of target contexts, which
e855c69d
AB
200 encapsulate such information. The backend should implement simple routines
201 of allocating/freeing/setting such a context. The scheduler calls these
202 as target hooks and handles the target context as an opaque pointer (similar
203 to the DFA state type, state_t).
204
205 Various speedups
206 ================
207
208 As the correct data dependence graph is not supported during scheduling (which
b8698a0f
L
209 is to be changed in mid-term), we cache as much of the dependence analysis
210 results as possible to avoid reanalyzing. This includes: bitmap caches on
211 each insn in stream of the region saying yes/no for a query with a pair of
e855c69d
AB
212 UIDs; hashtables with the previously done transformations on each insn in
213 stream; a vector keeping a history of transformations on each expr.
214
215 Also, we try to minimize the dependence context used on each fence to check
216 whether the given expression is ready for scheduling by removing from it
b8698a0f 217 insns that are definitely completed the execution. The results of
e855c69d
AB
218 tick_check_p checks are also cached in a vector on each fence.
219
b8698a0f 220 We keep a valid liveness set on each insn in a region to avoid the high
e855c69d
AB
221 cost of recomputation on large basic blocks.
222
223 Finally, we try to minimize the number of needed updates to the availability
b8698a0f 224 sets. The updates happen in two cases: when fill_insns terminates,
e855c69d
AB
225 we advance all fences and increase the stage number to show that the region
226 has changed and the sets are to be recomputed; and when the next iteration
227 of a loop in fill_insns happens (but this one reuses the saved av sets
228 on bb headers.) Thus, we try to break the fill_insns loop only when
229 "significant" number of insns from the current scheduling window was
230 scheduled. This should be made a target param.
b8698a0f 231
e855c69d
AB
232
233 TODO: correctly support the data dependence graph at all stages and get rid
234 of all caches. This should speed up the scheduler.
235 TODO: implement moving cond jumps with bookkeeping copies on both targets.
236 TODO: tune the scheduler before RA so it does not create too much pseudos.
237
238
239 References:
240 S.-M. Moon and K. Ebcioglu. Parallelizing nonnumerical code with
b8698a0f
L
241 selective scheduling and software pipelining.
242 ACM TOPLAS, Vol 19, No. 6, pages 853--898, Nov. 1997.
e855c69d 243
b8698a0f
L
244 Andrey Belevantsev, Maxim Kuvyrkov, Vladimir Makarov, Dmitry Melnik,
245 and Dmitry Zhurikhin. An interblock VLIW-targeted instruction scheduler
e855c69d
AB
246 for GCC. In Proceedings of GCC Developers' Summit 2006.
247
b8698a0f 248 Arutyun Avetisyan, Andrey Belevantsev, and Dmitry Melnik. GCC Instruction
e855c69d
AB
249 Scheduler and Software Pipeliner on the Itanium Platform. EPIC-7 Workshop.
250 http://rogue.colorado.edu/EPIC7/.
b8698a0f 251
e855c69d
AB
252*/
253
254/* True when pipelining is enabled. */
255bool pipelining_p;
256
257/* True if bookkeeping is enabled. */
258bool bookkeeping_p;
259
260/* Maximum number of insns that are eligible for renaming. */
261int max_insns_to_rename;
262\f
263
264/* Definitions of local types and macros. */
265
266/* Represents possible outcomes of moving an expression through an insn. */
b8698a0f
L
267enum MOVEUP_EXPR_CODE
268 {
e855c69d 269 /* The expression is not changed. */
b8698a0f 270 MOVEUP_EXPR_SAME,
e855c69d
AB
271
272 /* Not changed, but requires a new destination register. */
b8698a0f 273 MOVEUP_EXPR_AS_RHS,
e855c69d
AB
274
275 /* Cannot be moved. */
b8698a0f 276 MOVEUP_EXPR_NULL,
e855c69d
AB
277
278 /* Changed (substituted or speculated). */
b8698a0f 279 MOVEUP_EXPR_CHANGED
e855c69d
AB
280 };
281
282/* The container to be passed into rtx search & replace functions. */
283struct rtx_search_arg
284{
285 /* What we are searching for. */
286 rtx x;
287
288 /* The occurence counter. */
289 int n;
290};
291
292typedef struct rtx_search_arg *rtx_search_arg_p;
293
b8698a0f 294/* This struct contains precomputed hard reg sets that are needed when
e855c69d 295 computing registers available for renaming. */
b8698a0f 296struct hard_regs_data
e855c69d 297{
b8698a0f 298 /* For every mode, this stores registers available for use with
e855c69d
AB
299 that mode. */
300 HARD_REG_SET regs_for_mode[NUM_MACHINE_MODES];
301
302 /* True when regs_for_mode[mode] is initialized. */
303 bool regs_for_mode_ok[NUM_MACHINE_MODES];
304
305 /* For every register, it has regs that are ok to rename into it.
306 The register in question is always set. If not, this means
307 that the whole set is not computed yet. */
308 HARD_REG_SET regs_for_rename[FIRST_PSEUDO_REGISTER];
309
b8698a0f 310 /* For every mode, this stores registers not available due to
e855c69d
AB
311 call clobbering. */
312 HARD_REG_SET regs_for_call_clobbered[NUM_MACHINE_MODES];
313
314 /* All registers that are used or call used. */
315 HARD_REG_SET regs_ever_used;
316
317#ifdef STACK_REGS
318 /* Stack registers. */
319 HARD_REG_SET stack_regs;
320#endif
321};
322
323/* Holds the results of computation of available for renaming and
324 unavailable hard registers. */
325struct reg_rename
326{
327 /* These are unavailable due to calls crossing, globalness, etc. */
328 HARD_REG_SET unavailable_hard_regs;
329
330 /* These are *available* for renaming. */
331 HARD_REG_SET available_for_renaming;
332
333 /* Whether this code motion path crosses a call. */
334 bool crosses_call;
335};
336
b8698a0f 337/* A global structure that contains the needed information about harg
e855c69d
AB
338 regs. */
339static struct hard_regs_data sel_hrd;
340\f
341
b8698a0f
L
342/* This structure holds local data used in code_motion_path_driver hooks on
343 the same or adjacent levels of recursion. Here we keep those parameters
344 that are not used in code_motion_path_driver routine itself, but only in
345 its hooks. Moreover, all parameters that can be modified in hooks are
346 in this structure, so all other parameters passed explicitly to hooks are
e855c69d
AB
347 read-only. */
348struct cmpd_local_params
349{
350 /* Local params used in move_op_* functions. */
351
352 /* Edges for bookkeeping generation. */
353 edge e1, e2;
354
355 /* C_EXPR merged from all successors and locally allocated temporary C_EXPR. */
356 expr_t c_expr_merged, c_expr_local;
357
358 /* Local params used in fur_* functions. */
359 /* Copy of the ORIGINAL_INSN list, stores the original insns already
360 found before entering the current level of code_motion_path_driver. */
361 def_list_t old_original_insns;
362
363 /* Local params used in move_op_* functions. */
b8698a0f 364 /* True when we have removed last insn in the block which was
e855c69d
AB
365 also a boundary. Do not update anything or create bookkeeping copies. */
366 BOOL_BITFIELD removed_last_insn : 1;
367};
368
369/* Stores the static parameters for move_op_* calls. */
370struct moveop_static_params
371{
372 /* Destination register. */
373 rtx dest;
374
375 /* Current C_EXPR. */
376 expr_t c_expr;
377
378 /* An UID of expr_vliw which is to be moved up. If we find other exprs,
379 they are to be removed. */
380 int uid;
381
382#ifdef ENABLE_CHECKING
383 /* This is initialized to the insn on which the driver stopped its traversal. */
384 insn_t failed_insn;
385#endif
386
387 /* True if we scheduled an insn with different register. */
388 bool was_renamed;
389};
390
391/* Stores the static parameters for fur_* calls. */
392struct fur_static_params
393{
394 /* Set of registers unavailable on the code motion path. */
395 regset used_regs;
396
397 /* Pointer to the list of original insns definitions. */
398 def_list_t *original_insns;
399
400 /* True if a code motion path contains a CALL insn. */
401 bool crosses_call;
402};
403
404typedef struct fur_static_params *fur_static_params_p;
405typedef struct cmpd_local_params *cmpd_local_params_p;
406typedef struct moveop_static_params *moveop_static_params_p;
407
408/* Set of hooks and parameters that determine behaviour specific to
409 move_op or find_used_regs functions. */
410struct code_motion_path_driver_info_def
411{
412 /* Called on enter to the basic block. */
413 int (*on_enter) (insn_t, cmpd_local_params_p, void *, bool);
414
415 /* Called when original expr is found. */
416 void (*orig_expr_found) (insn_t, expr_t, cmpd_local_params_p, void *);
417
418 /* Called while descending current basic block if current insn is not
419 the original EXPR we're searching for. */
420 bool (*orig_expr_not_found) (insn_t, av_set_t, void *);
421
422 /* Function to merge C_EXPRes from different successors. */
423 void (*merge_succs) (insn_t, insn_t, int, cmpd_local_params_p, void *);
424
425 /* Function to finalize merge from different successors and possibly
426 deallocate temporary data structures used for merging. */
427 void (*after_merge_succs) (cmpd_local_params_p, void *);
428
429 /* Called on the backward stage of recursion to do moveup_expr.
430 Used only with move_op_*. */
431 void (*ascend) (insn_t, void *);
432
b8698a0f 433 /* Called on the ascending pass, before returning from the current basic
e855c69d
AB
434 block or from the whole traversal. */
435 void (*at_first_insn) (insn_t, cmpd_local_params_p, void *);
436
b8698a0f 437 /* When processing successors in move_op we need only descend into
e855c69d
AB
438 SUCCS_NORMAL successors, while in find_used_regs we need SUCCS_ALL. */
439 int succ_flags;
440
441 /* The routine name to print in dumps ("move_op" of "find_used_regs"). */
442 const char *routine_name;
443};
444
445/* Global pointer to current hooks, either points to MOVE_OP_HOOKS or
446 FUR_HOOKS. */
447struct code_motion_path_driver_info_def *code_motion_path_driver_info;
448
449/* Set of hooks for performing move_op and find_used_regs routines with
450 code_motion_path_driver. */
c32e2175 451extern struct code_motion_path_driver_info_def move_op_hooks, fur_hooks;
e855c69d 452
b8698a0f
L
453/* True if/when we want to emulate Haifa scheduler in the common code.
454 This is used in sched_rgn_local_init and in various places in
e855c69d
AB
455 sched-deps.c. */
456int sched_emulate_haifa_p;
457
458/* GLOBAL_LEVEL is used to discard information stored in basic block headers
459 av_sets. Av_set of bb header is valid if its (bb header's) level is equal
460 to GLOBAL_LEVEL. And invalid if lesser. This is primarily used to advance
461 scheduling window. */
462int global_level;
463
464/* Current fences. */
465flist_t fences;
466
467/* True when separable insns should be scheduled as RHSes. */
468static bool enable_schedule_as_rhs_p;
469
470/* Used in verify_target_availability to assert that target reg is reported
471 unavailabile by both TARGET_UNAVAILABLE and find_used_regs only if
b8698a0f 472 we haven't scheduled anything on the previous fence.
e855c69d 473 if scheduled_something_on_previous_fence is true, TARGET_UNAVAILABLE can
b8698a0f 474 have more conservative value than the one returned by the
e855c69d
AB
475 find_used_regs, thus we shouldn't assert that these values are equal. */
476static bool scheduled_something_on_previous_fence;
477
478/* All newly emitted insns will have their uids greater than this value. */
479static int first_emitted_uid;
480
481/* Set of basic blocks that are forced to start new ebbs. This is a subset
482 of all the ebb heads. */
483static bitmap_head _forced_ebb_heads;
484bitmap_head *forced_ebb_heads = &_forced_ebb_heads;
485
486/* Blocks that need to be rescheduled after pipelining. */
487bitmap blocks_to_reschedule = NULL;
488
489/* True when the first lv set should be ignored when updating liveness. */
490static bool ignore_first = false;
491
492/* Number of insns max_issue has initialized data structures for. */
493static int max_issue_size = 0;
494
495/* Whether we can issue more instructions. */
496static int can_issue_more;
497
498/* Maximum software lookahead window size, reduced when rescheduling after
499 pipelining. */
500static int max_ws;
501
502/* Number of insns scheduled in current region. */
503static int num_insns_scheduled;
504
505/* A vector of expressions is used to be able to sort them. */
506DEF_VEC_P(expr_t);
507DEF_VEC_ALLOC_P(expr_t,heap);
508static VEC(expr_t, heap) *vec_av_set = NULL;
509
510/* A vector of vinsns is used to hold temporary lists of vinsns. */
511DEF_VEC_P(vinsn_t);
512DEF_VEC_ALLOC_P(vinsn_t,heap);
513typedef VEC(vinsn_t, heap) *vinsn_vec_t;
514
515/* This vector has the exprs which may still present in av_sets, but actually
516 can't be moved up due to bookkeeping created during code motion to another
517 fence. See comment near the call to update_and_record_unavailable_insns
518 for the detailed explanations. */
519static vinsn_vec_t vec_bookkeeping_blocked_vinsns = NULL;
520
b8698a0f 521/* This vector has vinsns which are scheduled with renaming on the first fence
e855c69d
AB
522 and then seen on the second. For expressions with such vinsns, target
523 availability information may be wrong. */
524static vinsn_vec_t vec_target_unavailable_vinsns = NULL;
525
526/* Vector to store temporary nops inserted in move_op to prevent removal
527 of empty bbs. */
528DEF_VEC_P(insn_t);
529DEF_VEC_ALLOC_P(insn_t,heap);
530static VEC(insn_t, heap) *vec_temp_moveop_nops = NULL;
531
b8698a0f
L
532/* These bitmaps record original instructions scheduled on the current
533 iteration and bookkeeping copies created by them. */
e855c69d
AB
534static bitmap current_originators = NULL;
535static bitmap current_copies = NULL;
536
537/* This bitmap marks the blocks visited by code_motion_path_driver so we don't
538 visit them afterwards. */
539static bitmap code_motion_visited_blocks = NULL;
540
541/* Variables to accumulate different statistics. */
542
543/* The number of bookkeeping copies created. */
544static int stat_bookkeeping_copies;
545
546/* The number of insns that required bookkeeiping for their scheduling. */
547static int stat_insns_needed_bookkeeping;
548
549/* The number of insns that got renamed. */
550static int stat_renamed_scheduled;
551
552/* The number of substitutions made during scheduling. */
553static int stat_substitutions_total;
554\f
555
556/* Forward declarations of static functions. */
557static bool rtx_ok_for_substitution_p (rtx, rtx);
558static int sel_rank_for_schedule (const void *, const void *);
559static av_set_t find_sequential_best_exprs (bnd_t, expr_t, bool);
b5b8b0ac 560static basic_block find_block_for_bookkeeping (edge e1, edge e2, bool lax);
e855c69d
AB
561
562static rtx get_dest_from_orig_ops (av_set_t);
563static basic_block generate_bookkeeping_insn (expr_t, edge, edge);
b8698a0f 564static bool find_used_regs (insn_t, av_set_t, regset, struct reg_rename *,
e855c69d 565 def_list_t *);
72a54528
AM
566static bool move_op (insn_t, av_set_t, expr_t, rtx, expr_t, bool*);
567static int code_motion_path_driver (insn_t, av_set_t, ilist_t,
568 cmpd_local_params_p, void *);
e855c69d
AB
569static void sel_sched_region_1 (void);
570static void sel_sched_region_2 (int);
571static av_set_t compute_av_set_inside_bb (insn_t, ilist_t, int, bool);
572
573static void debug_state (state_t);
574\f
575
576/* Functions that work with fences. */
577
578/* Advance one cycle on FENCE. */
579static void
580advance_one_cycle (fence_t fence)
581{
582 unsigned i;
583 int cycle;
584 rtx insn;
b8698a0f 585
e855c69d
AB
586 advance_state (FENCE_STATE (fence));
587 cycle = ++FENCE_CYCLE (fence);
588 FENCE_ISSUED_INSNS (fence) = 0;
589 FENCE_STARTS_CYCLE_P (fence) = 1;
590 can_issue_more = issue_rate;
136e01a3 591 FENCE_ISSUE_MORE (fence) = can_issue_more;
e855c69d
AB
592
593 for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); )
594 {
595 if (INSN_READY_CYCLE (insn) < cycle)
596 {
597 remove_from_deps (FENCE_DC (fence), insn);
598 VEC_unordered_remove (rtx, FENCE_EXECUTING_INSNS (fence), i);
599 continue;
600 }
601 i++;
602 }
603 if (sched_verbose >= 2)
604 {
605 sel_print ("Finished a cycle. Current cycle = %d\n", FENCE_CYCLE (fence));
606 debug_state (FENCE_STATE (fence));
607 }
608}
609
610/* Returns true when SUCC in a fallthru bb of INSN, possibly
611 skipping empty basic blocks. */
612static bool
613in_fallthru_bb_p (rtx insn, rtx succ)
614{
615 basic_block bb = BLOCK_FOR_INSN (insn);
616
617 if (bb == BLOCK_FOR_INSN (succ))
618 return true;
619
620 if (find_fallthru_edge (bb))
621 bb = find_fallthru_edge (bb)->dest;
622 else
623 return false;
624
625 while (sel_bb_empty_p (bb))
626 bb = bb->next_bb;
627
628 return bb == BLOCK_FOR_INSN (succ);
629}
630
b8698a0f 631/* Construct successor fences from OLD_FENCEs and put them in NEW_FENCES.
e855c69d
AB
632 When a successor will continue a ebb, transfer all parameters of a fence
633 to the new fence. ORIG_MAX_SEQNO is the maximal seqno before this round
634 of scheduling helping to distinguish between the old and the new code. */
635static void
636extract_new_fences_from (flist_t old_fences, flist_tail_t new_fences,
637 int orig_max_seqno)
638{
639 bool was_here_p = false;
640 insn_t insn = NULL_RTX;
641 insn_t succ;
642 succ_iterator si;
643 ilist_iterator ii;
644 fence_t fence = FLIST_FENCE (old_fences);
645 basic_block bb;
646
647 /* Get the only element of FENCE_BNDS (fence). */
648 FOR_EACH_INSN (insn, ii, FENCE_BNDS (fence))
649 {
650 gcc_assert (!was_here_p);
651 was_here_p = true;
652 }
653 gcc_assert (was_here_p && insn != NULL_RTX);
654
b8698a0f 655 /* When in the "middle" of the block, just move this fence
e855c69d
AB
656 to the new list. */
657 bb = BLOCK_FOR_INSN (insn);
658 if (! sel_bb_end_p (insn)
b8698a0f 659 || (single_succ_p (bb)
e855c69d
AB
660 && single_pred_p (single_succ (bb))))
661 {
662 insn_t succ;
663
b8698a0f 664 succ = (sel_bb_end_p (insn)
e855c69d
AB
665 ? sel_bb_head (single_succ (bb))
666 : NEXT_INSN (insn));
667
b8698a0f 668 if (INSN_SEQNO (succ) > 0
e855c69d
AB
669 && INSN_SEQNO (succ) <= orig_max_seqno
670 && INSN_SCHED_TIMES (succ) <= 0)
671 {
672 FENCE_INSN (fence) = succ;
673 move_fence_to_fences (old_fences, new_fences);
674
675 if (sched_verbose >= 1)
b8698a0f 676 sel_print ("Fence %d continues as %d[%d] (state continue)\n",
e855c69d
AB
677 INSN_UID (insn), INSN_UID (succ), BLOCK_NUM (succ));
678 }
679 return;
680 }
681
682 /* Otherwise copy fence's structures to (possibly) multiple successors. */
683 FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
684 {
685 int seqno = INSN_SEQNO (succ);
686
687 if (0 < seqno && seqno <= orig_max_seqno
688 && (pipelining_p || INSN_SCHED_TIMES (succ) <= 0))
689 {
690 bool b = (in_same_ebb_p (insn, succ)
b8698a0f 691 || in_fallthru_bb_p (insn, succ));
e855c69d
AB
692
693 if (sched_verbose >= 1)
b8698a0f
L
694 sel_print ("Fence %d continues as %d[%d] (state %s)\n",
695 INSN_UID (insn), INSN_UID (succ),
e855c69d
AB
696 BLOCK_NUM (succ), b ? "continue" : "reset");
697
698 if (b)
699 add_dirty_fence_to_fences (new_fences, succ, fence);
700 else
701 {
702 /* Mark block of the SUCC as head of the new ebb. */
703 bitmap_set_bit (forced_ebb_heads, BLOCK_NUM (succ));
704 add_clean_fence_to_fences (new_fences, succ, fence);
705 }
706 }
707 }
708}
709\f
710
711/* Functions to support substitution. */
712
b8698a0f
L
713/* Returns whether INSN with dependence status DS is eligible for
714 substitution, i.e. it's a copy operation x := y, and RHS that is
e855c69d
AB
715 moved up through this insn should be substituted. */
716static bool
717can_substitute_through_p (insn_t insn, ds_t ds)
718{
719 /* We can substitute only true dependencies. */
720 if ((ds & DEP_OUTPUT)
721 || (ds & DEP_ANTI)
722 || ! INSN_RHS (insn)
723 || ! INSN_LHS (insn))
724 return false;
725
b8698a0f 726 /* Now we just need to make sure the INSN_RHS consists of only one
e855c69d 727 simple REG rtx. */
b8698a0f 728 if (REG_P (INSN_LHS (insn))
e855c69d 729 && REG_P (INSN_RHS (insn)))
b8698a0f 730 return true;
e855c69d
AB
731 return false;
732}
733
b8698a0f 734/* Substitute all occurences of INSN's destination in EXPR' vinsn with INSN's
e855c69d
AB
735 source (if INSN is eligible for substitution). Returns TRUE if
736 substitution was actually performed, FALSE otherwise. Substitution might
737 be not performed because it's either EXPR' vinsn doesn't contain INSN's
b8698a0f 738 destination or the resulting insn is invalid for the target machine.
e855c69d
AB
739 When UNDO is true, perform unsubstitution instead (the difference is in
740 the part of rtx on which validate_replace_rtx is called). */
741static bool
742substitute_reg_in_expr (expr_t expr, insn_t insn, bool undo)
743{
744 rtx *where;
745 bool new_insn_valid;
746 vinsn_t *vi = &EXPR_VINSN (expr);
747 bool has_rhs = VINSN_RHS (*vi) != NULL;
748 rtx old, new_rtx;
749
750 /* Do not try to replace in SET_DEST. Although we'll choose new
b8698a0f 751 register for the RHS, we don't want to change RHS' original reg.
e855c69d 752 If the insn is not SET, we may still be able to substitute something
b8698a0f 753 in it, and if we're here (don't have deps), it doesn't write INSN's
e855c69d
AB
754 dest. */
755 where = (has_rhs
756 ? &VINSN_RHS (*vi)
757 : &PATTERN (VINSN_INSN_RTX (*vi)));
758 old = undo ? INSN_RHS (insn) : INSN_LHS (insn);
759
760 /* Substitute if INSN has a form of x:=y and LHS(INSN) occurs in *VI. */
761 if (rtx_ok_for_substitution_p (old, *where))
762 {
763 rtx new_insn;
764 rtx *where_replace;
765
766 /* We should copy these rtxes before substitution. */
767 new_rtx = copy_rtx (undo ? INSN_LHS (insn) : INSN_RHS (insn));
768 new_insn = create_copy_of_insn_rtx (VINSN_INSN_RTX (*vi));
769
b8698a0f 770 /* Where we'll replace.
e855c69d
AB
771 WHERE_REPLACE should point inside NEW_INSN, so INSN_RHS couldn't be
772 used instead of SET_SRC. */
773 where_replace = (has_rhs
774 ? &SET_SRC (PATTERN (new_insn))
775 : &PATTERN (new_insn));
776
b8698a0f
L
777 new_insn_valid
778 = validate_replace_rtx_part_nosimplify (old, new_rtx, where_replace,
e855c69d
AB
779 new_insn);
780
781 /* ??? Actually, constrain_operands result depends upon choice of
782 destination register. E.g. if we allow single register to be an rhs,
b8698a0f 783 and if we try to move dx=ax(as rhs) through ax=dx, we'll result
e855c69d
AB
784 in invalid insn dx=dx, so we'll loose this rhs here.
785 Just can't come up with significant testcase for this, so just
786 leaving it for now. */
787 if (new_insn_valid)
788 {
b8698a0f 789 change_vinsn_in_expr (expr,
e855c69d
AB
790 create_vinsn_from_insn_rtx (new_insn, false));
791
b8698a0f 792 /* Do not allow clobbering the address register of speculative
e855c69d
AB
793 insns. */
794 if ((EXPR_SPEC_DONE_DS (expr) & SPECULATIVE)
b8698a0f 795 && bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)),
e855c69d
AB
796 expr_dest_regno (expr)))
797 EXPR_TARGET_AVAILABLE (expr) = false;
798
799 return true;
800 }
801 else
802 return false;
803 }
804 else
805 return false;
806}
807
808/* Helper function for count_occurences_equiv. */
b8698a0f 809static int
e855c69d
AB
810count_occurrences_1 (rtx *cur_rtx, void *arg)
811{
812 rtx_search_arg_p p = (rtx_search_arg_p) arg;
813
814 /* The last param FOR_GCSE is true, because otherwise it performs excessive
815 substitutions like
816 r8 = r33
817 r16 = r33
818 for the last insn it presumes r33 equivalent to r8, so it changes it to
819 r33. Actually, there's no change, but it spoils debugging. */
820 if (exp_equiv_p (*cur_rtx, p->x, 0, true))
821 {
822 /* Bail out if we occupy more than one register. */
823 if (REG_P (*cur_rtx)
72a54528 824 && HARD_REGISTER_P (*cur_rtx)
e855c69d
AB
825 && hard_regno_nregs[REGNO(*cur_rtx)][GET_MODE (*cur_rtx)] > 1)
826 {
827 p->n = 0;
828 return 1;
829 }
830
831 p->n++;
832
833 /* Do not traverse subexprs. */
834 return -1;
835 }
836
837 if (GET_CODE (*cur_rtx) == SUBREG
838 && REG_P (p->x)
839 && REGNO (SUBREG_REG (*cur_rtx)) == REGNO (p->x))
840 {
841 /* ??? Do not support substituting regs inside subregs. In that case,
b8698a0f 842 simplify_subreg will be called by validate_replace_rtx, and
e855c69d
AB
843 unsubstitution will fail later. */
844 p->n = 0;
845 return 1;
846 }
847
848 /* Continue search. */
849 return 0;
850}
851
b8698a0f 852/* Return the number of places WHAT appears within WHERE.
e855c69d 853 Bail out when we found a reference occupying several hard registers. */
b8698a0f 854static int
e855c69d
AB
855count_occurrences_equiv (rtx what, rtx where)
856{
857 struct rtx_search_arg arg;
858
859 arg.x = what;
860 arg.n = 0;
861
862 for_each_rtx (&where, &count_occurrences_1, (void *) &arg);
863
864 return arg.n;
865}
866
867/* Returns TRUE if WHAT is found in WHERE rtx tree. */
868static bool
869rtx_ok_for_substitution_p (rtx what, rtx where)
870{
871 return (count_occurrences_equiv (what, where) > 0);
872}
873\f
874
875/* Functions to support register renaming. */
876
877/* Substitute VI's set source with REGNO. Returns newly created pattern
878 that has REGNO as its source. */
879static rtx
880create_insn_rtx_with_rhs (vinsn_t vi, rtx rhs_rtx)
881{
882 rtx lhs_rtx;
883 rtx pattern;
884 rtx insn_rtx;
885
886 lhs_rtx = copy_rtx (VINSN_LHS (vi));
887
888 pattern = gen_rtx_SET (VOIDmode, lhs_rtx, rhs_rtx);
889 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);
890
891 return insn_rtx;
892}
893
b8698a0f 894/* Returns whether INSN's src can be replaced with register number
e855c69d
AB
895 NEW_SRC_REG. E.g. the following insn is valid for i386:
896
b8698a0f 897 (insn:HI 2205 6585 2207 727 ../../gcc/libiberty/regex.c:3337
e855c69d
AB
898 (set (mem/s:QI (plus:SI (plus:SI (reg/f:SI 7 sp)
899 (reg:SI 0 ax [orig:770 c1 ] [770]))
900 (const_int 288 [0x120])) [0 str S1 A8])
901 (const_int 0 [0x0])) 43 {*movqi_1} (nil)
902 (nil))
903
904 But if we change (const_int 0 [0x0]) to (reg:QI 4 si), it will be invalid
b8698a0f 905 because of operand constraints:
e855c69d
AB
906
907 (define_insn "*movqi_1"
908 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
909 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn")
910 )]
b8698a0f
L
911
912 So do constrain_operands here, before choosing NEW_SRC_REG as best
e855c69d
AB
913 reg for rhs. */
914
915static bool
916replace_src_with_reg_ok_p (insn_t insn, rtx new_src_reg)
917{
918 vinsn_t vi = INSN_VINSN (insn);
919 enum machine_mode mode;
920 rtx dst_loc;
921 bool res;
922
923 gcc_assert (VINSN_SEPARABLE_P (vi));
924
925 get_dest_and_mode (insn, &dst_loc, &mode);
926 gcc_assert (mode == GET_MODE (new_src_reg));
927
928 if (REG_P (dst_loc) && REGNO (new_src_reg) == REGNO (dst_loc))
929 return true;
930
931 /* See whether SET_SRC can be replaced with this register. */
932 validate_change (insn, &SET_SRC (PATTERN (insn)), new_src_reg, 1);
933 res = verify_changes (0);
934 cancel_changes (0);
935
936 return res;
937}
938
939/* Returns whether INSN still be valid after replacing it's DEST with
940 register NEW_REG. */
941static bool
942replace_dest_with_reg_ok_p (insn_t insn, rtx new_reg)
943{
944 vinsn_t vi = INSN_VINSN (insn);
945 bool res;
946
947 /* We should deal here only with separable insns. */
948 gcc_assert (VINSN_SEPARABLE_P (vi));
949 gcc_assert (GET_MODE (VINSN_LHS (vi)) == GET_MODE (new_reg));
950
951 /* See whether SET_DEST can be replaced with this register. */
952 validate_change (insn, &SET_DEST (PATTERN (insn)), new_reg, 1);
953 res = verify_changes (0);
954 cancel_changes (0);
955
956 return res;
957}
958
959/* Create a pattern with rhs of VI and lhs of LHS_RTX. */
960static rtx
961create_insn_rtx_with_lhs (vinsn_t vi, rtx lhs_rtx)
962{
963 rtx rhs_rtx;
964 rtx pattern;
965 rtx insn_rtx;
966
967 rhs_rtx = copy_rtx (VINSN_RHS (vi));
968
969 pattern = gen_rtx_SET (VOIDmode, lhs_rtx, rhs_rtx);
970 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);
971
972 return insn_rtx;
973}
974
b8698a0f 975/* Substitute lhs in the given expression EXPR for the register with number
e855c69d
AB
976 NEW_REGNO. SET_DEST may be arbitrary rtx, not only register. */
977static void
978replace_dest_with_reg_in_expr (expr_t expr, rtx new_reg)
979{
980 rtx insn_rtx;
981 vinsn_t vinsn;
982
983 insn_rtx = create_insn_rtx_with_lhs (EXPR_VINSN (expr), new_reg);
984 vinsn = create_vinsn_from_insn_rtx (insn_rtx, false);
985
986 change_vinsn_in_expr (expr, vinsn);
987 EXPR_WAS_RENAMED (expr) = 1;
988 EXPR_TARGET_AVAILABLE (expr) = 1;
989}
990
991/* Returns whether VI writes either one of the USED_REGS registers or,
992 if a register is a hard one, one of the UNAVAILABLE_HARD_REGS registers. */
993static bool
b8698a0f 994vinsn_writes_one_of_regs_p (vinsn_t vi, regset used_regs,
e855c69d
AB
995 HARD_REG_SET unavailable_hard_regs)
996{
997 unsigned regno;
998 reg_set_iterator rsi;
999
1000 EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_SETS (vi), 0, regno, rsi)
1001 {
1002 if (REGNO_REG_SET_P (used_regs, regno))
1003 return true;
1004 if (HARD_REGISTER_NUM_P (regno)
1005 && TEST_HARD_REG_BIT (unavailable_hard_regs, regno))
1006 return true;
1007 }
1008
1009 EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_CLOBBERS (vi), 0, regno, rsi)
1010 {
1011 if (REGNO_REG_SET_P (used_regs, regno))
1012 return true;
1013 if (HARD_REGISTER_NUM_P (regno)
1014 && TEST_HARD_REG_BIT (unavailable_hard_regs, regno))
1015 return true;
1016 }
1017
1018 return false;
1019}
1020
b8698a0f 1021/* Returns register class of the output register in INSN.
e855c69d
AB
1022 Returns NO_REGS for call insns because some targets have constraints on
1023 destination register of a call insn.
b8698a0f 1024
e855c69d
AB
1025 Code adopted from regrename.c::build_def_use. */
1026static enum reg_class
1027get_reg_class (rtx insn)
1028{
1029 int alt, i, n_ops;
1030
1031 extract_insn (insn);
1032 if (! constrain_operands (1))
1033 fatal_insn_not_found (insn);
1034 preprocess_constraints ();
1035 alt = which_alternative;
1036 n_ops = recog_data.n_operands;
1037
1038 for (i = 0; i < n_ops; ++i)
1039 {
1040 int matches = recog_op_alt[i][alt].matches;
1041 if (matches >= 0)
1042 recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
1043 }
1044
1045 if (asm_noperands (PATTERN (insn)) > 0)
1046 {
1047 for (i = 0; i < n_ops; i++)
1048 if (recog_data.operand_type[i] == OP_OUT)
1049 {
1050 rtx *loc = recog_data.operand_loc[i];
1051 rtx op = *loc;
1052 enum reg_class cl = recog_op_alt[i][alt].cl;
1053
1054 if (REG_P (op)
1055 && REGNO (op) == ORIGINAL_REGNO (op))
1056 continue;
1057
1058 return cl;
1059 }
1060 }
1061 else if (!CALL_P (insn))
1062 {
1063 for (i = 0; i < n_ops + recog_data.n_dups; i++)
1064 {
1065 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1066 enum reg_class cl = recog_op_alt[opn][alt].cl;
b8698a0f 1067
e855c69d
AB
1068 if (recog_data.operand_type[opn] == OP_OUT ||
1069 recog_data.operand_type[opn] == OP_INOUT)
1070 return cl;
1071 }
1072 }
1073
1074/* Insns like
1075 (insn (set (reg:CCZ 17 flags) (compare:CCZ ...)))
1076 may result in returning NO_REGS, cause flags is written implicitly through
1077 CMP insn, which has no OP_OUT | OP_INOUT operands. */
1078 return NO_REGS;
1079}
1080
1081#ifdef HARD_REGNO_RENAME_OK
1082/* Calculate HARD_REGNO_RENAME_OK data for REGNO. */
1083static void
1084init_hard_regno_rename (int regno)
1085{
1086 int cur_reg;
1087
1088 SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], regno);
1089
1090 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
1091 {
1092 /* We are not interested in renaming in other regs. */
1093 if (!TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg))
1094 continue;
1095
1096 if (HARD_REGNO_RENAME_OK (regno, cur_reg))
1097 SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], cur_reg);
1098 }
1099}
1100#endif
1101
b8698a0f 1102/* A wrapper around HARD_REGNO_RENAME_OK that will look into the hard regs
e855c69d
AB
1103 data first. */
1104static inline bool
a20d7130 1105sel_hard_regno_rename_ok (int from ATTRIBUTE_UNUSED, int to ATTRIBUTE_UNUSED)
e855c69d
AB
1106{
1107#ifdef HARD_REGNO_RENAME_OK
1108 /* Check whether this is all calculated. */
1109 if (TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], from))
1110 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);
1111
1112 init_hard_regno_rename (from);
1113
1114 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);
1115#else
1116 return true;
1117#endif
1118}
1119
1120/* Calculate set of registers that are capable of holding MODE. */
1121static void
1122init_regs_for_mode (enum machine_mode mode)
1123{
1124 int cur_reg;
b8698a0f 1125
e855c69d
AB
1126 CLEAR_HARD_REG_SET (sel_hrd.regs_for_mode[mode]);
1127 CLEAR_HARD_REG_SET (sel_hrd.regs_for_call_clobbered[mode]);
1128
1129 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
1130 {
1131 int nregs = hard_regno_nregs[cur_reg][mode];
1132 int i;
b8698a0f 1133
e855c69d
AB
1134 for (i = nregs - 1; i >= 0; --i)
1135 if (fixed_regs[cur_reg + i]
1136 || global_regs[cur_reg + i]
b8698a0f 1137 /* Can't use regs which aren't saved by
e855c69d
AB
1138 the prologue. */
1139 || !TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg + i)
1140#ifdef LEAF_REGISTERS
1141 /* We can't use a non-leaf register if we're in a
1142 leaf function. */
1143 || (current_function_is_leaf
1144 && !LEAF_REGISTERS[cur_reg + i])
1145#endif
1146 )
1147 break;
b8698a0f
L
1148
1149 if (i >= 0)
e855c69d 1150 continue;
b8698a0f 1151
e855c69d
AB
1152 /* See whether it accepts all modes that occur in
1153 original insns. */
1154 if (! HARD_REGNO_MODE_OK (cur_reg, mode))
1155 continue;
b8698a0f 1156
e855c69d 1157 if (HARD_REGNO_CALL_PART_CLOBBERED (cur_reg, mode))
b8698a0f 1158 SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
e855c69d 1159 cur_reg);
b8698a0f
L
1160
1161 /* If the CUR_REG passed all the checks above,
e855c69d
AB
1162 then it's ok. */
1163 SET_HARD_REG_BIT (sel_hrd.regs_for_mode[mode], cur_reg);
1164 }
1165
1166 sel_hrd.regs_for_mode_ok[mode] = true;
1167}
1168
1169/* Init all register sets gathered in HRD. */
1170static void
1171init_hard_regs_data (void)
1172{
1173 int cur_reg = 0;
32e8bb8e 1174 int cur_mode = 0;
e855c69d
AB
1175
1176 CLEAR_HARD_REG_SET (sel_hrd.regs_ever_used);
1177 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
1178 if (df_regs_ever_live_p (cur_reg) || call_used_regs[cur_reg])
1179 SET_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg);
b8698a0f
L
1180
1181 /* Initialize registers that are valid based on mode when this is
e855c69d
AB
1182 really needed. */
1183 for (cur_mode = 0; cur_mode < NUM_MACHINE_MODES; cur_mode++)
1184 sel_hrd.regs_for_mode_ok[cur_mode] = false;
b8698a0f 1185
e855c69d
AB
1186 /* Mark that all HARD_REGNO_RENAME_OK is not calculated. */
1187 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
1188 CLEAR_HARD_REG_SET (sel_hrd.regs_for_rename[cur_reg]);
1189
1190#ifdef STACK_REGS
1191 CLEAR_HARD_REG_SET (sel_hrd.stack_regs);
1192
1193 for (cur_reg = FIRST_STACK_REG; cur_reg <= LAST_STACK_REG; cur_reg++)
1194 SET_HARD_REG_BIT (sel_hrd.stack_regs, cur_reg);
1195#endif
b8698a0f 1196}
e855c69d 1197
b8698a0f 1198/* Mark hardware regs in REG_RENAME_P that are not suitable
e855c69d
AB
1199 for renaming rhs in INSN due to hardware restrictions (register class,
1200 modes compatibility etc). This doesn't affect original insn's dest reg,
1201 if it isn't in USED_REGS. DEF is a definition insn of rhs for which the
1202 destination register is sought. LHS (DEF->ORIG_INSN) may be REG or MEM.
1203 Registers that are in used_regs are always marked in
1204 unavailable_hard_regs as well. */
1205
1206static void
1207mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
1208 regset used_regs ATTRIBUTE_UNUSED)
1209{
1210 enum machine_mode mode;
1211 enum reg_class cl = NO_REGS;
1212 rtx orig_dest;
1213 unsigned cur_reg, regno;
1214 hard_reg_set_iterator hrsi;
1215
1216 gcc_assert (GET_CODE (PATTERN (def->orig_insn)) == SET);
1217 gcc_assert (reg_rename_p);
1218
1219 orig_dest = SET_DEST (PATTERN (def->orig_insn));
b8698a0f 1220
e855c69d
AB
1221 /* We have decided not to rename 'mem = something;' insns, as 'something'
1222 is usually a register. */
1223 if (!REG_P (orig_dest))
1224 return;
1225
1226 regno = REGNO (orig_dest);
1227
1228 /* If before reload, don't try to work with pseudos. */
1229 if (!reload_completed && !HARD_REGISTER_NUM_P (regno))
1230 return;
1231
0c94f956
AM
1232 if (reload_completed)
1233 cl = get_reg_class (def->orig_insn);
e855c69d 1234
0c94f956
AM
1235 /* Stop if the original register is one of the fixed_regs, global_regs or
1236 frame pointer, or we could not discover its class. */
b8698a0f 1237 if (fixed_regs[regno]
e855c69d
AB
1238 || global_regs[regno]
1239#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
0c94f956 1240 || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM)
e855c69d 1241#else
0c94f956 1242 || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM)
e855c69d 1243#endif
0c94f956 1244 || (reload_completed && cl == NO_REGS))
e855c69d
AB
1245 {
1246 SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs);
1247
1248 /* Give a chance for original register, if it isn't in used_regs. */
1249 if (!def->crosses_call)
1250 CLEAR_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, regno);
1251
1252 return;
1253 }
1254
1255 /* If something allocated on stack in this function, mark frame pointer
b8698a0f 1256 register unavailable, considering also modes.
e855c69d
AB
1257 FIXME: it is enough to do this once per all original defs. */
1258 if (frame_pointer_needed)
1259 {
1260 int i;
1261
1262 for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;)
b8698a0f 1263 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
e855c69d
AB
1264 FRAME_POINTER_REGNUM + i);
1265
1266#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
1267 for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;)
b8698a0f 1268 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
e855c69d
AB
1269 HARD_FRAME_POINTER_REGNUM + i);
1270#endif
1271 }
1272
1273#ifdef STACK_REGS
1274 /* For the stack registers the presence of FIRST_STACK_REG in USED_REGS
1275 is equivalent to as if all stack regs were in this set.
1276 I.e. no stack register can be renamed, and even if it's an original
b8698a0f
L
1277 register here we make sure it won't be lifted over it's previous def
1278 (it's previous def will appear as if it's a FIRST_STACK_REG def.
e855c69d
AB
1279 The HARD_REGNO_RENAME_OK covers other cases in condition below. */
1280 if (IN_RANGE (REGNO (orig_dest), FIRST_STACK_REG, LAST_STACK_REG)
b8698a0f
L
1281 && REGNO_REG_SET_P (used_regs, FIRST_STACK_REG))
1282 IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs,
e855c69d 1283 sel_hrd.stack_regs);
b8698a0f 1284#endif
e855c69d 1285
b8698a0f 1286 /* If there's a call on this path, make regs from call_used_reg_set
e855c69d
AB
1287 unavailable. */
1288 if (def->crosses_call)
b8698a0f 1289 IOR_HARD_REG_SET (reg_rename_p->unavailable_hard_regs,
e855c69d
AB
1290 call_used_reg_set);
1291
b8698a0f 1292 /* Stop here before reload: we need FRAME_REGS, STACK_REGS, and crosses_call,
e855c69d
AB
1293 but not register classes. */
1294 if (!reload_completed)
1295 return;
1296
b8698a0f 1297 /* Leave regs as 'available' only from the current
e855c69d 1298 register class. */
e855c69d
AB
1299 COPY_HARD_REG_SET (reg_rename_p->available_for_renaming,
1300 reg_class_contents[cl]);
1301
0c94f956
AM
1302 mode = GET_MODE (orig_dest);
1303
e855c69d
AB
1304 /* Leave only registers available for this mode. */
1305 if (!sel_hrd.regs_for_mode_ok[mode])
1306 init_regs_for_mode (mode);
b8698a0f 1307 AND_HARD_REG_SET (reg_rename_p->available_for_renaming,
e855c69d
AB
1308 sel_hrd.regs_for_mode[mode]);
1309
1310 /* Exclude registers that are partially call clobbered. */
1311 if (def->crosses_call
1312 && ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
b8698a0f 1313 AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
e855c69d
AB
1314 sel_hrd.regs_for_call_clobbered[mode]);
1315
1316 /* Leave only those that are ok to rename. */
1317 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
1318 0, cur_reg, hrsi)
1319 {
1320 int nregs;
1321 int i;
1322
1323 nregs = hard_regno_nregs[cur_reg][mode];
1324 gcc_assert (nregs > 0);
1325
1326 for (i = nregs - 1; i >= 0; --i)
1327 if (! sel_hard_regno_rename_ok (regno + i, cur_reg + i))
1328 break;
1329
b8698a0f
L
1330 if (i >= 0)
1331 CLEAR_HARD_REG_BIT (reg_rename_p->available_for_renaming,
e855c69d
AB
1332 cur_reg);
1333 }
1334
b8698a0f 1335 AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
e855c69d
AB
1336 reg_rename_p->unavailable_hard_regs);
1337
1338 /* Regno is always ok from the renaming part of view, but it really
1339 could be in *unavailable_hard_regs already, so set it here instead
1340 of there. */
1341 SET_HARD_REG_BIT (reg_rename_p->available_for_renaming, regno);
1342}
1343
1344/* reg_rename_tick[REG1] > reg_rename_tick[REG2] if REG1 was chosen as the
1345 best register more recently than REG2. */
1346static int reg_rename_tick[FIRST_PSEUDO_REGISTER];
1347
1348/* Indicates the number of times renaming happened before the current one. */
1349static int reg_rename_this_tick;
1350
b8698a0f 1351/* Choose the register among free, that is suitable for storing
e855c69d
AB
1352 the rhs value.
1353
1354 ORIGINAL_INSNS is the list of insns where the operation (rhs)
b8698a0f
L
1355 originally appears. There could be multiple original operations
1356 for single rhs since we moving it up and merging along different
e855c69d
AB
1357 paths.
1358
1359 Some code is adapted from regrename.c (regrename_optimize).
1360 If original register is available, function returns it.
1361 Otherwise it performs the checks, so the new register should
1362 comply with the following:
b8698a0f 1363 - it should not violate any live ranges (such registers are in
e855c69d
AB
1364 REG_RENAME_P->available_for_renaming set);
1365 - it should not be in the HARD_REGS_USED regset;
1366 - it should be in the class compatible with original uses;
1367 - it should not be clobbered through reference with different mode;
b8698a0f 1368 - if we're in the leaf function, then the new register should
e855c69d
AB
1369 not be in the LEAF_REGISTERS;
1370 - etc.
1371
1372 If several registers meet the conditions, the register with smallest
1373 tick is returned to achieve more even register allocation.
1374
1375 If original register seems to be ok, we set *IS_ORIG_REG_P_PTR to true.
1376
1377 If no register satisfies the above conditions, NULL_RTX is returned. */
1378static rtx
b8698a0f
L
1379choose_best_reg_1 (HARD_REG_SET hard_regs_used,
1380 struct reg_rename *reg_rename_p,
e855c69d
AB
1381 def_list_t original_insns, bool *is_orig_reg_p_ptr)
1382{
1383 int best_new_reg;
1384 unsigned cur_reg;
1385 enum machine_mode mode = VOIDmode;
1386 unsigned regno, i, n;
1387 hard_reg_set_iterator hrsi;
1388 def_list_iterator di;
1389 def_t def;
1390
1391 /* If original register is available, return it. */
1392 *is_orig_reg_p_ptr = true;
1393
1394 FOR_EACH_DEF (def, di, original_insns)
1395 {
1396 rtx orig_dest = SET_DEST (PATTERN (def->orig_insn));
1397
1398 gcc_assert (REG_P (orig_dest));
1399
b8698a0f 1400 /* Check that all original operations have the same mode.
e855c69d 1401 This is done for the next loop; if we'd return from this
b8698a0f 1402 loop, we'd check only part of them, but in this case
e855c69d
AB
1403 it doesn't matter. */
1404 if (mode == VOIDmode)
1405 mode = GET_MODE (orig_dest);
1406 gcc_assert (mode == GET_MODE (orig_dest));
1407
1408 regno = REGNO (orig_dest);
1409 for (i = 0, n = hard_regno_nregs[regno][mode]; i < n; i++)
1410 if (TEST_HARD_REG_BIT (hard_regs_used, regno + i))
1411 break;
1412
1413 /* All hard registers are available. */
1414 if (i == n)
1415 {
1416 gcc_assert (mode != VOIDmode);
b8698a0f 1417
e855c69d
AB
1418 /* Hard registers should not be shared. */
1419 return gen_rtx_REG (mode, regno);
1420 }
1421 }
b8698a0f 1422
e855c69d
AB
1423 *is_orig_reg_p_ptr = false;
1424 best_new_reg = -1;
b8698a0f
L
1425
1426 /* Among all available regs choose the register that was
e855c69d
AB
1427 allocated earliest. */
1428 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
1429 0, cur_reg, hrsi)
1430 if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg))
1431 {
a9ced68b
AM
1432 /* Check that all hard regs for mode are available. */
1433 for (i = 1, n = hard_regno_nregs[cur_reg][mode]; i < n; i++)
1434 if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i)
1435 || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming,
1436 cur_reg + i))
1437 break;
1438
1439 if (i < n)
1440 continue;
1441
e855c69d
AB
1442 /* All hard registers are available. */
1443 if (best_new_reg < 0
1444 || reg_rename_tick[cur_reg] < reg_rename_tick[best_new_reg])
1445 {
1446 best_new_reg = cur_reg;
b8698a0f 1447
e855c69d
AB
1448 /* Return immediately when we know there's no better reg. */
1449 if (! reg_rename_tick[best_new_reg])
1450 break;
1451 }
1452 }
1453
1454 if (best_new_reg >= 0)
1455 {
1456 /* Use the check from the above loop. */
1457 gcc_assert (mode != VOIDmode);
1458 return gen_rtx_REG (mode, best_new_reg);
1459 }
1460
1461 return NULL_RTX;
1462}
1463
1464/* A wrapper around choose_best_reg_1 () to verify that we make correct
1465 assumptions about available registers in the function. */
1466static rtx
b8698a0f 1467choose_best_reg (HARD_REG_SET hard_regs_used, struct reg_rename *reg_rename_p,
e855c69d
AB
1468 def_list_t original_insns, bool *is_orig_reg_p_ptr)
1469{
b8698a0f 1470 rtx best_reg = choose_best_reg_1 (hard_regs_used, reg_rename_p,
e855c69d
AB
1471 original_insns, is_orig_reg_p_ptr);
1472
a9ced68b 1473 /* FIXME loop over hard_regno_nregs here. */
e855c69d
AB
1474 gcc_assert (best_reg == NULL_RTX
1475 || TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, REGNO (best_reg)));
1476
1477 return best_reg;
1478}
1479
b8698a0f 1480/* Choose the pseudo register for storing rhs value. As this is supposed
e855c69d 1481 to work before reload, we return either the original register or make
b8698a0f
L
1482 the new one. The parameters are the same that in choose_nest_reg_1
1483 functions, except that USED_REGS may contain pseudos.
e855c69d
AB
1484 If we work with hard regs, check also REG_RENAME_P->UNAVAILABLE_HARD_REGS.
1485
b8698a0f
L
1486 TODO: take into account register pressure while doing this. Up to this
1487 moment, this function would never return NULL for pseudos, but we should
e855c69d
AB
1488 not rely on this. */
1489static rtx
b8698a0f
L
1490choose_best_pseudo_reg (regset used_regs,
1491 struct reg_rename *reg_rename_p,
e855c69d
AB
1492 def_list_t original_insns, bool *is_orig_reg_p_ptr)
1493{
1494 def_list_iterator i;
1495 def_t def;
1496 enum machine_mode mode = VOIDmode;
1497 bool bad_hard_regs = false;
b8698a0f 1498
e855c69d
AB
1499 /* We should not use this after reload. */
1500 gcc_assert (!reload_completed);
1501
1502 /* If original register is available, return it. */
1503 *is_orig_reg_p_ptr = true;
1504
1505 FOR_EACH_DEF (def, i, original_insns)
1506 {
1507 rtx dest = SET_DEST (PATTERN (def->orig_insn));
1508 int orig_regno;
b8698a0f 1509
e855c69d 1510 gcc_assert (REG_P (dest));
b8698a0f 1511
e855c69d
AB
1512 /* Check that all original operations have the same mode. */
1513 if (mode == VOIDmode)
1514 mode = GET_MODE (dest);
1515 else
1516 gcc_assert (mode == GET_MODE (dest));
1517 orig_regno = REGNO (dest);
b8698a0f 1518
e855c69d
AB
1519 if (!REGNO_REG_SET_P (used_regs, orig_regno))
1520 {
1521 if (orig_regno < FIRST_PSEUDO_REGISTER)
1522 {
1523 gcc_assert (df_regs_ever_live_p (orig_regno));
b8698a0f
L
1524
1525 /* For hard registers, we have to check hardware imposed
e855c69d 1526 limitations (frame/stack registers, calls crossed). */
b8698a0f 1527 if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
e855c69d
AB
1528 orig_regno))
1529 {
b8698a0f
L
1530 /* Don't let register cross a call if it doesn't already
1531 cross one. This condition is written in accordance with
e855c69d 1532 that in sched-deps.c sched_analyze_reg(). */
b8698a0f 1533 if (!reg_rename_p->crosses_call
e855c69d 1534 || REG_N_CALLS_CROSSED (orig_regno) > 0)
b8698a0f 1535 return gen_rtx_REG (mode, orig_regno);
e855c69d 1536 }
b8698a0f 1537
e855c69d
AB
1538 bad_hard_regs = true;
1539 }
1540 else
1541 return dest;
1542 }
1543 }
1544
1545 *is_orig_reg_p_ptr = false;
b8698a0f 1546
e855c69d
AB
1547 /* We had some original hard registers that couldn't be used.
1548 Those were likely special. Don't try to create a pseudo. */
1549 if (bad_hard_regs)
1550 return NULL_RTX;
b8698a0f
L
1551
1552 /* We haven't found a register from original operations. Get a new one.
e855c69d
AB
1553 FIXME: control register pressure somehow. */
1554 {
1555 rtx new_reg = gen_reg_rtx (mode);
1556
1557 gcc_assert (mode != VOIDmode);
1558
1559 max_regno = max_reg_num ();
1560 maybe_extend_reg_info_p ();
1561 REG_N_CALLS_CROSSED (REGNO (new_reg)) = reg_rename_p->crosses_call ? 1 : 0;
1562
1563 return new_reg;
1564 }
1565}
1566
1567/* True when target of EXPR is available due to EXPR_TARGET_AVAILABLE,
1568 USED_REGS and REG_RENAME_P->UNAVAILABLE_HARD_REGS. */
1569static void
b8698a0f 1570verify_target_availability (expr_t expr, regset used_regs,
e855c69d
AB
1571 struct reg_rename *reg_rename_p)
1572{
1573 unsigned n, i, regno;
1574 enum machine_mode mode;
1575 bool target_available, live_available, hard_available;
1576
1577 if (!REG_P (EXPR_LHS (expr)) || EXPR_TARGET_AVAILABLE (expr) < 0)
1578 return;
b8698a0f 1579
e855c69d
AB
1580 regno = expr_dest_regno (expr);
1581 mode = GET_MODE (EXPR_LHS (expr));
1582 target_available = EXPR_TARGET_AVAILABLE (expr) == 1;
1583 n = reload_completed ? hard_regno_nregs[regno][mode] : 1;
1584
1585 live_available = hard_available = true;
1586 for (i = 0; i < n; i++)
1587 {
1588 if (bitmap_bit_p (used_regs, regno + i))
1589 live_available = false;
1590 if (TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, regno + i))
1591 hard_available = false;
1592 }
1593
b8698a0f 1594 /* When target is not available, it may be due to hard register
e855c69d
AB
1595 restrictions, e.g. crosses calls, so we check hard_available too. */
1596 if (target_available)
1597 gcc_assert (live_available);
1598 else
b8698a0f 1599 /* Check only if we haven't scheduled something on the previous fence,
e855c69d
AB
1600 cause due to MAX_SOFTWARE_LOOKAHEAD_WINDOW_SIZE issues
1601 and having more than one fence, we may end having targ_un in a block
b8698a0f 1602 in which successors target register is actually available.
e855c69d
AB
1603
1604 The last condition handles the case when a dependence from a call insn
b8698a0f
L
1605 was created in sched-deps.c for insns with destination registers that
1606 never crossed a call before, but do cross one after our code motion.
e855c69d 1607
b8698a0f
L
1608 FIXME: in the latter case, we just uselessly called find_used_regs,
1609 because we can't move this expression with any other register
e855c69d 1610 as well. */
b8698a0f
L
1611 gcc_assert (scheduled_something_on_previous_fence || !live_available
1612 || !hard_available
1613 || (!reload_completed && reg_rename_p->crosses_call
e855c69d
AB
1614 && REG_N_CALLS_CROSSED (regno) == 0));
1615}
1616
b8698a0f
L
1617/* Collect unavailable registers due to liveness for EXPR from BNDS
1618 into USED_REGS. Save additional information about available
e855c69d
AB
1619 registers and unavailable due to hardware restriction registers
1620 into REG_RENAME_P structure. Save original insns into ORIGINAL_INSNS
1621 list. */
1622static void
1623collect_unavailable_regs_from_bnds (expr_t expr, blist_t bnds, regset used_regs,
1624 struct reg_rename *reg_rename_p,
1625 def_list_t *original_insns)
1626{
1627 for (; bnds; bnds = BLIST_NEXT (bnds))
1628 {
1629 bool res;
1630 av_set_t orig_ops = NULL;
1631 bnd_t bnd = BLIST_BND (bnds);
1632
1633 /* If the chosen best expr doesn't belong to current boundary,
1634 skip it. */
1635 if (!av_set_is_in_p (BND_AV1 (bnd), EXPR_VINSN (expr)))
1636 continue;
1637
1638 /* Put in ORIG_OPS all exprs from this boundary that became
1639 RES on top. */
1640 orig_ops = find_sequential_best_exprs (bnd, expr, false);
1641
1642 /* Compute used regs and OR it into the USED_REGS. */
1643 res = find_used_regs (BND_TO (bnd), orig_ops, used_regs,
1644 reg_rename_p, original_insns);
1645
1646 /* FIXME: the assert is true until we'd have several boundaries. */
1647 gcc_assert (res);
1648 av_set_clear (&orig_ops);
1649 }
1650}
1651
1652/* Return TRUE if it is possible to replace LHSes of ORIG_INSNS with BEST_REG.
1653 If BEST_REG is valid, replace LHS of EXPR with it. */
1654static bool
1655try_replace_dest_reg (ilist_t orig_insns, rtx best_reg, expr_t expr)
1656{
e855c69d
AB
1657 /* Try whether we'll be able to generate the insn
1658 'dest := best_reg' at the place of the original operation. */
1659 for (; orig_insns; orig_insns = ILIST_NEXT (orig_insns))
1660 {
1661 insn_t orig_insn = DEF_LIST_DEF (orig_insns)->orig_insn;
1662
1663 gcc_assert (EXPR_SEPARABLE_P (INSN_EXPR (orig_insn)));
1664
0666ff4e
AB
1665 if (REGNO (best_reg) != REGNO (INSN_LHS (orig_insn))
1666 && (! replace_src_with_reg_ok_p (orig_insn, best_reg)
1667 || ! replace_dest_with_reg_ok_p (orig_insn, best_reg)))
e855c69d
AB
1668 return false;
1669 }
1670
1671 /* Make sure that EXPR has the right destination
1672 register. */
0666ff4e
AB
1673 if (expr_dest_regno (expr) != REGNO (best_reg))
1674 replace_dest_with_reg_in_expr (expr, best_reg);
1675 else
1676 EXPR_TARGET_AVAILABLE (expr) = 1;
1677
e855c69d
AB
1678 return true;
1679}
1680
b8698a0f
L
1681/* Select and assign best register to EXPR searching from BNDS.
1682 Set *IS_ORIG_REG_P to TRUE if original register was selected.
e855c69d
AB
1683 Return FALSE if no register can be chosen, which could happen when:
1684 * EXPR_SEPARABLE_P is true but we were unable to find suitable register;
1685 * EXPR_SEPARABLE_P is false but the insn sets/clobbers one of the registers
1686 that are used on the moving path. */
1687static bool
1688find_best_reg_for_expr (expr_t expr, blist_t bnds, bool *is_orig_reg_p)
1689{
1690 static struct reg_rename reg_rename_data;
1691
1692 regset used_regs;
1693 def_list_t original_insns = NULL;
1694 bool reg_ok;
1695
1696 *is_orig_reg_p = false;
1697
1698 /* Don't bother to do anything if this insn doesn't set any registers. */
1699 if (bitmap_empty_p (VINSN_REG_SETS (EXPR_VINSN (expr)))
1700 && bitmap_empty_p (VINSN_REG_CLOBBERS (EXPR_VINSN (expr))))
1701 return true;
1702
1703 used_regs = get_clear_regset_from_pool ();
1704 CLEAR_HARD_REG_SET (reg_rename_data.unavailable_hard_regs);
1705
1706 collect_unavailable_regs_from_bnds (expr, bnds, used_regs, &reg_rename_data,
1707 &original_insns);
1708
1709#ifdef ENABLE_CHECKING
1710 /* If after reload, make sure we're working with hard regs here. */
b8698a0f 1711 if (reload_completed)
e855c69d
AB
1712 {
1713 reg_set_iterator rsi;
1714 unsigned i;
b8698a0f 1715
e855c69d
AB
1716 EXECUTE_IF_SET_IN_REG_SET (used_regs, FIRST_PSEUDO_REGISTER, i, rsi)
1717 gcc_unreachable ();
1718 }
1719#endif
1720
1721 if (EXPR_SEPARABLE_P (expr))
1722 {
1723 rtx best_reg = NULL_RTX;
1724 /* Check that we have computed availability of a target register
1725 correctly. */
1726 verify_target_availability (expr, used_regs, &reg_rename_data);
1727
1728 /* Turn everything in hard regs after reload. */
1729 if (reload_completed)
1730 {
1731 HARD_REG_SET hard_regs_used;
1732 REG_SET_TO_HARD_REG_SET (hard_regs_used, used_regs);
1733
1734 /* Join hard registers unavailable due to register class
1735 restrictions and live range intersection. */
1736 IOR_HARD_REG_SET (hard_regs_used,
1737 reg_rename_data.unavailable_hard_regs);
1738
1739 best_reg = choose_best_reg (hard_regs_used, &reg_rename_data,
1740 original_insns, is_orig_reg_p);
1741 }
1742 else
1743 best_reg = choose_best_pseudo_reg (used_regs, &reg_rename_data,
1744 original_insns, is_orig_reg_p);
1745
1746 if (!best_reg)
1747 reg_ok = false;
1748 else if (*is_orig_reg_p)
1749 {
1750 /* In case of unification BEST_REG may be different from EXPR's LHS
1751 when EXPR's LHS is unavailable, and there is another LHS among
1752 ORIGINAL_INSNS. */
1753 reg_ok = try_replace_dest_reg (original_insns, best_reg, expr);
1754 }
1755 else
1756 {
1757 /* Forbid renaming of low-cost insns. */
1758 if (sel_vinsn_cost (EXPR_VINSN (expr)) < 2)
1759 reg_ok = false;
1760 else
1761 reg_ok = try_replace_dest_reg (original_insns, best_reg, expr);
1762 }
1763 }
1764 else
1765 {
1766 /* If !EXPR_SCHEDULE_AS_RHS (EXPR), just make sure INSN doesn't set
1767 any of the HARD_REGS_USED set. */
1768 if (vinsn_writes_one_of_regs_p (EXPR_VINSN (expr), used_regs,
1769 reg_rename_data.unavailable_hard_regs))
1770 {
1771 reg_ok = false;
1772 gcc_assert (EXPR_TARGET_AVAILABLE (expr) <= 0);
1773 }
1774 else
1775 {
1776 reg_ok = true;
1777 gcc_assert (EXPR_TARGET_AVAILABLE (expr) != 0);
1778 }
1779 }
1780
1781 ilist_clear (&original_insns);
1782 return_regset_to_pool (used_regs);
1783
1784 return reg_ok;
1785}
1786\f
1787
1788/* Return true if dependence described by DS can be overcomed. */
1789static bool
1790can_speculate_dep_p (ds_t ds)
1791{
1792 if (spec_info == NULL)
1793 return false;
1794
1795 /* Leave only speculative data. */
1796 ds &= SPECULATIVE;
1797
1798 if (ds == 0)
1799 return false;
1800
1801 {
1802 /* FIXME: make sched-deps.c produce only those non-hard dependencies,
1803 that we can overcome. */
1804 ds_t spec_mask = spec_info->mask;
1805
1806 if ((ds & spec_mask) != ds)
1807 return false;
1808 }
1809
1810 if (ds_weak (ds) < spec_info->data_weakness_cutoff)
1811 return false;
1812
1813 return true;
1814}
1815
1816/* Get a speculation check instruction.
1817 C_EXPR is a speculative expression,
1818 CHECK_DS describes speculations that should be checked,
1819 ORIG_INSN is the original non-speculative insn in the stream. */
1820static insn_t
1821create_speculation_check (expr_t c_expr, ds_t check_ds, insn_t orig_insn)
1822{
1823 rtx check_pattern;
1824 rtx insn_rtx;
1825 insn_t insn;
1826 basic_block recovery_block;
1827 rtx label;
1828
1829 /* Create a recovery block if target is going to emit branchy check, or if
1830 ORIG_INSN was speculative already. */
388092d5 1831 if (targetm.sched.needs_block_p (check_ds)
e855c69d
AB
1832 || EXPR_SPEC_DONE_DS (INSN_EXPR (orig_insn)) != 0)
1833 {
1834 recovery_block = sel_create_recovery_block (orig_insn);
1835 label = BB_HEAD (recovery_block);
1836 }
1837 else
1838 {
1839 recovery_block = NULL;
1840 label = NULL_RTX;
1841 }
1842
1843 /* Get pattern of the check. */
1844 check_pattern = targetm.sched.gen_spec_check (EXPR_INSN_RTX (c_expr), label,
1845 check_ds);
1846
1847 gcc_assert (check_pattern != NULL);
1848
1849 /* Emit check. */
1850 insn_rtx = create_insn_rtx_from_pattern (check_pattern, label);
1851
1852 insn = sel_gen_insn_from_rtx_after (insn_rtx, INSN_EXPR (orig_insn),
1853 INSN_SEQNO (orig_insn), orig_insn);
1854
1855 /* Make check to be non-speculative. */
1856 EXPR_SPEC_DONE_DS (INSN_EXPR (insn)) = 0;
1857 INSN_SPEC_CHECKED_DS (insn) = check_ds;
1858
1859 /* Decrease priority of check by difference of load/check instruction
1860 latencies. */
1861 EXPR_PRIORITY (INSN_EXPR (insn)) -= (sel_vinsn_cost (INSN_VINSN (orig_insn))
1862 - sel_vinsn_cost (INSN_VINSN (insn)));
1863
1864 /* Emit copy of original insn (though with replaced target register,
1865 if needed) to the recovery block. */
1866 if (recovery_block != NULL)
1867 {
1868 rtx twin_rtx;
1869 insn_t twin;
1870
1871 twin_rtx = copy_rtx (PATTERN (EXPR_INSN_RTX (c_expr)));
1872 twin_rtx = create_insn_rtx_from_pattern (twin_rtx, NULL_RTX);
1873 twin = sel_gen_recovery_insn_from_rtx_after (twin_rtx,
1874 INSN_EXPR (orig_insn),
1875 INSN_SEQNO (insn),
1876 bb_note (recovery_block));
1877 }
1878
1879 /* If we've generated a data speculation check, make sure
1880 that all the bookkeeping instruction we'll create during
1881 this move_op () will allocate an ALAT entry so that the
1882 check won't fail.
1883 In case of control speculation we must convert C_EXPR to control
1884 speculative mode, because failing to do so will bring us an exception
1885 thrown by the non-control-speculative load. */
1886 check_ds = ds_get_max_dep_weak (check_ds);
1887 speculate_expr (c_expr, check_ds);
b8698a0f 1888
e855c69d
AB
1889 return insn;
1890}
1891
1892/* True when INSN is a "regN = regN" copy. */
1893static bool
1894identical_copy_p (rtx insn)
1895{
1896 rtx lhs, rhs, pat;
1897
1898 pat = PATTERN (insn);
1899
1900 if (GET_CODE (pat) != SET)
1901 return false;
1902
1903 lhs = SET_DEST (pat);
1904 if (!REG_P (lhs))
1905 return false;
1906
1907 rhs = SET_SRC (pat);
1908 if (!REG_P (rhs))
1909 return false;
1910
1911 return REGNO (lhs) == REGNO (rhs);
1912}
1913
b8698a0f 1914/* Undo all transformations on *AV_PTR that were done when
e855c69d
AB
1915 moving through INSN. */
1916static void
1917undo_transformations (av_set_t *av_ptr, rtx insn)
1918{
1919 av_set_iterator av_iter;
1920 expr_t expr;
1921 av_set_t new_set = NULL;
1922
b8698a0f 1923 /* First, kill any EXPR that uses registers set by an insn. This is
e855c69d
AB
1924 required for correctness. */
1925 FOR_EACH_EXPR_1 (expr, av_iter, av_ptr)
1926 if (!sched_insns_conditions_mutex_p (insn, EXPR_INSN_RTX (expr))
b8698a0f 1927 && bitmap_intersect_p (INSN_REG_SETS (insn),
e855c69d
AB
1928 VINSN_REG_USES (EXPR_VINSN (expr)))
1929 /* When an insn looks like 'r1 = r1', we could substitute through
1930 it, but the above condition will still hold. This happened with
b8698a0f 1931 gcc.c-torture/execute/961125-1.c. */
e855c69d
AB
1932 && !identical_copy_p (insn))
1933 {
1934 if (sched_verbose >= 6)
b8698a0f 1935 sel_print ("Expr %d removed due to use/set conflict\n",
e855c69d
AB
1936 INSN_UID (EXPR_INSN_RTX (expr)));
1937 av_set_iter_remove (&av_iter);
1938 }
1939
1940 /* Undo transformations looking at the history vector. */
1941 FOR_EACH_EXPR (expr, av_iter, *av_ptr)
1942 {
1943 int index = find_in_history_vect (EXPR_HISTORY_OF_CHANGES (expr),
1944 insn, EXPR_VINSN (expr), true);
1945
1946 if (index >= 0)
1947 {
1948 expr_history_def *phist;
1949
b8698a0f 1950 phist = VEC_index (expr_history_def,
e855c69d
AB
1951 EXPR_HISTORY_OF_CHANGES (expr),
1952 index);
1953
b8698a0f 1954 switch (phist->type)
e855c69d
AB
1955 {
1956 case TRANS_SPECULATION:
1957 {
1958 ds_t old_ds, new_ds;
b8698a0f 1959
e855c69d 1960 /* Compute the difference between old and new speculative
b8698a0f 1961 statuses: that's what we need to check.
e855c69d
AB
1962 Earlier we used to assert that the status will really
1963 change. This no longer works because only the probability
1964 bits in the status may have changed during compute_av_set,
b8698a0f
L
1965 and in the case of merging different probabilities of the
1966 same speculative status along different paths we do not
e855c69d
AB
1967 record this in the history vector. */
1968 old_ds = phist->spec_ds;
1969 new_ds = EXPR_SPEC_DONE_DS (expr);
1970
1971 old_ds &= SPECULATIVE;
1972 new_ds &= SPECULATIVE;
1973 new_ds &= ~old_ds;
b8698a0f 1974
e855c69d
AB
1975 EXPR_SPEC_TO_CHECK_DS (expr) |= new_ds;
1976 break;
1977 }
1978 case TRANS_SUBSTITUTION:
1979 {
1980 expr_def _tmp_expr, *tmp_expr = &_tmp_expr;
1981 vinsn_t new_vi;
1982 bool add = true;
b8698a0f 1983
e855c69d 1984 new_vi = phist->old_expr_vinsn;
b8698a0f
L
1985
1986 gcc_assert (VINSN_SEPARABLE_P (new_vi)
e855c69d
AB
1987 == EXPR_SEPARABLE_P (expr));
1988 copy_expr (tmp_expr, expr);
1989
b8698a0f 1990 if (vinsn_equal_p (phist->new_expr_vinsn,
e855c69d
AB
1991 EXPR_VINSN (tmp_expr)))
1992 change_vinsn_in_expr (tmp_expr, new_vi);
1993 else
1994 /* This happens when we're unsubstituting on a bookkeeping
1995 copy, which was in turn substituted. The history is wrong
1996 in this case. Do it the hard way. */
1997 add = substitute_reg_in_expr (tmp_expr, insn, true);
1998 if (add)
1999 av_set_add (&new_set, tmp_expr);
2000 clear_expr (tmp_expr);
2001 break;
2002 }
2003 default:
2004 gcc_unreachable ();
2005 }
2006 }
b8698a0f 2007
e855c69d
AB
2008 }
2009
2010 av_set_union_and_clear (av_ptr, &new_set, NULL);
2011}
2012\f
2013
2014/* Moveup_* helpers for code motion and computing av sets. */
2015
2016/* Propagates EXPR inside an insn group through THROUGH_INSN.
b8698a0f 2017 The difference from the below function is that only substitution is
e855c69d
AB
2018 performed. */
2019static enum MOVEUP_EXPR_CODE
2020moveup_expr_inside_insn_group (expr_t expr, insn_t through_insn)
2021{
2022 vinsn_t vi = EXPR_VINSN (expr);
2023 ds_t *has_dep_p;
2024 ds_t full_ds;
2025
2026 /* Do this only inside insn group. */
2027 gcc_assert (INSN_SCHED_CYCLE (through_insn) > 0);
2028
2029 full_ds = has_dependence_p (expr, through_insn, &has_dep_p);
2030 if (full_ds == 0)
2031 return MOVEUP_EXPR_SAME;
2032
2033 /* Substitution is the possible choice in this case. */
2034 if (has_dep_p[DEPS_IN_RHS])
2035 {
2036 /* Can't substitute UNIQUE VINSNs. */
2037 gcc_assert (!VINSN_UNIQUE_P (vi));
b8698a0f
L
2038
2039 if (can_substitute_through_p (through_insn,
e855c69d
AB
2040 has_dep_p[DEPS_IN_RHS])
2041 && substitute_reg_in_expr (expr, through_insn, false))
2042 {
2043 EXPR_WAS_SUBSTITUTED (expr) = true;
2044 return MOVEUP_EXPR_CHANGED;
2045 }
2046
2047 /* Don't care about this, as even true dependencies may be allowed
2048 in an insn group. */
2049 return MOVEUP_EXPR_SAME;
2050 }
2051
2052 /* This can catch output dependencies in COND_EXECs. */
2053 if (has_dep_p[DEPS_IN_INSN])
2054 return MOVEUP_EXPR_NULL;
b8698a0f 2055
e855c69d
AB
2056 /* This is either an output or an anti dependence, which usually have
2057 a zero latency. Allow this here, if we'd be wrong, tick_check_p
2058 will fix this. */
2059 gcc_assert (has_dep_p[DEPS_IN_LHS]);
2060 return MOVEUP_EXPR_AS_RHS;
2061}
2062
2063/* True when a trapping EXPR cannot be moved through THROUGH_INSN. */
2064#define CANT_MOVE_TRAPPING(expr, through_insn) \
2065 (VINSN_MAY_TRAP_P (EXPR_VINSN (expr)) \
2066 && !sel_insn_has_single_succ_p ((through_insn), SUCCS_ALL) \
2067 && !sel_insn_is_speculation_check (through_insn))
2068
2069/* True when a conflict on a target register was found during moveup_expr. */
2070static bool was_target_conflict = false;
2071
b5b8b0ac
AO
2072/* Return true when moving a debug INSN across THROUGH_INSN will
2073 create a bookkeeping block. We don't want to create such blocks,
2074 for they would cause codegen differences between compilations with
2075 and without debug info. */
2076
2077static bool
2078moving_insn_creates_bookkeeping_block_p (insn_t insn,
2079 insn_t through_insn)
2080{
2081 basic_block bbi, bbt;
2082 edge e1, e2;
2083 edge_iterator ei1, ei2;
2084
2085 if (!bookkeeping_can_be_created_if_moved_through_p (through_insn))
2086 {
2087 if (sched_verbose >= 9)
2088 sel_print ("no bookkeeping required: ");
2089 return FALSE;
2090 }
2091
2092 bbi = BLOCK_FOR_INSN (insn);
2093
2094 if (EDGE_COUNT (bbi->preds) == 1)
2095 {
2096 if (sched_verbose >= 9)
2097 sel_print ("only one pred edge: ");
2098 return TRUE;
2099 }
2100
2101 bbt = BLOCK_FOR_INSN (through_insn);
2102
2103 FOR_EACH_EDGE (e1, ei1, bbt->succs)
2104 {
2105 FOR_EACH_EDGE (e2, ei2, bbi->preds)
2106 {
2107 if (find_block_for_bookkeeping (e1, e2, TRUE))
2108 {
2109 if (sched_verbose >= 9)
2110 sel_print ("found existing block: ");
2111 return FALSE;
2112 }
2113 }
2114 }
2115
2116 if (sched_verbose >= 9)
2117 sel_print ("would create bookkeeping block: ");
2118
2119 return TRUE;
2120}
2121
e855c69d 2122/* Modifies EXPR so it can be moved through the THROUGH_INSN,
b8698a0f
L
2123 performing necessary transformations. Record the type of transformation
2124 made in PTRANS_TYPE, when it is not NULL. When INSIDE_INSN_GROUP,
e855c69d 2125 permit all dependencies except true ones, and try to remove those
b8698a0f
L
2126 too via forward substitution. All cases when a non-eliminable
2127 non-zero cost dependency exists inside an insn group will be fixed
e855c69d
AB
2128 in tick_check_p instead. */
2129static enum MOVEUP_EXPR_CODE
2130moveup_expr (expr_t expr, insn_t through_insn, bool inside_insn_group,
2131 enum local_trans_type *ptrans_type)
2132{
2133 vinsn_t vi = EXPR_VINSN (expr);
2134 insn_t insn = VINSN_INSN_RTX (vi);
2135 bool was_changed = false;
2136 bool as_rhs = false;
2137 ds_t *has_dep_p;
2138 ds_t full_ds;
2139
2140 /* When inside_insn_group, delegate to the helper. */
2141 if (inside_insn_group)
2142 return moveup_expr_inside_insn_group (expr, through_insn);
2143
2144 /* Deal with unique insns and control dependencies. */
2145 if (VINSN_UNIQUE_P (vi))
2146 {
2147 /* We can move jumps without side-effects or jumps that are
2148 mutually exclusive with instruction THROUGH_INSN (all in cases
2149 dependencies allow to do so and jump is not speculative). */
2150 if (control_flow_insn_p (insn))
2151 {
2152 basic_block fallthru_bb;
2153
b8698a0f 2154 /* Do not move checks and do not move jumps through other
e855c69d
AB
2155 jumps. */
2156 if (control_flow_insn_p (through_insn)
2157 || sel_insn_is_speculation_check (insn))
2158 return MOVEUP_EXPR_NULL;
2159
2160 /* Don't move jumps through CFG joins. */
2161 if (bookkeeping_can_be_created_if_moved_through_p (through_insn))
2162 return MOVEUP_EXPR_NULL;
2163
b8698a0f 2164 /* The jump should have a clear fallthru block, and
e855c69d
AB
2165 this block should be in the current region. */
2166 if ((fallthru_bb = fallthru_bb_of_jump (insn)) == NULL
2167 || ! in_current_region_p (fallthru_bb))
2168 return MOVEUP_EXPR_NULL;
b8698a0f
L
2169
2170 /* And it should be mutually exclusive with through_insn, or
e855c69d
AB
2171 be an unconditional jump. */
2172 if (! any_uncondjump_p (insn)
b5b8b0ac
AO
2173 && ! sched_insns_conditions_mutex_p (insn, through_insn)
2174 && ! DEBUG_INSN_P (through_insn))
e855c69d
AB
2175 return MOVEUP_EXPR_NULL;
2176 }
2177
2178 /* Don't move what we can't move. */
2179 if (EXPR_CANT_MOVE (expr)
2180 && BLOCK_FOR_INSN (through_insn) != BLOCK_FOR_INSN (insn))
2181 return MOVEUP_EXPR_NULL;
2182
2183 /* Don't move SCHED_GROUP instruction through anything.
2184 If we don't force this, then it will be possible to start
2185 scheduling a sched_group before all its dependencies are
2186 resolved.
2187 ??? Haifa deals with this issue by delaying the SCHED_GROUP
2188 as late as possible through rank_for_schedule. */
2189 if (SCHED_GROUP_P (insn))
2190 return MOVEUP_EXPR_NULL;
2191 }
2192 else
2193 gcc_assert (!control_flow_insn_p (insn));
2194
b5b8b0ac
AO
2195 /* Don't move debug insns if this would require bookkeeping. */
2196 if (DEBUG_INSN_P (insn)
2197 && BLOCK_FOR_INSN (through_insn) != BLOCK_FOR_INSN (insn)
2198 && moving_insn_creates_bookkeeping_block_p (insn, through_insn))
2199 return MOVEUP_EXPR_NULL;
2200
e855c69d
AB
2201 /* Deal with data dependencies. */
2202 was_target_conflict = false;
2203 full_ds = has_dependence_p (expr, through_insn, &has_dep_p);
2204 if (full_ds == 0)
2205 {
2206 if (!CANT_MOVE_TRAPPING (expr, through_insn))
2207 return MOVEUP_EXPR_SAME;
2208 }
2209 else
2210 {
b8698a0f 2211 /* We can move UNIQUE insn up only as a whole and unchanged,
e855c69d
AB
2212 so it shouldn't have any dependencies. */
2213 if (VINSN_UNIQUE_P (vi))
2214 return MOVEUP_EXPR_NULL;
2215 }
2216
2217 if (full_ds != 0 && can_speculate_dep_p (full_ds))
2218 {
2219 int res;
2220
2221 res = speculate_expr (expr, full_ds);
2222 if (res >= 0)
2223 {
2224 /* Speculation was successful. */
2225 full_ds = 0;
2226 was_changed = (res > 0);
2227 if (res == 2)
2228 was_target_conflict = true;
2229 if (ptrans_type)
2230 *ptrans_type = TRANS_SPECULATION;
2231 sel_clear_has_dependence ();
2232 }
2233 }
2234
2235 if (has_dep_p[DEPS_IN_INSN])
2236 /* We have some dependency that cannot be discarded. */
2237 return MOVEUP_EXPR_NULL;
2238
2239 if (has_dep_p[DEPS_IN_LHS])
b8698a0f 2240 {
e855c69d 2241 /* Only separable insns can be moved up with the new register.
b8698a0f 2242 Anyways, we should mark that the original register is
e855c69d
AB
2243 unavailable. */
2244 if (!enable_schedule_as_rhs_p || !EXPR_SEPARABLE_P (expr))
2245 return MOVEUP_EXPR_NULL;
2246
2247 EXPR_TARGET_AVAILABLE (expr) = false;
2248 was_target_conflict = true;
2249 as_rhs = true;
2250 }
2251
2252 /* At this point we have either separable insns, that will be lifted
2253 up only as RHSes, or non-separable insns with no dependency in lhs.
2254 If dependency is in RHS, then try to perform substitution and move up
2255 substituted RHS:
2256
2257 Ex. 1: Ex.2
2258 y = x; y = x;
2259 z = y*2; y = y*2;
2260
b8698a0f 2261 In Ex.1 y*2 can be substituted for x*2 and the whole operation can be
e855c69d
AB
2262 moved above y=x assignment as z=x*2.
2263
b8698a0f 2264 In Ex.2 y*2 also can be substituted for x*2, but only the right hand
e855c69d
AB
2265 side can be moved because of the output dependency. The operation was
2266 cropped to its rhs above. */
2267 if (has_dep_p[DEPS_IN_RHS])
2268 {
2269 ds_t *rhs_dsp = &has_dep_p[DEPS_IN_RHS];
2270
2271 /* Can't substitute UNIQUE VINSNs. */
2272 gcc_assert (!VINSN_UNIQUE_P (vi));
2273
2274 if (can_speculate_dep_p (*rhs_dsp))
2275 {
2276 int res;
b8698a0f 2277
e855c69d
AB
2278 res = speculate_expr (expr, *rhs_dsp);
2279 if (res >= 0)
2280 {
2281 /* Speculation was successful. */
2282 *rhs_dsp = 0;
2283 was_changed = (res > 0);
2284 if (res == 2)
2285 was_target_conflict = true;
2286 if (ptrans_type)
2287 *ptrans_type = TRANS_SPECULATION;
2288 }
2289 else
2290 return MOVEUP_EXPR_NULL;
2291 }
2292 else if (can_substitute_through_p (through_insn,
2293 *rhs_dsp)
2294 && substitute_reg_in_expr (expr, through_insn, false))
2295 {
2296 /* ??? We cannot perform substitution AND speculation on the same
2297 insn. */
2298 gcc_assert (!was_changed);
2299 was_changed = true;
2300 if (ptrans_type)
2301 *ptrans_type = TRANS_SUBSTITUTION;
2302 EXPR_WAS_SUBSTITUTED (expr) = true;
2303 }
2304 else
2305 return MOVEUP_EXPR_NULL;
2306 }
2307
2308 /* Don't move trapping insns through jumps.
2309 This check should be at the end to give a chance to control speculation
2310 to perform its duties. */
2311 if (CANT_MOVE_TRAPPING (expr, through_insn))
2312 return MOVEUP_EXPR_NULL;
2313
b8698a0f
L
2314 return (was_changed
2315 ? MOVEUP_EXPR_CHANGED
2316 : (as_rhs
e855c69d
AB
2317 ? MOVEUP_EXPR_AS_RHS
2318 : MOVEUP_EXPR_SAME));
2319}
2320
b8698a0f 2321/* Try to look at bitmap caches for EXPR and INSN pair, return true
e855c69d
AB
2322 if successful. When INSIDE_INSN_GROUP, also try ignore dependencies
2323 that can exist within a parallel group. Write to RES the resulting
2324 code for moveup_expr. */
b8698a0f 2325static bool
e855c69d
AB
2326try_bitmap_cache (expr_t expr, insn_t insn,
2327 bool inside_insn_group,
2328 enum MOVEUP_EXPR_CODE *res)
2329{
2330 int expr_uid = INSN_UID (EXPR_INSN_RTX (expr));
b8698a0f 2331
e855c69d
AB
2332 /* First check whether we've analyzed this situation already. */
2333 if (bitmap_bit_p (INSN_ANALYZED_DEPS (insn), expr_uid))
2334 {
2335 if (bitmap_bit_p (INSN_FOUND_DEPS (insn), expr_uid))
2336 {
2337 if (sched_verbose >= 6)
2338 sel_print ("removed (cached)\n");
2339 *res = MOVEUP_EXPR_NULL;
2340 return true;
2341 }
2342 else
2343 {
2344 if (sched_verbose >= 6)
2345 sel_print ("unchanged (cached)\n");
2346 *res = MOVEUP_EXPR_SAME;
2347 return true;
2348 }
2349 }
2350 else if (bitmap_bit_p (INSN_FOUND_DEPS (insn), expr_uid))
2351 {
2352 if (inside_insn_group)
2353 {
2354 if (sched_verbose >= 6)
2355 sel_print ("unchanged (as RHS, cached, inside insn group)\n");
2356 *res = MOVEUP_EXPR_SAME;
2357 return true;
b8698a0f 2358
e855c69d
AB
2359 }
2360 else
2361 EXPR_TARGET_AVAILABLE (expr) = false;
2362
b8698a0f
L
2363 /* This is the only case when propagation result can change over time,
2364 as we can dynamically switch off scheduling as RHS. In this case,
e855c69d
AB
2365 just check the flag to reach the correct decision. */
2366 if (enable_schedule_as_rhs_p)
2367 {
2368 if (sched_verbose >= 6)
2369 sel_print ("unchanged (as RHS, cached)\n");
2370 *res = MOVEUP_EXPR_AS_RHS;
2371 return true;
2372 }
2373 else
2374 {
2375 if (sched_verbose >= 6)
2376 sel_print ("removed (cached as RHS, but renaming"
2377 " is now disabled)\n");
2378 *res = MOVEUP_EXPR_NULL;
2379 return true;
2380 }
2381 }
2382
2383 return false;
2384}
2385
b8698a0f 2386/* Try to look at bitmap caches for EXPR and INSN pair, return true
e855c69d 2387 if successful. Write to RES the resulting code for moveup_expr. */
b8698a0f 2388static bool
e855c69d
AB
2389try_transformation_cache (expr_t expr, insn_t insn,
2390 enum MOVEUP_EXPR_CODE *res)
2391{
b8698a0f 2392 struct transformed_insns *pti
e855c69d
AB
2393 = (struct transformed_insns *)
2394 htab_find_with_hash (INSN_TRANSFORMED_INSNS (insn),
b8698a0f 2395 &EXPR_VINSN (expr),
e855c69d
AB
2396 VINSN_HASH_RTX (EXPR_VINSN (expr)));
2397 if (pti)
2398 {
b8698a0f
L
2399 /* This EXPR was already moved through this insn and was
2400 changed as a result. Fetch the proper data from
e855c69d 2401 the hashtable. */
b8698a0f
L
2402 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (expr),
2403 INSN_UID (insn), pti->type,
2404 pti->vinsn_old, pti->vinsn_new,
e855c69d 2405 EXPR_SPEC_DONE_DS (expr));
b8698a0f 2406
e855c69d
AB
2407 if (INSN_IN_STREAM_P (VINSN_INSN_RTX (pti->vinsn_new)))
2408 pti->vinsn_new = vinsn_copy (pti->vinsn_new, true);
2409 change_vinsn_in_expr (expr, pti->vinsn_new);
2410 if (pti->was_target_conflict)
2411 EXPR_TARGET_AVAILABLE (expr) = false;
2412 if (pti->type == TRANS_SPECULATION)
2413 {
2414 ds_t ds;
2415
2416 ds = EXPR_SPEC_DONE_DS (expr);
b8698a0f 2417
e855c69d
AB
2418 EXPR_SPEC_DONE_DS (expr) = pti->ds;
2419 EXPR_NEEDS_SPEC_CHECK_P (expr) |= pti->needs_check;
2420 }
2421
2422 if (sched_verbose >= 6)
2423 {
2424 sel_print ("changed (cached): ");
2425 dump_expr (expr);
2426 sel_print ("\n");
2427 }
2428
2429 *res = MOVEUP_EXPR_CHANGED;
2430 return true;
2431 }
2432
2433 return false;
2434}
2435
2436/* Update bitmap caches on INSN with result RES of propagating EXPR. */
2437static void
b8698a0f 2438update_bitmap_cache (expr_t expr, insn_t insn, bool inside_insn_group,
e855c69d
AB
2439 enum MOVEUP_EXPR_CODE res)
2440{
2441 int expr_uid = INSN_UID (EXPR_INSN_RTX (expr));
2442
b8698a0f 2443 /* Do not cache result of propagating jumps through an insn group,
e855c69d
AB
2444 as it is always true, which is not useful outside the group. */
2445 if (inside_insn_group)
2446 return;
b8698a0f 2447
e855c69d
AB
2448 if (res == MOVEUP_EXPR_NULL)
2449 {
2450 bitmap_set_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
2451 bitmap_set_bit (INSN_FOUND_DEPS (insn), expr_uid);
2452 }
2453 else if (res == MOVEUP_EXPR_SAME)
2454 {
2455 bitmap_set_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
2456 bitmap_clear_bit (INSN_FOUND_DEPS (insn), expr_uid);
2457 }
2458 else if (res == MOVEUP_EXPR_AS_RHS)
2459 {
2460 bitmap_clear_bit (INSN_ANALYZED_DEPS (insn), expr_uid);
2461 bitmap_set_bit (INSN_FOUND_DEPS (insn), expr_uid);
2462 }
2463 else
2464 gcc_unreachable ();
2465}
2466
2467/* Update hashtable on INSN with changed EXPR, old EXPR_OLD_VINSN
2468 and transformation type TRANS_TYPE. */
2469static void
b8698a0f 2470update_transformation_cache (expr_t expr, insn_t insn,
e855c69d 2471 bool inside_insn_group,
b8698a0f 2472 enum local_trans_type trans_type,
e855c69d
AB
2473 vinsn_t expr_old_vinsn)
2474{
2475 struct transformed_insns *pti;
2476
2477 if (inside_insn_group)
2478 return;
b8698a0f 2479
e855c69d
AB
2480 pti = XNEW (struct transformed_insns);
2481 pti->vinsn_old = expr_old_vinsn;
2482 pti->vinsn_new = EXPR_VINSN (expr);
2483 pti->type = trans_type;
2484 pti->was_target_conflict = was_target_conflict;
2485 pti->ds = EXPR_SPEC_DONE_DS (expr);
2486 pti->needs_check = EXPR_NEEDS_SPEC_CHECK_P (expr);
2487 vinsn_attach (pti->vinsn_old);
2488 vinsn_attach (pti->vinsn_new);
b8698a0f 2489 *((struct transformed_insns **)
e855c69d
AB
2490 htab_find_slot_with_hash (INSN_TRANSFORMED_INSNS (insn),
2491 pti, VINSN_HASH_RTX (expr_old_vinsn),
2492 INSERT)) = pti;
2493}
2494
b8698a0f 2495/* Same as moveup_expr, but first looks up the result of
e855c69d
AB
2496 transformation in caches. */
2497static enum MOVEUP_EXPR_CODE
2498moveup_expr_cached (expr_t expr, insn_t insn, bool inside_insn_group)
2499{
2500 enum MOVEUP_EXPR_CODE res;
2501 bool got_answer = false;
2502
2503 if (sched_verbose >= 6)
2504 {
b8698a0f 2505 sel_print ("Moving ");
e855c69d
AB
2506 dump_expr (expr);
2507 sel_print (" through %d: ", INSN_UID (insn));
2508 }
2509
b5b8b0ac
AO
2510 if (DEBUG_INSN_P (EXPR_INSN_RTX (expr))
2511 && (sel_bb_head (BLOCK_FOR_INSN (EXPR_INSN_RTX (expr)))
2512 == EXPR_INSN_RTX (expr)))
2513 /* Don't use cached information for debug insns that are heads of
2514 basic blocks. */;
2515 else if (try_bitmap_cache (expr, insn, inside_insn_group, &res))
e855c69d
AB
2516 /* When inside insn group, we do not want remove stores conflicting
2517 with previosly issued loads. */
2518 got_answer = ! inside_insn_group || res != MOVEUP_EXPR_NULL;
2519 else if (try_transformation_cache (expr, insn, &res))
2520 got_answer = true;
2521
2522 if (! got_answer)
2523 {
2524 /* Invoke moveup_expr and record the results. */
2525 vinsn_t expr_old_vinsn = EXPR_VINSN (expr);
2526 ds_t expr_old_spec_ds = EXPR_SPEC_DONE_DS (expr);
2527 int expr_uid = INSN_UID (VINSN_INSN_RTX (expr_old_vinsn));
2528 bool unique_p = VINSN_UNIQUE_P (expr_old_vinsn);
2529 enum local_trans_type trans_type = TRANS_SUBSTITUTION;
2530
b8698a0f 2531 /* ??? Invent something better than this. We can't allow old_vinsn
e855c69d
AB
2532 to go, we need it for the history vector. */
2533 vinsn_attach (expr_old_vinsn);
2534
2535 res = moveup_expr (expr, insn, inside_insn_group,
2536 &trans_type);
2537 switch (res)
2538 {
2539 case MOVEUP_EXPR_NULL:
2540 update_bitmap_cache (expr, insn, inside_insn_group, res);
2541 if (sched_verbose >= 6)
2542 sel_print ("removed\n");
2543 break;
2544
2545 case MOVEUP_EXPR_SAME:
2546 update_bitmap_cache (expr, insn, inside_insn_group, res);
2547 if (sched_verbose >= 6)
2548 sel_print ("unchanged\n");
2549 break;
2550
2551 case MOVEUP_EXPR_AS_RHS:
2552 gcc_assert (!unique_p || inside_insn_group);
2553 update_bitmap_cache (expr, insn, inside_insn_group, res);
2554 if (sched_verbose >= 6)
2555 sel_print ("unchanged (as RHS)\n");
2556 break;
2557
2558 case MOVEUP_EXPR_CHANGED:
2559 gcc_assert (INSN_UID (EXPR_INSN_RTX (expr)) != expr_uid
2560 || EXPR_SPEC_DONE_DS (expr) != expr_old_spec_ds);
b8698a0f
L
2561 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (expr),
2562 INSN_UID (insn), trans_type,
2563 expr_old_vinsn, EXPR_VINSN (expr),
e855c69d
AB
2564 expr_old_spec_ds);
2565 update_transformation_cache (expr, insn, inside_insn_group,
2566 trans_type, expr_old_vinsn);
2567 if (sched_verbose >= 6)
2568 {
2569 sel_print ("changed: ");
2570 dump_expr (expr);
2571 sel_print ("\n");
2572 }
2573 break;
2574 default:
2575 gcc_unreachable ();
2576 }
2577
2578 vinsn_detach (expr_old_vinsn);
2579 }
2580
2581 return res;
2582}
2583
b8698a0f 2584/* Moves an av set AVP up through INSN, performing necessary
e855c69d
AB
2585 transformations. */
2586static void
2587moveup_set_expr (av_set_t *avp, insn_t insn, bool inside_insn_group)
2588{
2589 av_set_iterator i;
2590 expr_t expr;
2591
b8698a0f
L
2592 FOR_EACH_EXPR_1 (expr, i, avp)
2593 {
2594
e855c69d
AB
2595 switch (moveup_expr_cached (expr, insn, inside_insn_group))
2596 {
2597 case MOVEUP_EXPR_SAME:
2598 case MOVEUP_EXPR_AS_RHS:
2599 break;
2600
2601 case MOVEUP_EXPR_NULL:
2602 av_set_iter_remove (&i);
2603 break;
2604
2605 case MOVEUP_EXPR_CHANGED:
2606 expr = merge_with_other_exprs (avp, &i, expr);
2607 break;
b8698a0f 2608
e855c69d
AB
2609 default:
2610 gcc_unreachable ();
2611 }
2612 }
2613}
2614
2615/* Moves AVP set along PATH. */
2616static void
2617moveup_set_inside_insn_group (av_set_t *avp, ilist_t path)
2618{
2619 int last_cycle;
b8698a0f 2620
e855c69d
AB
2621 if (sched_verbose >= 6)
2622 sel_print ("Moving expressions up in the insn group...\n");
2623 if (! path)
2624 return;
2625 last_cycle = INSN_SCHED_CYCLE (ILIST_INSN (path));
b8698a0f 2626 while (path
e855c69d
AB
2627 && INSN_SCHED_CYCLE (ILIST_INSN (path)) == last_cycle)
2628 {
2629 moveup_set_expr (avp, ILIST_INSN (path), true);
2630 path = ILIST_NEXT (path);
2631 }
2632}
2633
2634/* Returns true if after moving EXPR along PATH it equals to EXPR_VLIW. */
2635static bool
2636equal_after_moveup_path_p (expr_t expr, ilist_t path, expr_t expr_vliw)
2637{
2638 expr_def _tmp, *tmp = &_tmp;
2639 int last_cycle;
2640 bool res = true;
2641
2642 copy_expr_onside (tmp, expr);
2643 last_cycle = path ? INSN_SCHED_CYCLE (ILIST_INSN (path)) : 0;
b8698a0f 2644 while (path
e855c69d
AB
2645 && res
2646 && INSN_SCHED_CYCLE (ILIST_INSN (path)) == last_cycle)
2647 {
b8698a0f 2648 res = (moveup_expr_cached (tmp, ILIST_INSN (path), true)
e855c69d
AB
2649 != MOVEUP_EXPR_NULL);
2650 path = ILIST_NEXT (path);
2651 }
2652
2653 if (res)
2654 {
2655 vinsn_t tmp_vinsn = EXPR_VINSN (tmp);
2656 vinsn_t expr_vliw_vinsn = EXPR_VINSN (expr_vliw);
2657
2658 if (tmp_vinsn != expr_vliw_vinsn)
2659 res = vinsn_equal_p (tmp_vinsn, expr_vliw_vinsn);
2660 }
2661
2662 clear_expr (tmp);
2663 return res;
2664}
2665\f
2666
2667/* Functions that compute av and lv sets. */
2668
b8698a0f 2669/* Returns true if INSN is not a downward continuation of the given path P in
e855c69d
AB
2670 the current stage. */
2671static bool
2672is_ineligible_successor (insn_t insn, ilist_t p)
2673{
2674 insn_t prev_insn;
2675
2676 /* Check if insn is not deleted. */
2677 if (PREV_INSN (insn) && NEXT_INSN (PREV_INSN (insn)) != insn)
2678 gcc_unreachable ();
2679 else if (NEXT_INSN (insn) && PREV_INSN (NEXT_INSN (insn)) != insn)
2680 gcc_unreachable ();
2681
2682 /* If it's the first insn visited, then the successor is ok. */
2683 if (!p)
2684 return false;
2685
2686 prev_insn = ILIST_INSN (p);
2687
2688 if (/* a backward edge. */
2689 INSN_SEQNO (insn) < INSN_SEQNO (prev_insn)
2690 /* is already visited. */
2691 || (INSN_SEQNO (insn) == INSN_SEQNO (prev_insn)
2692 && (ilist_is_in_p (p, insn)
b8698a0f
L
2693 /* We can reach another fence here and still seqno of insn
2694 would be equal to seqno of prev_insn. This is possible
e855c69d
AB
2695 when prev_insn is a previously created bookkeeping copy.
2696 In that case it'd get a seqno of insn. Thus, check here
2697 whether insn is in current fence too. */
2698 || IN_CURRENT_FENCE_P (insn)))
2699 /* Was already scheduled on this round. */
2700 || (INSN_SEQNO (insn) > INSN_SEQNO (prev_insn)
2701 && IN_CURRENT_FENCE_P (insn))
b8698a0f
L
2702 /* An insn from another fence could also be
2703 scheduled earlier even if this insn is not in
e855c69d
AB
2704 a fence list right now. Check INSN_SCHED_CYCLE instead. */
2705 || (!pipelining_p
2706 && INSN_SCHED_TIMES (insn) > 0))
2707 return true;
2708 else
2709 return false;
2710}
2711
b8698a0f
L
2712/* Computes the av_set below the last bb insn INSN, doing all the 'dirty work'
2713 of handling multiple successors and properly merging its av_sets. P is
2714 the current path traversed. WS is the size of lookahead window.
e855c69d
AB
2715 Return the av set computed. */
2716static av_set_t
2717compute_av_set_at_bb_end (insn_t insn, ilist_t p, int ws)
2718{
2719 struct succs_info *sinfo;
2720 av_set_t expr_in_all_succ_branches = NULL;
2721 int is;
2722 insn_t succ, zero_succ = NULL;
2723 av_set_t av1 = NULL;
2724
2725 gcc_assert (sel_bb_end_p (insn));
2726
b8698a0f 2727 /* Find different kind of successors needed for correct computing of
e855c69d
AB
2728 SPEC and TARGET_AVAILABLE attributes. */
2729 sinfo = compute_succs_info (insn, SUCCS_NORMAL);
2730
2731 /* Debug output. */
2732 if (sched_verbose >= 6)
2733 {
2734 sel_print ("successors of bb end (%d): ", INSN_UID (insn));
2735 dump_insn_vector (sinfo->succs_ok);
2736 sel_print ("\n");
2737 if (sinfo->succs_ok_n != sinfo->all_succs_n)
2738 sel_print ("real successors num: %d\n", sinfo->all_succs_n);
2739 }
2740
2741 /* Add insn to to the tail of current path. */
2742 ilist_add (&p, insn);
2743
2744 for (is = 0; VEC_iterate (rtx, sinfo->succs_ok, is, succ); is++)
2745 {
2746 av_set_t succ_set;
2747
2748 /* We will edit SUCC_SET and EXPR_SPEC field of its elements. */
2749 succ_set = compute_av_set_inside_bb (succ, p, ws, true);
2750
b8698a0f
L
2751 av_set_split_usefulness (succ_set,
2752 VEC_index (int, sinfo->probs_ok, is),
e855c69d
AB
2753 sinfo->all_prob);
2754
b8698a0f 2755 if (sinfo->all_succs_n > 1
e855c69d
AB
2756 && sinfo->all_succs_n == sinfo->succs_ok_n)
2757 {
b8698a0f 2758 /* Find EXPR'es that came from *all* successors and save them
e855c69d
AB
2759 into expr_in_all_succ_branches. This set will be used later
2760 for calculating speculation attributes of EXPR'es. */
2761 if (is == 0)
2762 {
2763 expr_in_all_succ_branches = av_set_copy (succ_set);
2764
2765 /* Remember the first successor for later. */
2766 zero_succ = succ;
2767 }
2768 else
2769 {
2770 av_set_iterator i;
2771 expr_t expr;
b8698a0f 2772
e855c69d
AB
2773 FOR_EACH_EXPR_1 (expr, i, &expr_in_all_succ_branches)
2774 if (!av_set_is_in_p (succ_set, EXPR_VINSN (expr)))
2775 av_set_iter_remove (&i);
2776 }
2777 }
2778
2779 /* Union the av_sets. Check liveness restrictions on target registers
2780 in special case of two successors. */
2781 if (sinfo->succs_ok_n == 2 && is == 1)
2782 {
2783 basic_block bb0 = BLOCK_FOR_INSN (zero_succ);
2784 basic_block bb1 = BLOCK_FOR_INSN (succ);
2785
2786 gcc_assert (BB_LV_SET_VALID_P (bb0) && BB_LV_SET_VALID_P (bb1));
b8698a0f 2787 av_set_union_and_live (&av1, &succ_set,
e855c69d
AB
2788 BB_LV_SET (bb0),
2789 BB_LV_SET (bb1),
2790 insn);
2791 }
2792 else
2793 av_set_union_and_clear (&av1, &succ_set, insn);
2794 }
2795
b8698a0f 2796 /* Check liveness restrictions via hard way when there are more than
e855c69d
AB
2797 two successors. */
2798 if (sinfo->succs_ok_n > 2)
2799 for (is = 0; VEC_iterate (rtx, sinfo->succs_ok, is, succ); is++)
2800 {
2801 basic_block succ_bb = BLOCK_FOR_INSN (succ);
b8698a0f 2802
e855c69d 2803 gcc_assert (BB_LV_SET_VALID_P (succ_bb));
b8698a0f 2804 mark_unavailable_targets (av1, BB_AV_SET (succ_bb),
e855c69d
AB
2805 BB_LV_SET (succ_bb));
2806 }
b8698a0f
L
2807
2808 /* Finally, check liveness restrictions on paths leaving the region. */
e855c69d
AB
2809 if (sinfo->all_succs_n > sinfo->succs_ok_n)
2810 for (is = 0; VEC_iterate (rtx, sinfo->succs_other, is, succ); is++)
b8698a0f 2811 mark_unavailable_targets
e855c69d
AB
2812 (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ)));
2813
2814 if (sinfo->all_succs_n > 1)
2815 {
2816 av_set_iterator i;
2817 expr_t expr;
2818
b8698a0f 2819 /* Increase the spec attribute of all EXPR'es that didn't come
e855c69d
AB
2820 from all successors. */
2821 FOR_EACH_EXPR (expr, i, av1)
2822 if (!av_set_is_in_p (expr_in_all_succ_branches, EXPR_VINSN (expr)))
2823 EXPR_SPEC (expr)++;
2824
2825 av_set_clear (&expr_in_all_succ_branches);
b8698a0f
L
2826
2827 /* Do not move conditional branches through other
2828 conditional branches. So, remove all conditional
e855c69d
AB
2829 branches from av_set if current operator is a conditional
2830 branch. */
2831 av_set_substract_cond_branches (&av1);
2832 }
b8698a0f 2833
e855c69d
AB
2834 ilist_remove (&p);
2835 free_succs_info (sinfo);
2836
2837 if (sched_verbose >= 6)
2838 {
2839 sel_print ("av_succs (%d): ", INSN_UID (insn));
2840 dump_av_set (av1);
2841 sel_print ("\n");
2842 }
2843
2844 return av1;
2845}
2846
b8698a0f
L
2847/* This function computes av_set for the FIRST_INSN by dragging valid
2848 av_set through all basic block insns either from the end of basic block
2849 (computed using compute_av_set_at_bb_end) or from the insn on which
e855c69d
AB
2850 MAX_WS was exceeded. It uses compute_av_set_at_bb_end to compute av_set
2851 below the basic block and handling conditional branches.
2852 FIRST_INSN - the basic block head, P - path consisting of the insns
2853 traversed on the way to the FIRST_INSN (the path is sparse, only bb heads
2854 and bb ends are added to the path), WS - current window size,
2855 NEED_COPY_P - true if we'll make a copy of av_set before returning it. */
2856static av_set_t
b8698a0f 2857compute_av_set_inside_bb (insn_t first_insn, ilist_t p, int ws,
e855c69d
AB
2858 bool need_copy_p)
2859{
2860 insn_t cur_insn;
2861 int end_ws = ws;
2862 insn_t bb_end = sel_bb_end (BLOCK_FOR_INSN (first_insn));
2863 insn_t after_bb_end = NEXT_INSN (bb_end);
2864 insn_t last_insn;
2865 av_set_t av = NULL;
2866 basic_block cur_bb = BLOCK_FOR_INSN (first_insn);
2867
2868 /* Return NULL if insn is not on the legitimate downward path. */
2869 if (is_ineligible_successor (first_insn, p))
2870 {
2871 if (sched_verbose >= 6)
2872 sel_print ("Insn %d is ineligible_successor\n", INSN_UID (first_insn));
2873
2874 return NULL;
2875 }
2876
b8698a0f 2877 /* If insn already has valid av(insn) computed, just return it. */
e855c69d
AB
2878 if (AV_SET_VALID_P (first_insn))
2879 {
2880 av_set_t av_set;
2881
2882 if (sel_bb_head_p (first_insn))
2883 av_set = BB_AV_SET (BLOCK_FOR_INSN (first_insn));
2884 else
2885 av_set = NULL;
2886
2887 if (sched_verbose >= 6)
2888 {
2889 sel_print ("Insn %d has a valid av set: ", INSN_UID (first_insn));
2890 dump_av_set (av_set);
2891 sel_print ("\n");
2892 }
2893
2894 return need_copy_p ? av_set_copy (av_set) : av_set;
2895 }
2896
2897 ilist_add (&p, first_insn);
2898
2899 /* As the result after this loop have completed, in LAST_INSN we'll
b8698a0f
L
2900 have the insn which has valid av_set to start backward computation
2901 from: it either will be NULL because on it the window size was exceeded
2902 or other valid av_set as returned by compute_av_set for the last insn
e855c69d
AB
2903 of the basic block. */
2904 for (last_insn = first_insn; last_insn != after_bb_end;
2905 last_insn = NEXT_INSN (last_insn))
2906 {
2907 /* We may encounter valid av_set not only on bb_head, but also on
2908 those insns on which previously MAX_WS was exceeded. */
2909 if (AV_SET_VALID_P (last_insn))
2910 {
2911 if (sched_verbose >= 6)
2912 sel_print ("Insn %d has a valid empty av set\n", INSN_UID (last_insn));
2913 break;
2914 }
2915
2916 /* The special case: the last insn of the BB may be an
2917 ineligible_successor due to its SEQ_NO that was set on
2918 it as a bookkeeping. */
b8698a0f 2919 if (last_insn != first_insn
e855c69d
AB
2920 && is_ineligible_successor (last_insn, p))
2921 {
2922 if (sched_verbose >= 6)
2923 sel_print ("Insn %d is ineligible_successor\n", INSN_UID (last_insn));
b8698a0f 2924 break;
e855c69d
AB
2925 }
2926
b5b8b0ac
AO
2927 if (DEBUG_INSN_P (last_insn))
2928 continue;
2929
e855c69d
AB
2930 if (end_ws > max_ws)
2931 {
b8698a0f 2932 /* We can reach max lookahead size at bb_header, so clean av_set
e855c69d
AB
2933 first. */
2934 INSN_WS_LEVEL (last_insn) = global_level;
2935
2936 if (sched_verbose >= 6)
2937 sel_print ("Insn %d is beyond the software lookahead window size\n",
2938 INSN_UID (last_insn));
2939 break;
2940 }
2941
2942 end_ws++;
2943 }
2944
2945 /* Get the valid av_set into AV above the LAST_INSN to start backward
2946 computation from. It either will be empty av_set or av_set computed from
2947 the successors on the last insn of the current bb. */
2948 if (last_insn != after_bb_end)
2949 {
2950 av = NULL;
2951
b8698a0f 2952 /* This is needed only to obtain av_sets that are identical to
e855c69d
AB
2953 those computed by the old compute_av_set version. */
2954 if (last_insn == first_insn && !INSN_NOP_P (last_insn))
2955 av_set_add (&av, INSN_EXPR (last_insn));
2956 }
2957 else
2958 /* END_WS is always already increased by 1 if LAST_INSN == AFTER_BB_END. */
2959 av = compute_av_set_at_bb_end (bb_end, p, end_ws);
2960
2961 /* Compute av_set in AV starting from below the LAST_INSN up to
2962 location above the FIRST_INSN. */
2963 for (cur_insn = PREV_INSN (last_insn); cur_insn != PREV_INSN (first_insn);
b8698a0f 2964 cur_insn = PREV_INSN (cur_insn))
e855c69d
AB
2965 if (!INSN_NOP_P (cur_insn))
2966 {
2967 expr_t expr;
b8698a0f 2968
e855c69d 2969 moveup_set_expr (&av, cur_insn, false);
b8698a0f
L
2970
2971 /* If the expression for CUR_INSN is already in the set,
e855c69d 2972 replace it by the new one. */
b8698a0f 2973 expr = av_set_lookup (av, INSN_VINSN (cur_insn));
e855c69d
AB
2974 if (expr != NULL)
2975 {
2976 clear_expr (expr);
2977 copy_expr (expr, INSN_EXPR (cur_insn));
2978 }
2979 else
2980 av_set_add (&av, INSN_EXPR (cur_insn));
2981 }
2982
2983 /* Clear stale bb_av_set. */
2984 if (sel_bb_head_p (first_insn))
2985 {
2986 av_set_clear (&BB_AV_SET (cur_bb));
2987 BB_AV_SET (cur_bb) = need_copy_p ? av_set_copy (av) : av;
2988 BB_AV_LEVEL (cur_bb) = global_level;
2989 }
2990
2991 if (sched_verbose >= 6)
2992 {
2993 sel_print ("Computed av set for insn %d: ", INSN_UID (first_insn));
2994 dump_av_set (av);
2995 sel_print ("\n");
2996 }
2997
2998 ilist_remove (&p);
2999 return av;
3000}
3001
3002/* Compute av set before INSN.
3003 INSN - the current operation (actual rtx INSN)
3004 P - the current path, which is list of insns visited so far
3005 WS - software lookahead window size.
3006 UNIQUE_P - TRUE, if returned av_set will be changed, hence
3007 if we want to save computed av_set in s_i_d, we should make a copy of it.
3008
3009 In the resulting set we will have only expressions that don't have delay
3010 stalls and nonsubstitutable dependences. */
3011static av_set_t
3012compute_av_set (insn_t insn, ilist_t p, int ws, bool unique_p)
3013{
3014 return compute_av_set_inside_bb (insn, p, ws, unique_p);
3015}
3016
3017/* Propagate a liveness set LV through INSN. */
3018static void
3019propagate_lv_set (regset lv, insn_t insn)
3020{
3021 gcc_assert (INSN_P (insn));
3022
3023 if (INSN_NOP_P (insn))
3024 return;
3025
02b47899 3026 df_simulate_one_insn_backwards (BLOCK_FOR_INSN (insn), insn, lv);
e855c69d
AB
3027}
3028
3029/* Return livness set at the end of BB. */
3030static regset
3031compute_live_after_bb (basic_block bb)
3032{
3033 edge e;
3034 edge_iterator ei;
3035 regset lv = get_clear_regset_from_pool ();
3036
3037 gcc_assert (!ignore_first);
3038
3039 FOR_EACH_EDGE (e, ei, bb->succs)
3040 if (sel_bb_empty_p (e->dest))
3041 {
3042 if (! BB_LV_SET_VALID_P (e->dest))
3043 {
3044 gcc_unreachable ();
3045 gcc_assert (BB_LV_SET (e->dest) == NULL);
3046 BB_LV_SET (e->dest) = compute_live_after_bb (e->dest);
3047 BB_LV_SET_VALID_P (e->dest) = true;
3048 }
3049 IOR_REG_SET (lv, BB_LV_SET (e->dest));
3050 }
3051 else
3052 IOR_REG_SET (lv, compute_live (sel_bb_head (e->dest)));
3053
3054 return lv;
3055}
3056
3057/* Compute the set of all live registers at the point before INSN and save
3058 it at INSN if INSN is bb header. */
3059regset
3060compute_live (insn_t insn)
3061{
3062 basic_block bb = BLOCK_FOR_INSN (insn);
3063 insn_t final, temp;
3064 regset lv;
3065
3066 /* Return the valid set if we're already on it. */
3067 if (!ignore_first)
3068 {
3069 regset src = NULL;
b8698a0f 3070
e855c69d
AB
3071 if (sel_bb_head_p (insn) && BB_LV_SET_VALID_P (bb))
3072 src = BB_LV_SET (bb);
b8698a0f 3073 else
e855c69d
AB
3074 {
3075 gcc_assert (in_current_region_p (bb));
3076 if (INSN_LIVE_VALID_P (insn))
3077 src = INSN_LIVE (insn);
3078 }
b8698a0f 3079
e855c69d
AB
3080 if (src)
3081 {
3082 lv = get_regset_from_pool ();
3083 COPY_REG_SET (lv, src);
3084
3085 if (sel_bb_head_p (insn) && ! BB_LV_SET_VALID_P (bb))
3086 {
3087 COPY_REG_SET (BB_LV_SET (bb), lv);
3088 BB_LV_SET_VALID_P (bb) = true;
3089 }
b8698a0f 3090
e855c69d
AB
3091 return_regset_to_pool (lv);
3092 return lv;
3093 }
3094 }
3095
3096 /* We've skipped the wrong lv_set. Don't skip the right one. */
3097 ignore_first = false;
3098 gcc_assert (in_current_region_p (bb));
3099
b8698a0f
L
3100 /* Find a valid LV set in this block or below, if needed.
3101 Start searching from the next insn: either ignore_first is true, or
e855c69d
AB
3102 INSN doesn't have a correct live set. */
3103 temp = NEXT_INSN (insn);
3104 final = NEXT_INSN (BB_END (bb));
3105 while (temp != final && ! INSN_LIVE_VALID_P (temp))
3106 temp = NEXT_INSN (temp);
3107 if (temp == final)
3108 {
3109 lv = compute_live_after_bb (bb);
3110 temp = PREV_INSN (temp);
3111 }
3112 else
3113 {
3114 lv = get_regset_from_pool ();
3115 COPY_REG_SET (lv, INSN_LIVE (temp));
3116 }
3117
3118 /* Put correct lv sets on the insns which have bad sets. */
3119 final = PREV_INSN (insn);
3120 while (temp != final)
3121 {
3122 propagate_lv_set (lv, temp);
3123 COPY_REG_SET (INSN_LIVE (temp), lv);
3124 INSN_LIVE_VALID_P (temp) = true;
3125 temp = PREV_INSN (temp);
3126 }
3127
3128 /* Also put it in a BB. */
3129 if (sel_bb_head_p (insn))
3130 {
3131 basic_block bb = BLOCK_FOR_INSN (insn);
b8698a0f 3132
e855c69d
AB
3133 COPY_REG_SET (BB_LV_SET (bb), lv);
3134 BB_LV_SET_VALID_P (bb) = true;
3135 }
b8698a0f 3136
e855c69d
AB
3137 /* We return LV to the pool, but will not clear it there. Thus we can
3138 legimatelly use LV till the next use of regset_pool_get (). */
3139 return_regset_to_pool (lv);
3140 return lv;
3141}
3142
3143/* Update liveness sets for INSN. */
3144static inline void
3145update_liveness_on_insn (rtx insn)
3146{
3147 ignore_first = true;
3148 compute_live (insn);
3149}
3150
3151/* Compute liveness below INSN and write it into REGS. */
3152static inline void
3153compute_live_below_insn (rtx insn, regset regs)
3154{
3155 rtx succ;
3156 succ_iterator si;
b8698a0f
L
3157
3158 FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_ALL)
e855c69d
AB
3159 IOR_REG_SET (regs, compute_live (succ));
3160}
3161
3162/* Update the data gathered in av and lv sets starting from INSN. */
3163static void
3164update_data_sets (rtx insn)
3165{
3166 update_liveness_on_insn (insn);
3167 if (sel_bb_head_p (insn))
3168 {
3169 gcc_assert (AV_LEVEL (insn) != 0);
3170 BB_AV_LEVEL (BLOCK_FOR_INSN (insn)) = -1;
3171 compute_av_set (insn, NULL, 0, 0);
3172 }
3173}
3174\f
3175
3176/* Helper for move_op () and find_used_regs ().
3177 Return speculation type for which a check should be created on the place
3178 of INSN. EXPR is one of the original ops we are searching for. */
3179static ds_t
3180get_spec_check_type_for_insn (insn_t insn, expr_t expr)
3181{
3182 ds_t to_check_ds;
3183 ds_t already_checked_ds = EXPR_SPEC_DONE_DS (INSN_EXPR (insn));
3184
3185 to_check_ds = EXPR_SPEC_TO_CHECK_DS (expr);
3186
3187 if (targetm.sched.get_insn_checked_ds)
3188 already_checked_ds |= targetm.sched.get_insn_checked_ds (insn);
3189
3190 if (spec_info != NULL
3191 && (spec_info->flags & SEL_SCHED_SPEC_DONT_CHECK_CONTROL))
3192 already_checked_ds |= BEGIN_CONTROL;
3193
3194 already_checked_ds = ds_get_speculation_types (already_checked_ds);
3195
3196 to_check_ds &= ~already_checked_ds;
3197
3198 return to_check_ds;
3199}
3200
b8698a0f 3201/* Find the set of registers that are unavailable for storing expres
e855c69d
AB
3202 while moving ORIG_OPS up on the path starting from INSN due to
3203 liveness (USED_REGS) or hardware restrictions (REG_RENAME_P).
3204
3205 All the original operations found during the traversal are saved in the
3206 ORIGINAL_INSNS list.
3207
3208 REG_RENAME_P denotes the set of hardware registers that
3209 can not be used with renaming due to the register class restrictions,
b8698a0f 3210 mode restrictions and other (the register we'll choose should be
e855c69d
AB
3211 compatible class with the original uses, shouldn't be in call_used_regs,
3212 should be HARD_REGNO_RENAME_OK etc).
3213
3214 Returns TRUE if we've found all original insns, FALSE otherwise.
3215
3216 This function utilizes code_motion_path_driver (formerly find_used_regs_1)
b8698a0f
L
3217 to traverse the code motion paths. This helper function finds registers
3218 that are not available for storing expres while moving ORIG_OPS up on the
e855c69d
AB
3219 path starting from INSN. A register considered as used on the moving path,
3220 if one of the following conditions is not satisfied:
3221
b8698a0f
L
3222 (1) a register not set or read on any path from xi to an instance of
3223 the original operation,
3224 (2) not among the live registers of the point immediately following the
e855c69d
AB
3225 first original operation on a given downward path, except for the
3226 original target register of the operation,
b8698a0f 3227 (3) not live on the other path of any conditional branch that is passed
e855c69d
AB
3228 by the operation, in case original operations are not present on
3229 both paths of the conditional branch.
3230
3231 All the original operations found during the traversal are saved in the
3232 ORIGINAL_INSNS list.
3233
b8698a0f
L
3234 REG_RENAME_P->CROSSES_CALL is true, if there is a call insn on the path
3235 from INSN to original insn. In this case CALL_USED_REG_SET will be added
e855c69d
AB
3236 to unavailable hard regs at the point original operation is found. */
3237
3238static bool
3239find_used_regs (insn_t insn, av_set_t orig_ops, regset used_regs,
3240 struct reg_rename *reg_rename_p, def_list_t *original_insns)
3241{
3242 def_list_iterator i;
3243 def_t def;
3244 int res;
3245 bool needs_spec_check_p = false;
3246 expr_t expr;
3247 av_set_iterator expr_iter;
3248 struct fur_static_params sparams;
3249 struct cmpd_local_params lparams;
3250
3251 /* We haven't visited any blocks yet. */
3252 bitmap_clear (code_motion_visited_blocks);
3253
3254 /* Init parameters for code_motion_path_driver. */
3255 sparams.crosses_call = false;
3256 sparams.original_insns = original_insns;
3257 sparams.used_regs = used_regs;
b8698a0f 3258
e855c69d
AB
3259 /* Set the appropriate hooks and data. */
3260 code_motion_path_driver_info = &fur_hooks;
b8698a0f 3261
e855c69d
AB
3262 res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);
3263
3264 reg_rename_p->crosses_call |= sparams.crosses_call;
3265
3266 gcc_assert (res == 1);
3267 gcc_assert (original_insns && *original_insns);
3268
3269 /* ??? We calculate whether an expression needs a check when computing
3270 av sets. This information is not as precise as it could be due to
3271 merging this bit in merge_expr. We can do better in find_used_regs,
b8698a0f 3272 but we want to avoid multiple traversals of the same code motion
e855c69d
AB
3273 paths. */
3274 FOR_EACH_EXPR (expr, expr_iter, orig_ops)
3275 needs_spec_check_p |= EXPR_NEEDS_SPEC_CHECK_P (expr);
3276
b8698a0f 3277 /* Mark hardware regs in REG_RENAME_P that are not suitable
e855c69d
AB
3278 for renaming expr in INSN due to hardware restrictions (register class,
3279 modes compatibility etc). */
3280 FOR_EACH_DEF (def, i, *original_insns)
3281 {
3282 vinsn_t vinsn = INSN_VINSN (def->orig_insn);
3283
3284 if (VINSN_SEPARABLE_P (vinsn))
3285 mark_unavailable_hard_regs (def, reg_rename_p, used_regs);
3286
b8698a0f 3287 /* Do not allow clobbering of ld.[sa] address in case some of the
e855c69d
AB
3288 original operations need a check. */
3289 if (needs_spec_check_p)
3290 IOR_REG_SET (used_regs, VINSN_REG_USES (vinsn));
3291 }
3292
3293 return true;
3294}
3295\f
3296
3297/* Functions to choose the best insn from available ones. */
3298
3299/* Adjusts the priority for EXPR using the backend *_adjust_priority hook. */
3300static int
3301sel_target_adjust_priority (expr_t expr)
3302{
3303 int priority = EXPR_PRIORITY (expr);
3304 int new_priority;
3305
3306 if (targetm.sched.adjust_priority)
3307 new_priority = targetm.sched.adjust_priority (EXPR_INSN_RTX (expr), priority);
3308 else
3309 new_priority = priority;
3310
3311 /* If the priority has changed, adjust EXPR_PRIORITY_ADJ accordingly. */
3312 EXPR_PRIORITY_ADJ (expr) = new_priority - EXPR_PRIORITY (expr);
3313
3314 gcc_assert (EXPR_PRIORITY_ADJ (expr) >= 0);
3315
136e01a3
AB
3316 if (sched_verbose >= 4)
3317 sel_print ("sel_target_adjust_priority: insn %d, %d+%d = %d.\n",
b8698a0f 3318 INSN_UID (EXPR_INSN_RTX (expr)), EXPR_PRIORITY (expr),
e855c69d
AB
3319 EXPR_PRIORITY_ADJ (expr), new_priority);
3320
3321 return new_priority;
3322}
3323
3324/* Rank two available exprs for schedule. Never return 0 here. */
b8698a0f 3325static int
e855c69d
AB
3326sel_rank_for_schedule (const void *x, const void *y)
3327{
3328 expr_t tmp = *(const expr_t *) y;
3329 expr_t tmp2 = *(const expr_t *) x;
3330 insn_t tmp_insn, tmp2_insn;
3331 vinsn_t tmp_vinsn, tmp2_vinsn;
3332 int val;
3333
3334 tmp_vinsn = EXPR_VINSN (tmp);
3335 tmp2_vinsn = EXPR_VINSN (tmp2);
3336 tmp_insn = EXPR_INSN_RTX (tmp);
3337 tmp2_insn = EXPR_INSN_RTX (tmp2);
b8698a0f 3338
b5b8b0ac
AO
3339 /* Schedule debug insns as early as possible. */
3340 if (DEBUG_INSN_P (tmp_insn) && !DEBUG_INSN_P (tmp2_insn))
3341 return -1;
3342 else if (DEBUG_INSN_P (tmp2_insn))
3343 return 1;
3344
e855c69d
AB
3345 /* Prefer SCHED_GROUP_P insns to any others. */
3346 if (SCHED_GROUP_P (tmp_insn) != SCHED_GROUP_P (tmp2_insn))
3347 {
b8698a0f 3348 if (VINSN_UNIQUE_P (tmp_vinsn) && VINSN_UNIQUE_P (tmp2_vinsn))
e855c69d
AB
3349 return SCHED_GROUP_P (tmp2_insn) ? 1 : -1;
3350
3351 /* Now uniqueness means SCHED_GROUP_P is set, because schedule groups
3352 cannot be cloned. */
3353 if (VINSN_UNIQUE_P (tmp2_vinsn))
3354 return 1;
3355 return -1;
3356 }
3357
3358 /* Discourage scheduling of speculative checks. */
3359 val = (sel_insn_is_speculation_check (tmp_insn)
3360 - sel_insn_is_speculation_check (tmp2_insn));
3361 if (val)
3362 return val;
3363
3364 /* Prefer not scheduled insn over scheduled one. */
3365 if (EXPR_SCHED_TIMES (tmp) > 0 || EXPR_SCHED_TIMES (tmp2) > 0)
3366 {
3367 val = EXPR_SCHED_TIMES (tmp) - EXPR_SCHED_TIMES (tmp2);
3368 if (val)
3369 return val;
3370 }
3371
3372 /* Prefer jump over non-jump instruction. */
3373 if (control_flow_insn_p (tmp_insn) && !control_flow_insn_p (tmp2_insn))
3374 return -1;
3375 else if (control_flow_insn_p (tmp2_insn) && !control_flow_insn_p (tmp_insn))
3376 return 1;
3377
3378 /* Prefer an expr with greater priority. */
3379 if (EXPR_USEFULNESS (tmp) != 0 && EXPR_USEFULNESS (tmp2) != 0)
3380 {
3381 int p2 = EXPR_PRIORITY (tmp2) + EXPR_PRIORITY_ADJ (tmp2),
3382 p1 = EXPR_PRIORITY (tmp) + EXPR_PRIORITY_ADJ (tmp);
3383
3384 val = p2 * EXPR_USEFULNESS (tmp2) - p1 * EXPR_USEFULNESS (tmp);
3385 }
3386 else
b8698a0f 3387 val = EXPR_PRIORITY (tmp2) - EXPR_PRIORITY (tmp)
e855c69d
AB
3388 + EXPR_PRIORITY_ADJ (tmp2) - EXPR_PRIORITY_ADJ (tmp);
3389 if (val)
3390 return val;
3391
3392 if (spec_info != NULL && spec_info->mask != 0)
3393 /* This code was taken from haifa-sched.c: rank_for_schedule (). */
3394 {
3395 ds_t ds1, ds2;
3396 dw_t dw1, dw2;
3397 int dw;
3398
3399 ds1 = EXPR_SPEC_DONE_DS (tmp);
3400 if (ds1)
3401 dw1 = ds_weak (ds1);
3402 else
3403 dw1 = NO_DEP_WEAK;
3404
3405 ds2 = EXPR_SPEC_DONE_DS (tmp2);
3406 if (ds2)
3407 dw2 = ds_weak (ds2);
3408 else
3409 dw2 = NO_DEP_WEAK;
3410
3411 dw = dw2 - dw1;
3412 if (dw > (NO_DEP_WEAK / 8) || dw < -(NO_DEP_WEAK / 8))
3413 return dw;
3414 }
3415
e855c69d 3416 /* Prefer an old insn to a bookkeeping insn. */
b8698a0f 3417 if (INSN_UID (tmp_insn) < first_emitted_uid
e855c69d
AB
3418 && INSN_UID (tmp2_insn) >= first_emitted_uid)
3419 return -1;
b8698a0f 3420 if (INSN_UID (tmp_insn) >= first_emitted_uid
e855c69d
AB
3421 && INSN_UID (tmp2_insn) < first_emitted_uid)
3422 return 1;
3423
b8698a0f 3424 /* Prefer an insn with smaller UID, as a last resort.
e855c69d
AB
3425 We can't safely use INSN_LUID as it is defined only for those insns
3426 that are in the stream. */
3427 return INSN_UID (tmp_insn) - INSN_UID (tmp2_insn);
3428}
3429
b8698a0f 3430/* Filter out expressions from av set pointed to by AV_PTR
e855c69d
AB
3431 that are pipelined too many times. */
3432static void
3433process_pipelined_exprs (av_set_t *av_ptr)
3434{
3435 expr_t expr;
3436 av_set_iterator si;
3437
3438 /* Don't pipeline already pipelined code as that would increase
b8698a0f 3439 number of unnecessary register moves. */
e855c69d
AB
3440 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3441 {
3442 if (EXPR_SCHED_TIMES (expr)
3443 >= PARAM_VALUE (PARAM_SELSCHED_MAX_SCHED_TIMES))
3444 av_set_iter_remove (&si);
3445 }
3446}
3447
3448/* Filter speculative insns from AV_PTR if we don't want them. */
3449static void
3450process_spec_exprs (av_set_t *av_ptr)
3451{
3452 bool try_data_p = true;
3453 bool try_control_p = true;
3454 expr_t expr;
3455 av_set_iterator si;
3456
3457 if (spec_info == NULL)
3458 return;
3459
3460 /* Scan *AV_PTR to find out if we want to consider speculative
3461 instructions for scheduling. */
3462 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3463 {
3464 ds_t ds;
3465
3466 ds = EXPR_SPEC_DONE_DS (expr);
3467
3468 /* The probability of a success is too low - don't speculate. */
3469 if ((ds & SPECULATIVE)
3470 && (ds_weak (ds) < spec_info->data_weakness_cutoff
3471 || EXPR_USEFULNESS (expr) < spec_info->control_weakness_cutoff
3472 || (pipelining_p && false
3473 && (ds & DATA_SPEC)
3474 && (ds & CONTROL_SPEC))))
3475 {
3476 av_set_iter_remove (&si);
3477 continue;
3478 }
3479
3480 if ((spec_info->flags & PREFER_NON_DATA_SPEC)
3481 && !(ds & BEGIN_DATA))
3482 try_data_p = false;
3483
3484 if ((spec_info->flags & PREFER_NON_CONTROL_SPEC)
3485 && !(ds & BEGIN_CONTROL))
3486 try_control_p = false;
3487 }
3488
3489 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3490 {
3491 ds_t ds;
3492
3493 ds = EXPR_SPEC_DONE_DS (expr);
3494
3495 if (ds & SPECULATIVE)
3496 {
3497 if ((ds & BEGIN_DATA) && !try_data_p)
3498 /* We don't want any data speculative instructions right
3499 now. */
3500 av_set_iter_remove (&si);
3501
3502 if ((ds & BEGIN_CONTROL) && !try_control_p)
3503 /* We don't want any control speculative instructions right
3504 now. */
3505 av_set_iter_remove (&si);
3506 }
3507 }
3508}
3509
b8698a0f
L
3510/* Search for any use-like insns in AV_PTR and decide on scheduling
3511 them. Return one when found, and NULL otherwise.
e855c69d
AB
3512 Note that we check here whether a USE could be scheduled to avoid
3513 an infinite loop later. */
3514static expr_t
3515process_use_exprs (av_set_t *av_ptr)
3516{
3517 expr_t expr;
3518 av_set_iterator si;
3519 bool uses_present_p = false;
3520 bool try_uses_p = true;
3521
3522 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3523 {
3524 /* This will also initialize INSN_CODE for later use. */
3525 if (recog_memoized (EXPR_INSN_RTX (expr)) < 0)
3526 {
3527 /* If we have a USE in *AV_PTR that was not scheduled yet,
3528 do so because it will do good only. */
3529 if (EXPR_SCHED_TIMES (expr) <= 0)
3530 {
3531 if (EXPR_TARGET_AVAILABLE (expr) == 1)
3532 return expr;
3533
3534 av_set_iter_remove (&si);
3535 }
3536 else
3537 {
3538 gcc_assert (pipelining_p);
3539
3540 uses_present_p = true;
3541 }
3542 }
3543 else
3544 try_uses_p = false;
3545 }
3546
3547 if (uses_present_p)
3548 {
3549 /* If we don't want to schedule any USEs right now and we have some
3550 in *AV_PTR, remove them, else just return the first one found. */
3551 if (!try_uses_p)
3552 {
3553 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3554 if (INSN_CODE (EXPR_INSN_RTX (expr)) < 0)
3555 av_set_iter_remove (&si);
3556 }
3557 else
3558 {
3559 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3560 {
3561 gcc_assert (INSN_CODE (EXPR_INSN_RTX (expr)) < 0);
3562
3563 if (EXPR_TARGET_AVAILABLE (expr) == 1)
3564 return expr;
3565
3566 av_set_iter_remove (&si);
3567 }
3568 }
3569 }
3570
3571 return NULL;
3572}
3573
3574/* Lookup EXPR in VINSN_VEC and return TRUE if found. */
3575static bool
3576vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr)
3577{
3578 vinsn_t vinsn;
3579 int n;
3580
3581 for (n = 0; VEC_iterate (vinsn_t, vinsn_vec, n, vinsn); n++)
3582 if (VINSN_SEPARABLE_P (vinsn))
3583 {
3584 if (vinsn_equal_p (vinsn, EXPR_VINSN (expr)))
3585 return true;
3586 }
3587 else
3588 {
3589 /* For non-separable instructions, the blocking insn can have
3590 another pattern due to substitution, and we can't choose
3591 different register as in the above case. Check all registers
3592 being written instead. */
b8698a0f 3593 if (bitmap_intersect_p (VINSN_REG_SETS (vinsn),
e855c69d
AB
3594 VINSN_REG_SETS (EXPR_VINSN (expr))))
3595 return true;
3596 }
3597
3598 return false;
3599}
3600
3601#ifdef ENABLE_CHECKING
3602/* Return true if either of expressions from ORIG_OPS can be blocked
3603 by previously created bookkeeping code. STATIC_PARAMS points to static
3604 parameters of move_op. */
3605static bool
3606av_set_could_be_blocked_by_bookkeeping_p (av_set_t orig_ops, void *static_params)
3607{
3608 expr_t expr;
3609 av_set_iterator iter;
3610 moveop_static_params_p sparams;
3611
3612 /* This checks that expressions in ORIG_OPS are not blocked by bookkeeping
3613 created while scheduling on another fence. */
3614 FOR_EACH_EXPR (expr, iter, orig_ops)
3615 if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr))
3616 return true;
3617
3618 gcc_assert (code_motion_path_driver_info == &move_op_hooks);
3619 sparams = (moveop_static_params_p) static_params;
3620
3621 /* Expressions can be also blocked by bookkeeping created during current
3622 move_op. */
3623 if (bitmap_bit_p (current_copies, INSN_UID (sparams->failed_insn)))
3624 FOR_EACH_EXPR (expr, iter, orig_ops)
3625 if (moveup_expr_cached (expr, sparams->failed_insn, false) != MOVEUP_EXPR_NULL)
3626 return true;
3627
3628 /* Expressions in ORIG_OPS may have wrong destination register due to
3629 renaming. Check with the right register instead. */
3630 if (sparams->dest && REG_P (sparams->dest))
3631 {
3632 unsigned regno = REGNO (sparams->dest);
3633 vinsn_t failed_vinsn = INSN_VINSN (sparams->failed_insn);
3634
3635 if (bitmap_bit_p (VINSN_REG_SETS (failed_vinsn), regno)
3636 || bitmap_bit_p (VINSN_REG_USES (failed_vinsn), regno)
3637 || bitmap_bit_p (VINSN_REG_CLOBBERS (failed_vinsn), regno))
3638 return true;
3639 }
3640
3641 return false;
3642}
3643#endif
3644
3645/* Clear VINSN_VEC and detach vinsns. */
3646static void
3647vinsn_vec_clear (vinsn_vec_t *vinsn_vec)
3648{
3649 unsigned len = VEC_length (vinsn_t, *vinsn_vec);
3650 if (len > 0)
3651 {
3652 vinsn_t vinsn;
3653 int n;
b8698a0f 3654
e855c69d
AB
3655 for (n = 0; VEC_iterate (vinsn_t, *vinsn_vec, n, vinsn); n++)
3656 vinsn_detach (vinsn);
3657 VEC_block_remove (vinsn_t, *vinsn_vec, 0, len);
3658 }
3659}
3660
3661/* Add the vinsn of EXPR to the VINSN_VEC. */
3662static void
3663vinsn_vec_add (vinsn_vec_t *vinsn_vec, expr_t expr)
3664{
3665 vinsn_attach (EXPR_VINSN (expr));
3666 VEC_safe_push (vinsn_t, heap, *vinsn_vec, EXPR_VINSN (expr));
3667}
3668
b8698a0f 3669/* Free the vector representing blocked expressions. */
e855c69d
AB
3670static void
3671vinsn_vec_free (vinsn_vec_t *vinsn_vec)
3672{
3673 if (*vinsn_vec)
3674 VEC_free (vinsn_t, heap, *vinsn_vec);
3675}
3676
3677/* Increase EXPR_PRIORITY_ADJ for INSN by AMOUNT. */
3678
3679void sel_add_to_insn_priority (rtx insn, int amount)
3680{
3681 EXPR_PRIORITY_ADJ (INSN_EXPR (insn)) += amount;
3682
3683 if (sched_verbose >= 2)
b8698a0f 3684 sel_print ("sel_add_to_insn_priority: insn %d, by %d (now %d+%d).\n",
e855c69d
AB
3685 INSN_UID (insn), amount, EXPR_PRIORITY (INSN_EXPR (insn)),
3686 EXPR_PRIORITY_ADJ (INSN_EXPR (insn)));
3687}
3688
b8698a0f 3689/* Turn AV into a vector, filter inappropriate insns and sort it. Return
e855c69d
AB
3690 true if there is something to schedule. BNDS and FENCE are current
3691 boundaries and fence, respectively. If we need to stall for some cycles
b8698a0f 3692 before an expr from AV would become available, write this number to
e855c69d
AB
3693 *PNEED_STALL. */
3694static bool
3695fill_vec_av_set (av_set_t av, blist_t bnds, fence_t fence,
3696 int *pneed_stall)
3697{
3698 av_set_iterator si;
3699 expr_t expr;
3700 int sched_next_worked = 0, stalled, n;
3701 static int av_max_prio, est_ticks_till_branch;
3702 int min_need_stall = -1;
3703 deps_t dc = BND_DC (BLIST_BND (bnds));
3704
3705 /* Bail out early when the ready list contained only USEs/CLOBBERs that are
3706 already scheduled. */
3707 if (av == NULL)
3708 return false;
3709
3710 /* Empty vector from the previous stuff. */
3711 if (VEC_length (expr_t, vec_av_set) > 0)
3712 VEC_block_remove (expr_t, vec_av_set, 0, VEC_length (expr_t, vec_av_set));
3713
3714 /* Turn the set into a vector for sorting and call sel_target_adjust_priority
3715 for each insn. */
3716 gcc_assert (VEC_empty (expr_t, vec_av_set));
3717 FOR_EACH_EXPR (expr, si, av)
b8698a0f 3718 {
e855c69d
AB
3719 VEC_safe_push (expr_t, heap, vec_av_set, expr);
3720
3721 gcc_assert (EXPR_PRIORITY_ADJ (expr) == 0 || *pneed_stall);
3722
3723 /* Adjust priority using target backend hook. */
3724 sel_target_adjust_priority (expr);
3725 }
3726
3727 /* Sort the vector. */
3728 qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
3729 sizeof (expr_t), sel_rank_for_schedule);
3730
3731 /* We record maximal priority of insns in av set for current instruction
3732 group. */
3733 if (FENCE_STARTS_CYCLE_P (fence))
3734 av_max_prio = est_ticks_till_branch = INT_MIN;
3735
3736 /* Filter out inappropriate expressions. Loop's direction is reversed to
3737 visit "best" instructions first. We assume that VEC_unordered_remove
3738 moves last element in place of one being deleted. */
3739 for (n = VEC_length (expr_t, vec_av_set) - 1, stalled = 0; n >= 0; n--)
3740 {
3741 expr_t expr = VEC_index (expr_t, vec_av_set, n);
3742 insn_t insn = EXPR_INSN_RTX (expr);
3743 char target_available;
3744 bool is_orig_reg_p = true;
3745 int need_cycles, new_prio;
3746
3747 /* Don't allow any insns other than from SCHED_GROUP if we have one. */
3748 if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence))
3749 {
3750 VEC_unordered_remove (expr_t, vec_av_set, n);
3751 continue;
3752 }
3753
b8698a0f 3754 /* Set number of sched_next insns (just in case there
e855c69d
AB
3755 could be several). */
3756 if (FENCE_SCHED_NEXT (fence))
3757 sched_next_worked++;
b8698a0f
L
3758
3759 /* Check all liveness requirements and try renaming.
e855c69d
AB
3760 FIXME: try to minimize calls to this. */
3761 target_available = EXPR_TARGET_AVAILABLE (expr);
3762
3763 /* If insn was already scheduled on the current fence,
3764 set TARGET_AVAILABLE to -1 no matter what expr's attribute says. */
3765 if (vinsn_vec_has_expr_p (vec_target_unavailable_vinsns, expr))
3766 target_available = -1;
3767
3768 /* If the availability of the EXPR is invalidated by the insertion of
3769 bookkeeping earlier, make sure that we won't choose this expr for
3770 scheduling if it's not separable, and if it is separable, then
3771 we have to recompute the set of available registers for it. */
3772 if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr))
3773 {
3774 VEC_unordered_remove (expr_t, vec_av_set, n);
3775 if (sched_verbose >= 4)
3776 sel_print ("Expr %d is blocked by bookkeeping inserted earlier\n",
3777 INSN_UID (insn));
3778 continue;
3779 }
b8698a0f 3780
e855c69d
AB
3781 if (target_available == true)
3782 {
3783 /* Do nothing -- we can use an existing register. */
3784 is_orig_reg_p = EXPR_SEPARABLE_P (expr);
3785 }
b8698a0f 3786 else if (/* Non-separable instruction will never
e855c69d
AB
3787 get another register. */
3788 (target_available == false
3789 && !EXPR_SEPARABLE_P (expr))
3790 /* Don't try to find a register for low-priority expression. */
3791 || (int) VEC_length (expr_t, vec_av_set) - 1 - n >= max_insns_to_rename
3792 /* ??? FIXME: Don't try to rename data speculation. */
3793 || (EXPR_SPEC_DONE_DS (expr) & BEGIN_DATA)
3794 || ! find_best_reg_for_expr (expr, bnds, &is_orig_reg_p))
3795 {
3796 VEC_unordered_remove (expr_t, vec_av_set, n);
3797 if (sched_verbose >= 4)
b8698a0f 3798 sel_print ("Expr %d has no suitable target register\n",
e855c69d
AB
3799 INSN_UID (insn));
3800 continue;
3801 }
3802
3803 /* Filter expressions that need to be renamed or speculated when
3804 pipelining, because compensating register copies or speculation
3805 checks are likely to be placed near the beginning of the loop,
3806 causing a stall. */
3807 if (pipelining_p && EXPR_ORIG_SCHED_CYCLE (expr) > 0
3808 && (!is_orig_reg_p || EXPR_SPEC_DONE_DS (expr) != 0))
3809 {
3810 /* Estimation of number of cycles until loop branch for
3811 renaming/speculation to be successful. */
3812 int need_n_ticks_till_branch = sel_vinsn_cost (EXPR_VINSN (expr));
3813
3814 if ((int) current_loop_nest->ninsns < 9)
3815 {
3816 VEC_unordered_remove (expr_t, vec_av_set, n);
3817 if (sched_verbose >= 4)
3818 sel_print ("Pipelining expr %d will likely cause stall\n",
3819 INSN_UID (insn));
3820 continue;
3821 }
3822
3823 if ((int) current_loop_nest->ninsns - num_insns_scheduled
3824 < need_n_ticks_till_branch * issue_rate / 2
3825 && est_ticks_till_branch < need_n_ticks_till_branch)
3826 {
3827 VEC_unordered_remove (expr_t, vec_av_set, n);
3828 if (sched_verbose >= 4)
3829 sel_print ("Pipelining expr %d will likely cause stall\n",
3830 INSN_UID (insn));
3831 continue;
3832 }
3833 }
3834
3835 /* We want to schedule speculation checks as late as possible. Discard
3836 them from av set if there are instructions with higher priority. */
3837 if (sel_insn_is_speculation_check (insn)
3838 && EXPR_PRIORITY (expr) < av_max_prio)
3839 {
3840 stalled++;
3841 min_need_stall = min_need_stall < 0 ? 1 : MIN (min_need_stall, 1);
3842 VEC_unordered_remove (expr_t, vec_av_set, n);
3843 if (sched_verbose >= 4)
3844 sel_print ("Delaying speculation check %d until its first use\n",
3845 INSN_UID (insn));
3846 continue;
3847 }
3848
3849 /* Ignore EXPRs available from pipelining to update AV_MAX_PRIO. */
3850 if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
3851 av_max_prio = MAX (av_max_prio, EXPR_PRIORITY (expr));
3852
3853 /* Don't allow any insns whose data is not yet ready.
3854 Check first whether we've already tried them and failed. */
3855 if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence))
3856 {
3857 need_cycles = (FENCE_READY_TICKS (fence)[INSN_UID (insn)]
3858 - FENCE_CYCLE (fence));
3859 if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
3860 est_ticks_till_branch = MAX (est_ticks_till_branch,
3861 EXPR_PRIORITY (expr) + need_cycles);
3862
3863 if (need_cycles > 0)
3864 {
3865 stalled++;
b8698a0f 3866 min_need_stall = (min_need_stall < 0
e855c69d
AB
3867 ? need_cycles
3868 : MIN (min_need_stall, need_cycles));
3869 VEC_unordered_remove (expr_t, vec_av_set, n);
3870
3871 if (sched_verbose >= 4)
b8698a0f 3872 sel_print ("Expr %d is not ready until cycle %d (cached)\n",
e855c69d
AB
3873 INSN_UID (insn),
3874 FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
3875 continue;
3876 }
3877 }
3878
b8698a0f 3879 /* Now resort to dependence analysis to find whether EXPR might be
e855c69d
AB
3880 stalled due to dependencies from FENCE's context. */
3881 need_cycles = tick_check_p (expr, dc, fence);
3882 new_prio = EXPR_PRIORITY (expr) + EXPR_PRIORITY_ADJ (expr) + need_cycles;
3883
3884 if (EXPR_ORIG_SCHED_CYCLE (expr) <= 0)
3885 est_ticks_till_branch = MAX (est_ticks_till_branch,
3886 new_prio);
3887
3888 if (need_cycles > 0)
3889 {
3890 if (INSN_UID (insn) >= FENCE_READY_TICKS_SIZE (fence))
3891 {
3892 int new_size = INSN_UID (insn) * 3 / 2;
b8698a0f
L
3893
3894 FENCE_READY_TICKS (fence)
e855c69d
AB
3895 = (int *) xrecalloc (FENCE_READY_TICKS (fence),
3896 new_size, FENCE_READY_TICKS_SIZE (fence),
3897 sizeof (int));
3898 }
b8698a0f
L
3899 FENCE_READY_TICKS (fence)[INSN_UID (insn)]
3900 = FENCE_CYCLE (fence) + need_cycles;
3901
e855c69d 3902 stalled++;
b8698a0f 3903 min_need_stall = (min_need_stall < 0
e855c69d
AB
3904 ? need_cycles
3905 : MIN (min_need_stall, need_cycles));
3906
3907 VEC_unordered_remove (expr_t, vec_av_set, n);
b8698a0f 3908
e855c69d 3909 if (sched_verbose >= 4)
b8698a0f 3910 sel_print ("Expr %d is not ready yet until cycle %d\n",
e855c69d
AB
3911 INSN_UID (insn),
3912 FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
3913 continue;
3914 }
3915
3916 if (sched_verbose >= 4)
3917 sel_print ("Expr %d is ok\n", INSN_UID (insn));
3918 min_need_stall = 0;
3919 }
3920
3921 /* Clear SCHED_NEXT. */
3922 if (FENCE_SCHED_NEXT (fence))
3923 {
3924 gcc_assert (sched_next_worked == 1);
3925 FENCE_SCHED_NEXT (fence) = NULL_RTX;
3926 }
3927
3928 /* No need to stall if this variable was not initialized. */
3929 if (min_need_stall < 0)
3930 min_need_stall = 0;
3931
3932 if (VEC_empty (expr_t, vec_av_set))
3933 {
3934 /* We need to set *pneed_stall here, because later we skip this code
3935 when ready list is empty. */
3936 *pneed_stall = min_need_stall;
3937 return false;
3938 }
3939 else
3940 gcc_assert (min_need_stall == 0);
3941
3942 /* Sort the vector. */
3943 qsort (VEC_address (expr_t, vec_av_set), VEC_length (expr_t, vec_av_set),
3944 sizeof (expr_t), sel_rank_for_schedule);
b8698a0f 3945
e855c69d
AB
3946 if (sched_verbose >= 4)
3947 {
b8698a0f 3948 sel_print ("Total ready exprs: %d, stalled: %d\n",
e855c69d
AB
3949 VEC_length (expr_t, vec_av_set), stalled);
3950 sel_print ("Sorted av set (%d): ", VEC_length (expr_t, vec_av_set));
3951 for (n = 0; VEC_iterate (expr_t, vec_av_set, n, expr); n++)
3952 dump_expr (expr);
3953 sel_print ("\n");
3954 }
3955
3956 *pneed_stall = 0;
3957 return true;
3958}
3959
3960/* Convert a vectored and sorted av set to the ready list that
3961 the rest of the backend wants to see. */
3962static void
3963convert_vec_av_set_to_ready (void)
3964{
3965 int n;
3966 expr_t expr;
3967
3968 /* Allocate and fill the ready list from the sorted vector. */
3969 ready.n_ready = VEC_length (expr_t, vec_av_set);
3970 ready.first = ready.n_ready - 1;
b8698a0f 3971
e855c69d
AB
3972 gcc_assert (ready.n_ready > 0);
3973
3974 if (ready.n_ready > max_issue_size)
3975 {
3976 max_issue_size = ready.n_ready;
3977 sched_extend_ready_list (ready.n_ready);
3978 }
b8698a0f 3979
e855c69d
AB
3980 for (n = 0; VEC_iterate (expr_t, vec_av_set, n, expr); n++)
3981 {
3982 vinsn_t vi = EXPR_VINSN (expr);
3983 insn_t insn = VINSN_INSN_RTX (vi);
3984
3985 ready_try[n] = 0;
3986 ready.vec[n] = insn;
3987 }
3988}
3989
3990/* Initialize ready list from *AV_PTR for the max_issue () call.
3991 If any unrecognizable insn found in *AV_PTR, return it (and skip
b8698a0f
L
3992 max_issue). BND and FENCE are current boundary and fence,
3993 respectively. If we need to stall for some cycles before an expr
e855c69d
AB
3994 from *AV_PTR would become available, write this number to *PNEED_STALL. */
3995static expr_t
3996fill_ready_list (av_set_t *av_ptr, blist_t bnds, fence_t fence,
3997 int *pneed_stall)
3998{
3999 expr_t expr;
4000
4001 /* We do not support multiple boundaries per fence. */
4002 gcc_assert (BLIST_NEXT (bnds) == NULL);
4003
b8698a0f 4004 /* Process expressions required special handling, i.e. pipelined,
e855c69d
AB
4005 speculative and recog() < 0 expressions first. */
4006 process_pipelined_exprs (av_ptr);
4007 process_spec_exprs (av_ptr);
4008
4009 /* A USE could be scheduled immediately. */
4010 expr = process_use_exprs (av_ptr);
4011 if (expr)
4012 {
4013 *pneed_stall = 0;
4014 return expr;
4015 }
4016
4017 /* Turn the av set to a vector for sorting. */
4018 if (! fill_vec_av_set (*av_ptr, bnds, fence, pneed_stall))
4019 {
4020 ready.n_ready = 0;
4021 return NULL;
4022 }
4023
4024 /* Build the final ready list. */
4025 convert_vec_av_set_to_ready ();
4026 return NULL;
4027}
4028
4029/* Wrapper for dfa_new_cycle (). Returns TRUE if cycle was advanced. */
4030static bool
4031sel_dfa_new_cycle (insn_t insn, fence_t fence)
4032{
b8698a0f
L
4033 int last_scheduled_cycle = FENCE_LAST_SCHEDULED_INSN (fence)
4034 ? INSN_SCHED_CYCLE (FENCE_LAST_SCHEDULED_INSN (fence))
e855c69d
AB
4035 : FENCE_CYCLE (fence) - 1;
4036 bool res = false;
4037 int sort_p = 0;
4038
4039 if (!targetm.sched.dfa_new_cycle)
4040 return false;
4041
4042 memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
4043
4044 while (!sort_p && targetm.sched.dfa_new_cycle (sched_dump, sched_verbose,
4045 insn, last_scheduled_cycle,
4046 FENCE_CYCLE (fence), &sort_p))
4047 {
4048 memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
4049 advance_one_cycle (fence);
4050 memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
4051 res = true;
4052 }
4053
4054 return res;
4055}
4056
4057/* Invoke reorder* target hooks on the ready list. Return the number of insns
4058 we can issue. FENCE is the current fence. */
4059static int
4060invoke_reorder_hooks (fence_t fence)
4061{
4062 int issue_more;
4063 bool ran_hook = false;
4064
4065 /* Call the reorder hook at the beginning of the cycle, and call
4066 the reorder2 hook in the middle of the cycle. */
4067 if (FENCE_ISSUED_INSNS (fence) == 0)
4068 {
4069 if (targetm.sched.reorder
4070 && !SCHED_GROUP_P (ready_element (&ready, 0))
4071 && ready.n_ready > 1)
4072 {
4073 /* Don't give reorder the most prioritized insn as it can break
4074 pipelining. */
4075 if (pipelining_p)
4076 --ready.n_ready;
4077
4078 issue_more
4079 = targetm.sched.reorder (sched_dump, sched_verbose,
4080 ready_lastpos (&ready),
4081 &ready.n_ready, FENCE_CYCLE (fence));
4082
4083 if (pipelining_p)
4084 ++ready.n_ready;
4085
4086 ran_hook = true;
4087 }
4088 else
4089 /* Initialize can_issue_more for variable_issue. */
4090 issue_more = issue_rate;
4091 }
4092 else if (targetm.sched.reorder2
4093 && !SCHED_GROUP_P (ready_element (&ready, 0)))
4094 {
4095 if (ready.n_ready == 1)
b8698a0f 4096 issue_more =
e855c69d
AB
4097 targetm.sched.reorder2 (sched_dump, sched_verbose,
4098 ready_lastpos (&ready),
4099 &ready.n_ready, FENCE_CYCLE (fence));
4100 else
4101 {
4102 if (pipelining_p)
4103 --ready.n_ready;
4104
4105 issue_more =
4106 targetm.sched.reorder2 (sched_dump, sched_verbose,
4107 ready.n_ready
4108 ? ready_lastpos (&ready) : NULL,
4109 &ready.n_ready, FENCE_CYCLE (fence));
4110
4111 if (pipelining_p)
4112 ++ready.n_ready;
4113 }
4114
4115 ran_hook = true;
4116 }
b8698a0f 4117 else
136e01a3 4118 issue_more = FENCE_ISSUE_MORE (fence);
e855c69d
AB
4119
4120 /* Ensure that ready list and vec_av_set are in line with each other,
4121 i.e. vec_av_set[i] == ready_element (&ready, i). */
4122 if (issue_more && ran_hook)
4123 {
4124 int i, j, n;
4125 rtx *arr = ready.vec;
4126 expr_t *vec = VEC_address (expr_t, vec_av_set);
4127
4128 for (i = 0, n = ready.n_ready; i < n; i++)
4129 if (EXPR_INSN_RTX (vec[i]) != arr[i])
4130 {
4131 expr_t tmp;
4132
4133 for (j = i; j < n; j++)
4134 if (EXPR_INSN_RTX (vec[j]) == arr[i])
4135 break;
4136 gcc_assert (j < n);
4137
b8698a0f 4138 tmp = vec[i];
e855c69d
AB
4139 vec[i] = vec[j];
4140 vec[j] = tmp;
4141 }
4142 }
4143
4144 return issue_more;
4145}
4146
b8698a0f
L
4147/* Return an EXPR correponding to INDEX element of ready list, if
4148 FOLLOW_READY_ELEMENT is true (i.e., an expr of
4149 ready_element (&ready, INDEX) will be returned), and to INDEX element of
e855c69d
AB
4150 ready.vec otherwise. */
4151static inline expr_t
4152find_expr_for_ready (int index, bool follow_ready_element)
4153{
4154 expr_t expr;
4155 int real_index;
4156
4157 real_index = follow_ready_element ? ready.first - index : index;
4158
4159 expr = VEC_index (expr_t, vec_av_set, real_index);
4160 gcc_assert (ready.vec[real_index] == EXPR_INSN_RTX (expr));
4161
4162 return expr;
4163}
4164
4165/* Calculate insns worth trying via lookahead_guard hook. Return a number
4166 of such insns found. */
4167static int
4168invoke_dfa_lookahead_guard (void)
4169{
4170 int i, n;
b8698a0f 4171 bool have_hook
e855c69d
AB
4172 = targetm.sched.first_cycle_multipass_dfa_lookahead_guard != NULL;
4173
4174 if (sched_verbose >= 2)
4175 sel_print ("ready after reorder: ");
4176
4177 for (i = 0, n = 0; i < ready.n_ready; i++)
4178 {
4179 expr_t expr;
4180 insn_t insn;
4181 int r;
4182
b8698a0f 4183 /* In this loop insn is Ith element of the ready list given by
e855c69d
AB
4184 ready_element, not Ith element of ready.vec. */
4185 insn = ready_element (&ready, i);
b8698a0f 4186
e855c69d
AB
4187 if (! have_hook || i == 0)
4188 r = 0;
4189 else
4190 r = !targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn);
b8698a0f 4191
e855c69d 4192 gcc_assert (INSN_CODE (insn) >= 0);
b8698a0f
L
4193
4194 /* Only insns with ready_try = 0 can get here
e855c69d
AB
4195 from fill_ready_list. */
4196 gcc_assert (ready_try [i] == 0);
4197 ready_try[i] = r;
4198 if (!r)
4199 n++;
4200
4201 expr = find_expr_for_ready (i, true);
b8698a0f 4202
e855c69d
AB
4203 if (sched_verbose >= 2)
4204 {
4205 dump_vinsn (EXPR_VINSN (expr));
4206 sel_print (":%d; ", ready_try[i]);
4207 }
4208 }
4209
4210 if (sched_verbose >= 2)
4211 sel_print ("\n");
4212 return n;
4213}
4214
4215/* Calculate the number of privileged insns and return it. */
4216static int
4217calculate_privileged_insns (void)
4218{
4219 expr_t cur_expr, min_spec_expr = NULL;
4220 insn_t cur_insn, min_spec_insn;
4221 int privileged_n = 0, i;
4222
4223 for (i = 0; i < ready.n_ready; i++)
4224 {
4225 if (ready_try[i])
4226 continue;
4227
4228 if (! min_spec_expr)
4229 {
4230 min_spec_insn = ready_element (&ready, i);
4231 min_spec_expr = find_expr_for_ready (i, true);
4232 }
b8698a0f 4233
e855c69d
AB
4234 cur_insn = ready_element (&ready, i);
4235 cur_expr = find_expr_for_ready (i, true);
4236
4237 if (EXPR_SPEC (cur_expr) > EXPR_SPEC (min_spec_expr))
4238 break;
4239
4240 ++privileged_n;
4241 }
4242
4243 if (i == ready.n_ready)
4244 privileged_n = 0;
4245
4246 if (sched_verbose >= 2)
4247 sel_print ("privileged_n: %d insns with SPEC %d\n",
4248 privileged_n, privileged_n ? EXPR_SPEC (min_spec_expr) : -1);
4249 return privileged_n;
4250}
4251
b8698a0f 4252/* Call the rest of the hooks after the choice was made. Return
e855c69d
AB
4253 the number of insns that still can be issued given that the current
4254 number is ISSUE_MORE. FENCE and BEST_INSN are the current fence
4255 and the insn chosen for scheduling, respectively. */
4256static int
4257invoke_aftermath_hooks (fence_t fence, rtx best_insn, int issue_more)
4258{
4259 gcc_assert (INSN_P (best_insn));
4260
4261 /* First, call dfa_new_cycle, and then variable_issue, if available. */
4262 sel_dfa_new_cycle (best_insn, fence);
b8698a0f 4263
e855c69d
AB
4264 if (targetm.sched.variable_issue)
4265 {
4266 memcpy (curr_state, FENCE_STATE (fence), dfa_state_size);
b8698a0f 4267 issue_more =
e855c69d
AB
4268 targetm.sched.variable_issue (sched_dump, sched_verbose, best_insn,
4269 issue_more);
4270 memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
4271 }
4272 else if (GET_CODE (PATTERN (best_insn)) != USE
4273 && GET_CODE (PATTERN (best_insn)) != CLOBBER)
4274 issue_more--;
4275
4276 return issue_more;
4277}
4278
4279/* Estimate the cost of issuing INSN on DFA state STATE. */
4280static int
4281estimate_insn_cost (rtx insn, state_t state)
4282{
4283 static state_t temp = NULL;
4284 int cost;
4285
4286 if (!temp)
4287 temp = xmalloc (dfa_state_size);
4288
4289 memcpy (temp, state, dfa_state_size);
4290 cost = state_transition (temp, insn);
4291
4292 if (cost < 0)
4293 return 0;
4294 else if (cost == 0)
4295 return 1;
4296 return cost;
4297}
4298
b8698a0f 4299/* Return the cost of issuing EXPR on the FENCE as estimated by DFA.
e855c69d
AB
4300 This function properly handles ASMs, USEs etc. */
4301static int
4302get_expr_cost (expr_t expr, fence_t fence)
4303{
4304 rtx insn = EXPR_INSN_RTX (expr);
4305
4306 if (recog_memoized (insn) < 0)
4307 {
b8698a0f 4308 if (!FENCE_STARTS_CYCLE_P (fence)
e855c69d
AB
4309 && INSN_ASM_P (insn))
4310 /* This is asm insn which is tryed to be issued on the
4311 cycle not first. Issue it on the next cycle. */
4312 return 1;
4313 else
4314 /* A USE insn, or something else we don't need to
4315 understand. We can't pass these directly to
4316 state_transition because it will trigger a
4317 fatal error for unrecognizable insns. */
4318 return 0;
4319 }
4320 else
4321 return estimate_insn_cost (insn, FENCE_STATE (fence));
4322}
4323
b8698a0f 4324/* Find the best insn for scheduling, either via max_issue or just take
e855c69d
AB
4325 the most prioritized available. */
4326static int
4327choose_best_insn (fence_t fence, int privileged_n, int *index)
4328{
4329 int can_issue = 0;
4330
4331 if (dfa_lookahead > 0)
4332 {
4333 cycle_issued_insns = FENCE_ISSUED_INSNS (fence);
4334 can_issue = max_issue (&ready, privileged_n,
4335 FENCE_STATE (fence), index);
4336 if (sched_verbose >= 2)
4337 sel_print ("max_issue: we can issue %d insns, already did %d insns\n",
4338 can_issue, FENCE_ISSUED_INSNS (fence));
4339 }
4340 else
4341 {
4342 /* We can't use max_issue; just return the first available element. */
4343 int i;
4344
4345 for (i = 0; i < ready.n_ready; i++)
4346 {
4347 expr_t expr = find_expr_for_ready (i, true);
4348
4349 if (get_expr_cost (expr, fence) < 1)
4350 {
4351 can_issue = can_issue_more;
4352 *index = i;
4353
4354 if (sched_verbose >= 2)
4355 sel_print ("using %dth insn from the ready list\n", i + 1);
4356
4357 break;
4358 }
4359 }
4360
4361 if (i == ready.n_ready)
4362 {
4363 can_issue = 0;
4364 *index = -1;
4365 }
4366 }
4367
4368 return can_issue;
4369}
4370
b8698a0f
L
4371/* Choose the best expr from *AV_VLIW_PTR and a suitable register for it.
4372 BNDS and FENCE are current boundaries and scheduling fence respectively.
4373 Return the expr found and NULL if nothing can be issued atm.
4374 Write to PNEED_STALL the number of cycles to stall if no expr was found. */
e855c69d
AB
4375static expr_t
4376find_best_expr (av_set_t *av_vliw_ptr, blist_t bnds, fence_t fence,
4377 int *pneed_stall)
4378{
4379 expr_t best;
b8698a0f 4380
e855c69d
AB
4381 /* Choose the best insn for scheduling via:
4382 1) sorting the ready list based on priority;
4383 2) calling the reorder hook;
4384 3) calling max_issue. */
4385 best = fill_ready_list (av_vliw_ptr, bnds, fence, pneed_stall);
4386 if (best == NULL && ready.n_ready > 0)
4387 {
4388 int privileged_n, index, avail_n;
4389
4390 can_issue_more = invoke_reorder_hooks (fence);
4391 if (can_issue_more > 0)
4392 {
b8698a0f 4393 /* Try choosing the best insn until we find one that is could be
e855c69d
AB
4394 scheduled due to liveness restrictions on its destination register.
4395 In the future, we'd like to choose once and then just probe insns
4396 in the order of their priority. */
4397 avail_n = invoke_dfa_lookahead_guard ();
4398 privileged_n = calculate_privileged_insns ();
4399 can_issue_more = choose_best_insn (fence, privileged_n, &index);
4400 if (can_issue_more)
4401 best = find_expr_for_ready (index, true);
4402 }
b8698a0f 4403 /* We had some available insns, so if we can't issue them,
e855c69d
AB
4404 we have a stall. */
4405 if (can_issue_more == 0)
4406 {
4407 best = NULL;
4408 *pneed_stall = 1;
4409 }
4410 }
4411
4412 if (best != NULL)
4413 {
4414 can_issue_more = invoke_aftermath_hooks (fence, EXPR_INSN_RTX (best),
4415 can_issue_more);
4416 if (can_issue_more == 0)
4417 *pneed_stall = 1;
4418 }
b8698a0f 4419
e855c69d
AB
4420 if (sched_verbose >= 2)
4421 {
4422 if (best != NULL)
4423 {
4424 sel_print ("Best expression (vliw form): ");
4425 dump_expr (best);
4426 sel_print ("; cycle %d\n", FENCE_CYCLE (fence));
4427 }
4428 else
4429 sel_print ("No best expr found!\n");
4430 }
4431
4432 return best;
4433}
4434\f
4435
4436/* Functions that implement the core of the scheduler. */
4437
4438
b8698a0f 4439/* Emit an instruction from EXPR with SEQNO and VINSN after
e855c69d
AB
4440 PLACE_TO_INSERT. */
4441static insn_t
b8698a0f 4442emit_insn_from_expr_after (expr_t expr, vinsn_t vinsn, int seqno,
e855c69d
AB
4443 insn_t place_to_insert)
4444{
4445 /* This assert fails when we have identical instructions
4446 one of which dominates the other. In this case move_op ()
4447 finds the first instruction and doesn't search for second one.
4448 The solution would be to compute av_set after the first found
4449 insn and, if insn present in that set, continue searching.
4450 For now we workaround this issue in move_op. */
4451 gcc_assert (!INSN_IN_STREAM_P (EXPR_INSN_RTX (expr)));
4452
4453 if (EXPR_WAS_RENAMED (expr))
4454 {
4455 unsigned regno = expr_dest_regno (expr);
b8698a0f 4456
e855c69d
AB
4457 if (HARD_REGISTER_NUM_P (regno))
4458 {
4459 df_set_regs_ever_live (regno, true);
4460 reg_rename_tick[regno] = ++reg_rename_this_tick;
4461 }
4462 }
b8698a0f
L
4463
4464 return sel_gen_insn_from_expr_after (expr, vinsn, seqno,
e855c69d
AB
4465 place_to_insert);
4466}
4467
4468/* Return TRUE if BB can hold bookkeeping code. */
4469static bool
4470block_valid_for_bookkeeping_p (basic_block bb)
4471{
4472 insn_t bb_end = BB_END (bb);
4473
4474 if (!in_current_region_p (bb) || EDGE_COUNT (bb->succs) > 1)
4475 return false;
4476
4477 if (INSN_P (bb_end))
4478 {
4479 if (INSN_SCHED_TIMES (bb_end) > 0)
4480 return false;
4481 }
4482 else
4483 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (bb_end));
4484
4485 return true;
4486}
4487
4488/* Attempt to find a block that can hold bookkeeping code for path(s) incoming
4489 into E2->dest, except from E1->src (there may be a sequence of empty basic
4490 blocks between E1->src and E2->dest). Return found block, or NULL if new
b5b8b0ac
AO
4491 one must be created. If LAX holds, don't assume there is a simple path
4492 from E1->src to E2->dest. */
e855c69d 4493static basic_block
b5b8b0ac 4494find_block_for_bookkeeping (edge e1, edge e2, bool lax)
e855c69d
AB
4495{
4496 basic_block candidate_block = NULL;
4497 edge e;
4498
4499 /* Loop over edges from E1 to E2, inclusive. */
b5b8b0ac 4500 for (e = e1; !lax || e->dest != EXIT_BLOCK_PTR; e = EDGE_SUCC (e->dest, 0))
e855c69d
AB
4501 {
4502 if (EDGE_COUNT (e->dest->preds) == 2)
4503 {
4504 if (candidate_block == NULL)
4505 candidate_block = (EDGE_PRED (e->dest, 0) == e
4506 ? EDGE_PRED (e->dest, 1)->src
4507 : EDGE_PRED (e->dest, 0)->src);
4508 else
4509 /* Found additional edge leading to path from e1 to e2
4510 from aside. */
4511 return NULL;
4512 }
4513 else if (EDGE_COUNT (e->dest->preds) > 2)
4514 /* Several edges leading to path from e1 to e2 from aside. */
4515 return NULL;
4516
4517 if (e == e2)
b5b8b0ac
AO
4518 return ((!lax || candidate_block)
4519 && block_valid_for_bookkeeping_p (candidate_block)
e855c69d
AB
4520 ? candidate_block
4521 : NULL);
b5b8b0ac
AO
4522
4523 if (lax && EDGE_COUNT (e->dest->succs) != 1)
4524 return NULL;
e855c69d 4525 }
b5b8b0ac
AO
4526
4527 if (lax)
4528 return NULL;
4529
e855c69d
AB
4530 gcc_unreachable ();
4531}
4532
4533/* Create new basic block for bookkeeping code for path(s) incoming into
4534 E2->dest, except from E1->src. Return created block. */
4535static basic_block
4536create_block_for_bookkeeping (edge e1, edge e2)
4537{
4538 basic_block new_bb, bb = e2->dest;
4539
4540 /* Check that we don't spoil the loop structure. */
4541 if (current_loop_nest)
4542 {
4543 basic_block latch = current_loop_nest->latch;
4544
4545 /* We do not split header. */
4546 gcc_assert (e2->dest != current_loop_nest->header);
4547
4548 /* We do not redirect the only edge to the latch block. */
4549 gcc_assert (e1->dest != latch
4550 || !single_pred_p (latch)
4551 || e1 != single_pred_edge (latch));
4552 }
4553
4554 /* Split BB to insert BOOK_INSN there. */
4555 new_bb = sched_split_block (bb, NULL);
4556
4557 /* Move note_list from the upper bb. */
4558 gcc_assert (BB_NOTE_LIST (new_bb) == NULL_RTX);
4559 BB_NOTE_LIST (new_bb) = BB_NOTE_LIST (bb);
4560 BB_NOTE_LIST (bb) = NULL_RTX;
4561
4562 gcc_assert (e2->dest == bb);
4563
4564 /* Skip block for bookkeeping copy when leaving E1->src. */
4565 if (e1->flags & EDGE_FALLTHRU)
4566 sel_redirect_edge_and_branch_force (e1, new_bb);
4567 else
4568 sel_redirect_edge_and_branch (e1, new_bb);
4569
4570 gcc_assert (e1->dest == new_bb);
4571 gcc_assert (sel_bb_empty_p (bb));
4572
b5b8b0ac
AO
4573 /* To keep basic block numbers in sync between debug and non-debug
4574 compilations, we have to rotate blocks here. Consider that we
4575 started from (a,b)->d, (c,d)->e, and d contained only debug
4576 insns. It would have been removed before if the debug insns
4577 weren't there, so we'd have split e rather than d. So what we do
4578 now is to swap the block numbers of new_bb and
4579 single_succ(new_bb) == e, so that the insns that were in e before
4580 get the new block number. */
4581
4582 if (MAY_HAVE_DEBUG_INSNS)
4583 {
4584 basic_block succ;
4585 insn_t insn = sel_bb_head (new_bb);
4586 insn_t last;
4587
4588 if (DEBUG_INSN_P (insn)
4589 && single_succ_p (new_bb)
4590 && (succ = single_succ (new_bb))
4591 && succ != EXIT_BLOCK_PTR
4592 && DEBUG_INSN_P ((last = sel_bb_end (new_bb))))
4593 {
4594 while (insn != last && (DEBUG_INSN_P (insn) || NOTE_P (insn)))
4595 insn = NEXT_INSN (insn);
4596
4597 if (insn == last)
4598 {
4599 sel_global_bb_info_def gbi;
4600 sel_region_bb_info_def rbi;
4601 int i;
4602
4603 if (sched_verbose >= 2)
4604 sel_print ("Swapping block ids %i and %i\n",
4605 new_bb->index, succ->index);
4606
4607 i = new_bb->index;
4608 new_bb->index = succ->index;
4609 succ->index = i;
4610
4611 SET_BASIC_BLOCK (new_bb->index, new_bb);
4612 SET_BASIC_BLOCK (succ->index, succ);
4613
4614 memcpy (&gbi, SEL_GLOBAL_BB_INFO (new_bb), sizeof (gbi));
4615 memcpy (SEL_GLOBAL_BB_INFO (new_bb), SEL_GLOBAL_BB_INFO (succ),
4616 sizeof (gbi));
4617 memcpy (SEL_GLOBAL_BB_INFO (succ), &gbi, sizeof (gbi));
4618
4619 memcpy (&rbi, SEL_REGION_BB_INFO (new_bb), sizeof (rbi));
4620 memcpy (SEL_REGION_BB_INFO (new_bb), SEL_REGION_BB_INFO (succ),
4621 sizeof (rbi));
4622 memcpy (SEL_REGION_BB_INFO (succ), &rbi, sizeof (rbi));
4623
4624 i = BLOCK_TO_BB (new_bb->index);
4625 BLOCK_TO_BB (new_bb->index) = BLOCK_TO_BB (succ->index);
4626 BLOCK_TO_BB (succ->index) = i;
4627
4628 i = CONTAINING_RGN (new_bb->index);
4629 CONTAINING_RGN (new_bb->index) = CONTAINING_RGN (succ->index);
4630 CONTAINING_RGN (succ->index) = i;
4631
4632 for (i = 0; i < current_nr_blocks; i++)
4633 if (BB_TO_BLOCK (i) == succ->index)
4634 BB_TO_BLOCK (i) = new_bb->index;
4635 else if (BB_TO_BLOCK (i) == new_bb->index)
4636 BB_TO_BLOCK (i) = succ->index;
4637
4638 FOR_BB_INSNS (new_bb, insn)
4639 if (INSN_P (insn))
4640 EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = new_bb->index;
4641
4642 FOR_BB_INSNS (succ, insn)
4643 if (INSN_P (insn))
4644 EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = succ->index;
4645
4646 if (bitmap_bit_p (code_motion_visited_blocks, new_bb->index))
4647 {
4648 bitmap_set_bit (code_motion_visited_blocks, succ->index);
4649 bitmap_clear_bit (code_motion_visited_blocks, new_bb->index);
4650 }
4651
4652 gcc_assert (LABEL_P (BB_HEAD (new_bb))
4653 && LABEL_P (BB_HEAD (succ)));
4654
4655 if (sched_verbose >= 4)
4656 sel_print ("Swapping code labels %i and %i\n",
4657 CODE_LABEL_NUMBER (BB_HEAD (new_bb)),
4658 CODE_LABEL_NUMBER (BB_HEAD (succ)));
4659
4660 i = CODE_LABEL_NUMBER (BB_HEAD (new_bb));
4661 CODE_LABEL_NUMBER (BB_HEAD (new_bb))
4662 = CODE_LABEL_NUMBER (BB_HEAD (succ));
4663 CODE_LABEL_NUMBER (BB_HEAD (succ)) = i;
4664 }
4665 }
4666 }
4667
e855c69d
AB
4668 return bb;
4669}
4670
4671/* Return insn after which we must insert bookkeeping code for path(s) incoming
4672 into E2->dest, except from E1->src. */
4673static insn_t
4674find_place_for_bookkeeping (edge e1, edge e2)
4675{
4676 insn_t place_to_insert;
4677 /* Find a basic block that can hold bookkeeping. If it can be found, do not
4678 create new basic block, but insert bookkeeping there. */
b5b8b0ac 4679 basic_block book_block = find_block_for_bookkeeping (e1, e2, FALSE);
e855c69d 4680
b5b8b0ac
AO
4681 if (book_block)
4682 {
4683 place_to_insert = BB_END (book_block);
4684
4685 /* Don't use a block containing only debug insns for
4686 bookkeeping, this causes scheduling differences between debug
4687 and non-debug compilations, for the block would have been
4688 removed already. */
4689 if (DEBUG_INSN_P (place_to_insert))
4690 {
4691 rtx insn = sel_bb_head (book_block);
e855c69d 4692
b5b8b0ac
AO
4693 while (insn != place_to_insert &&
4694 (DEBUG_INSN_P (insn) || NOTE_P (insn)))
4695 insn = NEXT_INSN (insn);
4696
4697 if (insn == place_to_insert)
4698 book_block = NULL;
4699 }
4700 }
4701
4702 if (!book_block)
4703 {
4704 book_block = create_block_for_bookkeeping (e1, e2);
4705 place_to_insert = BB_END (book_block);
4706 if (sched_verbose >= 9)
4707 sel_print ("New block is %i, split from bookkeeping block %i\n",
4708 EDGE_SUCC (book_block, 0)->dest->index, book_block->index);
4709 }
4710 else
4711 {
4712 if (sched_verbose >= 9)
4713 sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index);
4714 }
e855c69d
AB
4715
4716 /* If basic block ends with a jump, insert bookkeeping code right before it. */
4717 if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert))
4718 place_to_insert = PREV_INSN (place_to_insert);
4719
4720 return place_to_insert;
4721}
4722
4723/* Find a proper seqno for bookkeeing insn inserted at PLACE_TO_INSERT
4724 for JOIN_POINT. */
4725static int
4726find_seqno_for_bookkeeping (insn_t place_to_insert, insn_t join_point)
4727{
4728 int seqno;
4729 rtx next;
4730
4731 /* Check if we are about to insert bookkeeping copy before a jump, and use
4732 jump's seqno for the copy; otherwise, use JOIN_POINT's seqno. */
4733 next = NEXT_INSN (place_to_insert);
b8698a0f 4734 if (INSN_P (next)
e855c69d
AB
4735 && JUMP_P (next)
4736 && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
da7ba240
AB
4737 {
4738 gcc_assert (INSN_SCHED_TIMES (next) == 0);
4739 seqno = INSN_SEQNO (next);
4740 }
e855c69d
AB
4741 else if (INSN_SEQNO (join_point) > 0)
4742 seqno = INSN_SEQNO (join_point);
4743 else
da7ba240
AB
4744 {
4745 seqno = get_seqno_by_preds (place_to_insert);
4746
b8698a0f
L
4747 /* Sometimes the fences can move in such a way that there will be
4748 no instructions with positive seqno around this bookkeeping.
da7ba240
AB
4749 This means that there will be no way to get to it by a regular
4750 fence movement. Never mind because we pick up such pieces for
4751 rescheduling anyways, so any positive value will do for now. */
4752 if (seqno < 0)
4753 {
4754 gcc_assert (pipelining_p);
4755 seqno = 1;
4756 }
4757 }
b8698a0f 4758
e855c69d
AB
4759 gcc_assert (seqno > 0);
4760 return seqno;
4761}
4762
4763/* Insert bookkeeping copy of C_EXPS's insn after PLACE_TO_INSERT, assigning
4764 NEW_SEQNO to it. Return created insn. */
4765static insn_t
4766emit_bookkeeping_insn (insn_t place_to_insert, expr_t c_expr, int new_seqno)
4767{
4768 rtx new_insn_rtx = create_copy_of_insn_rtx (EXPR_INSN_RTX (c_expr));
4769
4770 vinsn_t new_vinsn
4771 = create_vinsn_from_insn_rtx (new_insn_rtx,
4772 VINSN_UNIQUE_P (EXPR_VINSN (c_expr)));
4773
4774 insn_t new_insn = emit_insn_from_expr_after (c_expr, new_vinsn, new_seqno,
4775 place_to_insert);
4776
4777 INSN_SCHED_TIMES (new_insn) = 0;
4778 bitmap_set_bit (current_copies, INSN_UID (new_insn));
4779
4780 return new_insn;
4781}
4782
4783/* Generate a bookkeeping copy of C_EXPR's insn for path(s) incoming into to
4784 E2->dest, except from E1->src (there may be a sequence of empty blocks
4785 between E1->src and E2->dest). Return block containing the copy.
4786 All scheduler data is initialized for the newly created insn. */
4787static basic_block
4788generate_bookkeeping_insn (expr_t c_expr, edge e1, edge e2)
4789{
4790 insn_t join_point, place_to_insert, new_insn;
4791 int new_seqno;
4792 bool need_to_exchange_data_sets;
4793
4794 if (sched_verbose >= 4)
4795 sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index,
4796 e2->dest->index);
4797
4798 join_point = sel_bb_head (e2->dest);
4799 place_to_insert = find_place_for_bookkeeping (e1, e2);
b5b8b0ac
AO
4800 if (!place_to_insert)
4801 return NULL;
e855c69d
AB
4802 new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point);
4803 need_to_exchange_data_sets
4804 = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert));
4805
4806 new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno);
4807
4808 /* When inserting bookkeeping insn in new block, av sets should be
4809 following: old basic block (that now holds bookkeeping) data sets are
4810 the same as was before generation of bookkeeping, and new basic block
4811 (that now hold all other insns of old basic block) data sets are
4812 invalid. So exchange data sets for these basic blocks as sel_split_block
4813 mistakenly exchanges them in this case. Cannot do it earlier because
4814 when single instruction is added to new basic block it should hold NULL
4815 lv_set. */
4816 if (need_to_exchange_data_sets)
4817 exchange_data_sets (BLOCK_FOR_INSN (new_insn),
4818 BLOCK_FOR_INSN (join_point));
4819
4820 stat_bookkeeping_copies++;
4821 return BLOCK_FOR_INSN (new_insn);
4822}
4823
b8698a0f 4824/* Remove from AV_PTR all insns that may need bookkeeping when scheduling
e855c69d
AB
4825 on FENCE, but we are unable to copy them. */
4826static void
4827remove_insns_that_need_bookkeeping (fence_t fence, av_set_t *av_ptr)
4828{
4829 expr_t expr;
4830 av_set_iterator i;
4831
b8698a0f
L
4832 /* An expression does not need bookkeeping if it is available on all paths
4833 from current block to original block and current block dominates
4834 original block. We check availability on all paths by examining
4835 EXPR_SPEC; this is not equivalent, because it may be positive even
4836 if expr is available on all paths (but if expr is not available on
e855c69d
AB
4837 any path, EXPR_SPEC will be positive). */
4838
4839 FOR_EACH_EXPR_1 (expr, i, av_ptr)
4840 {
4841 if (!control_flow_insn_p (EXPR_INSN_RTX (expr))
4842 && (!bookkeeping_p || VINSN_UNIQUE_P (EXPR_VINSN (expr)))
4843 && (EXPR_SPEC (expr)
4844 || !EXPR_ORIG_BB_INDEX (expr)
4845 || !dominated_by_p (CDI_DOMINATORS,
4846 BASIC_BLOCK (EXPR_ORIG_BB_INDEX (expr)),
4847 BLOCK_FOR_INSN (FENCE_INSN (fence)))))
4848 {
4849 if (sched_verbose >= 4)
4850 sel_print ("Expr %d removed because it would need bookkeeping, which "
4851 "cannot be created\n", INSN_UID (EXPR_INSN_RTX (expr)));
4852 av_set_iter_remove (&i);
4853 }
4854 }
4855}
4856
4857/* Moving conditional jump through some instructions.
4858
4859 Consider example:
4860
4861 ... <- current scheduling point
4862 NOTE BASIC BLOCK: <- bb header
4863 (p8) add r14=r14+0x9;;
4864 (p8) mov [r14]=r23
4865 (!p8) jump L1;;
4866 NOTE BASIC BLOCK:
4867 ...
4868
b8698a0f 4869 We can schedule jump one cycle earlier, than mov, because they cannot be
e855c69d
AB
4870 executed together as their predicates are mutually exclusive.
4871
b8698a0f
L
4872 This is done in this way: first, new fallthrough basic block is created
4873 after jump (it is always can be done, because there already should be a
e855c69d 4874 fallthrough block, where control flow goes in case of predicate being true -
b8698a0f
L
4875 in our example; otherwise there should be a dependence between those
4876 instructions and jump and we cannot schedule jump right now);
4877 next, all instructions between jump and current scheduling point are moved
e855c69d
AB
4878 to this new block. And the result is this:
4879
4880 NOTE BASIC BLOCK:
4881 (!p8) jump L1 <- current scheduling point
4882 NOTE BASIC BLOCK: <- bb header
4883 (p8) add r14=r14+0x9;;
4884 (p8) mov [r14]=r23
4885 NOTE BASIC BLOCK:
4886 ...
4887*/
4888static void
4889move_cond_jump (rtx insn, bnd_t bnd)
4890{
4891 edge ft_edge;
4892 basic_block block_from, block_next, block_new;
4893 rtx next, prev, link;
4894
4895 /* BLOCK_FROM holds basic block of the jump. */
4896 block_from = BLOCK_FOR_INSN (insn);
4897
4898 /* Moving of jump should not cross any other jumps or
4899 beginnings of new basic blocks. */
4900 gcc_assert (block_from == BLOCK_FOR_INSN (BND_TO (bnd)));
4901
4902 /* Jump is moved to the boundary. */
4903 prev = BND_TO (bnd);
4904 next = PREV_INSN (insn);
4905 BND_TO (bnd) = insn;
4906
4907 ft_edge = find_fallthru_edge (block_from);
4908 block_next = ft_edge->dest;
4909 /* There must be a fallthrough block (or where should go
4910 control flow in case of false jump predicate otherwise?). */
4911 gcc_assert (block_next);
4912
4913 /* Create new empty basic block after source block. */
4914 block_new = sel_split_edge (ft_edge);
4915 gcc_assert (block_new->next_bb == block_next
4916 && block_from->next_bb == block_new);
4917
4918 gcc_assert (BB_END (block_from) == insn);
4919
4920 /* Move all instructions except INSN from BLOCK_FROM to
4921 BLOCK_NEW. */
4922 for (link = prev; link != insn; link = NEXT_INSN (link))
4923 {
4924 EXPR_ORIG_BB_INDEX (INSN_EXPR (link)) = block_new->index;
4925 df_insn_change_bb (link, block_new);
4926 }
4927
4928 /* Set correct basic block and instructions properties. */
4929 BB_END (block_new) = PREV_INSN (insn);
4930
4931 NEXT_INSN (PREV_INSN (prev)) = insn;
4932 PREV_INSN (insn) = PREV_INSN (prev);
4933
4934 /* Assert there is no jump to BLOCK_NEW, only fallthrough edge. */
4935 gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (block_new)));
4936 PREV_INSN (prev) = BB_HEAD (block_new);
4937 NEXT_INSN (next) = NEXT_INSN (BB_HEAD (block_new));
4938 NEXT_INSN (BB_HEAD (block_new)) = prev;
4939 PREV_INSN (NEXT_INSN (next)) = next;
4940
4941 gcc_assert (!sel_bb_empty_p (block_from)
4942 && !sel_bb_empty_p (block_new));
4943
4944 /* Update data sets for BLOCK_NEW to represent that INSN and
4945 instructions from the other branch of INSN is no longer
4946 available at BLOCK_NEW. */
4947 BB_AV_LEVEL (block_new) = global_level;
4948 gcc_assert (BB_LV_SET (block_new) == NULL);
4949 BB_LV_SET (block_new) = get_clear_regset_from_pool ();
4950 update_data_sets (sel_bb_head (block_new));
4951
4952 /* INSN is a new basic block header - so prepare its data
4953 structures and update availability and liveness sets. */
4954 update_data_sets (insn);
4955
4956 if (sched_verbose >= 4)
4957 sel_print ("Moving jump %d\n", INSN_UID (insn));
4958}
4959
4960/* Remove nops generated during move_op for preventing removal of empty
4961 basic blocks. */
4962static void
b5b8b0ac 4963remove_temp_moveop_nops (bool full_tidying)
e855c69d
AB
4964{
4965 int i;
4966 insn_t insn;
b8698a0f 4967
e855c69d
AB
4968 for (i = 0; VEC_iterate (insn_t, vec_temp_moveop_nops, i, insn); i++)
4969 {
4970 gcc_assert (INSN_NOP_P (insn));
b5b8b0ac 4971 return_nop_to_pool (insn, full_tidying);
e855c69d
AB
4972 }
4973
4974 /* Empty the vector. */
4975 if (VEC_length (insn_t, vec_temp_moveop_nops) > 0)
b8698a0f 4976 VEC_block_remove (insn_t, vec_temp_moveop_nops, 0,
e855c69d
AB
4977 VEC_length (insn_t, vec_temp_moveop_nops));
4978}
4979
4980/* Records the maximal UID before moving up an instruction. Used for
4981 distinguishing between bookkeeping copies and original insns. */
4982static int max_uid_before_move_op = 0;
4983
4984/* Remove from AV_VLIW_P all instructions but next when debug counter
4985 tells us so. Next instruction is fetched from BNDS. */
4986static void
4987remove_insns_for_debug (blist_t bnds, av_set_t *av_vliw_p)
4988{
4989 if (! dbg_cnt (sel_sched_insn_cnt))
4990 /* Leave only the next insn in av_vliw. */
4991 {
4992 av_set_iterator av_it;
4993 expr_t expr;
4994 bnd_t bnd = BLIST_BND (bnds);
4995 insn_t next = BND_TO (bnd);
4996
4997 gcc_assert (BLIST_NEXT (bnds) == NULL);
4998
4999 FOR_EACH_EXPR_1 (expr, av_it, av_vliw_p)
5000 if (EXPR_INSN_RTX (expr) != next)
5001 av_set_iter_remove (&av_it);
5002 }
5003}
5004
b8698a0f 5005/* Compute available instructions on BNDS. FENCE is the current fence. Write
e855c69d
AB
5006 the computed set to *AV_VLIW_P. */
5007static void
5008compute_av_set_on_boundaries (fence_t fence, blist_t bnds, av_set_t *av_vliw_p)
5009{
5010 if (sched_verbose >= 2)
5011 {
5012 sel_print ("Boundaries: ");
5013 dump_blist (bnds);
5014 sel_print ("\n");
5015 }
5016
5017 for (; bnds; bnds = BLIST_NEXT (bnds))
5018 {
5019 bnd_t bnd = BLIST_BND (bnds);
5020 av_set_t av1_copy;
5021 insn_t bnd_to = BND_TO (bnd);
5022
5023 /* Rewind BND->TO to the basic block header in case some bookkeeping
5024 instructions were inserted before BND->TO and it needs to be
5025 adjusted. */
5026 if (sel_bb_head_p (bnd_to))
5027 gcc_assert (INSN_SCHED_TIMES (bnd_to) == 0);
5028 else
5029 while (INSN_SCHED_TIMES (PREV_INSN (bnd_to)) == 0)
5030 {
5031 bnd_to = PREV_INSN (bnd_to);
5032 if (sel_bb_head_p (bnd_to))
5033 break;
5034 }
5035
5036 if (BND_TO (bnd) != bnd_to)
5037 {
5038 gcc_assert (FENCE_INSN (fence) == BND_TO (bnd));
5039 FENCE_INSN (fence) = bnd_to;
5040 BND_TO (bnd) = bnd_to;
5041 }
5042
5043 av_set_clear (&BND_AV (bnd));
5044 BND_AV (bnd) = compute_av_set (BND_TO (bnd), NULL, 0, true);
5045
5046 av_set_clear (&BND_AV1 (bnd));
5047 BND_AV1 (bnd) = av_set_copy (BND_AV (bnd));
5048
5049 moveup_set_inside_insn_group (&BND_AV1 (bnd), NULL);
b8698a0f 5050
e855c69d
AB
5051 av1_copy = av_set_copy (BND_AV1 (bnd));
5052 av_set_union_and_clear (av_vliw_p, &av1_copy, NULL);
5053 }
5054
5055 if (sched_verbose >= 2)
5056 {
5057 sel_print ("Available exprs (vliw form): ");
5058 dump_av_set (*av_vliw_p);
5059 sel_print ("\n");
5060 }
5061}
5062
b8698a0f
L
5063/* Calculate the sequential av set on BND corresponding to the EXPR_VLIW
5064 expression. When FOR_MOVEOP is true, also replace the register of
e855c69d
AB
5065 expressions found with the register from EXPR_VLIW. */
5066static av_set_t
5067find_sequential_best_exprs (bnd_t bnd, expr_t expr_vliw, bool for_moveop)
5068{
5069 av_set_t expr_seq = NULL;
5070 expr_t expr;
5071 av_set_iterator i;
b8698a0f 5072
e855c69d
AB
5073 FOR_EACH_EXPR (expr, i, BND_AV (bnd))
5074 {
5075 if (equal_after_moveup_path_p (expr, NULL, expr_vliw))
5076 {
5077 if (for_moveop)
5078 {
b8698a0f
L
5079 /* The sequential expression has the right form to pass
5080 to move_op except when renaming happened. Put the
e855c69d
AB
5081 correct register in EXPR then. */
5082 if (EXPR_SEPARABLE_P (expr) && REG_P (EXPR_LHS (expr)))
5083 {
5084 if (expr_dest_regno (expr) != expr_dest_regno (expr_vliw))
5085 {
5086 replace_dest_with_reg_in_expr (expr, EXPR_LHS (expr_vliw));
5087 stat_renamed_scheduled++;
5088 }
b8698a0f
L
5089 /* Also put the correct TARGET_AVAILABLE bit on the expr.
5090 This is needed when renaming came up with original
e855c69d 5091 register. */
b8698a0f 5092 else if (EXPR_TARGET_AVAILABLE (expr)
e855c69d
AB
5093 != EXPR_TARGET_AVAILABLE (expr_vliw))
5094 {
5095 gcc_assert (EXPR_TARGET_AVAILABLE (expr_vliw) == 1);
5096 EXPR_TARGET_AVAILABLE (expr) = 1;
5097 }
5098 }
5099 if (EXPR_WAS_SUBSTITUTED (expr))
5100 stat_substitutions_total++;
5101 }
5102
5103 av_set_add (&expr_seq, expr);
b8698a0f
L
5104
5105 /* With substitution inside insn group, it is possible
5106 that more than one expression in expr_seq will correspond
5107 to expr_vliw. In this case, choose one as the attempt to
e855c69d
AB
5108 move both leads to miscompiles. */
5109 break;
5110 }
5111 }
5112
5113 if (for_moveop && sched_verbose >= 2)
5114 {
5115 sel_print ("Best expression(s) (sequential form): ");
5116 dump_av_set (expr_seq);
5117 sel_print ("\n");
5118 }
b8698a0f 5119
e855c69d
AB
5120 return expr_seq;
5121}
5122
5123
5124/* Move nop to previous block. */
5125static void ATTRIBUTE_UNUSED
5126move_nop_to_previous_block (insn_t nop, basic_block prev_bb)
5127{
5128 insn_t prev_insn, next_insn, note;
5129
b8698a0f 5130 gcc_assert (sel_bb_head_p (nop)
e855c69d
AB
5131 && prev_bb == BLOCK_FOR_INSN (nop)->prev_bb);
5132 note = bb_note (BLOCK_FOR_INSN (nop));
5133 prev_insn = sel_bb_end (prev_bb);
5134 next_insn = NEXT_INSN (nop);
5135 gcc_assert (prev_insn != NULL_RTX
5136 && PREV_INSN (note) == prev_insn);
5137
5138 NEXT_INSN (prev_insn) = nop;
5139 PREV_INSN (nop) = prev_insn;
5140
5141 PREV_INSN (note) = nop;
5142 NEXT_INSN (note) = next_insn;
5143
5144 NEXT_INSN (nop) = note;
5145 PREV_INSN (next_insn) = note;
5146
5147 BB_END (prev_bb) = nop;
5148 BLOCK_FOR_INSN (nop) = prev_bb;
5149}
5150
5151/* Prepare a place to insert the chosen expression on BND. */
5152static insn_t
5153prepare_place_to_insert (bnd_t bnd)
5154{
5155 insn_t place_to_insert;
5156
5157 /* Init place_to_insert before calling move_op, as the later
5158 can possibly remove BND_TO (bnd). */
5159 if (/* If this is not the first insn scheduled. */
5160 BND_PTR (bnd))
5161 {
5162 /* Add it after last scheduled. */
5163 place_to_insert = ILIST_INSN (BND_PTR (bnd));
b5b8b0ac
AO
5164 if (DEBUG_INSN_P (place_to_insert))
5165 {
5166 ilist_t l = BND_PTR (bnd);
5167 while ((l = ILIST_NEXT (l)) &&
5168 DEBUG_INSN_P (ILIST_INSN (l)))
5169 ;
5170 if (!l)
5171 place_to_insert = NULL;
5172 }
e855c69d
AB
5173 }
5174 else
b5b8b0ac
AO
5175 place_to_insert = NULL;
5176
5177 if (!place_to_insert)
e855c69d
AB
5178 {
5179 /* Add it before BND_TO. The difference is in the
5180 basic block, where INSN will be added. */
5181 place_to_insert = get_nop_from_pool (BND_TO (bnd));
5182 gcc_assert (BLOCK_FOR_INSN (place_to_insert)
5183 == BLOCK_FOR_INSN (BND_TO (bnd)));
5184 }
5185
5186 return place_to_insert;
5187}
5188
b8698a0f 5189/* Find original instructions for EXPR_SEQ and move it to BND boundary.
e855c69d 5190 Return the expression to emit in C_EXPR. */
72a54528 5191static bool
b8698a0f 5192move_exprs_to_boundary (bnd_t bnd, expr_t expr_vliw,
e855c69d
AB
5193 av_set_t expr_seq, expr_t c_expr)
5194{
72a54528 5195 bool b, should_move;
e855c69d
AB
5196 unsigned book_uid;
5197 bitmap_iterator bi;
5198 int n_bookkeeping_copies_before_moveop;
5199
5200 /* Make a move. This call will remove the original operation,
5201 insert all necessary bookkeeping instructions and update the
5202 data sets. After that all we have to do is add the operation
5203 at before BND_TO (BND). */
5204 n_bookkeeping_copies_before_moveop = stat_bookkeeping_copies;
5205 max_uid_before_move_op = get_max_uid ();
5206 bitmap_clear (current_copies);
5207 bitmap_clear (current_originators);
5208
b8698a0f 5209 b = move_op (BND_TO (bnd), expr_seq, expr_vliw,
72a54528 5210 get_dest_from_orig_ops (expr_seq), c_expr, &should_move);
e855c69d 5211
b8698a0f 5212 /* We should be able to find the expression we've chosen for
e855c69d 5213 scheduling. */
72a54528 5214 gcc_assert (b);
b8698a0f 5215
e855c69d
AB
5216 if (stat_bookkeeping_copies > n_bookkeeping_copies_before_moveop)
5217 stat_insns_needed_bookkeeping++;
b8698a0f 5218
e855c69d
AB
5219 EXECUTE_IF_SET_IN_BITMAP (current_copies, 0, book_uid, bi)
5220 {
14f30b87
AM
5221 unsigned uid;
5222 bitmap_iterator bi;
5223
e855c69d
AB
5224 /* We allocate these bitmaps lazily. */
5225 if (! INSN_ORIGINATORS_BY_UID (book_uid))
5226 INSN_ORIGINATORS_BY_UID (book_uid) = BITMAP_ALLOC (NULL);
b8698a0f
L
5227
5228 bitmap_copy (INSN_ORIGINATORS_BY_UID (book_uid),
e855c69d 5229 current_originators);
14f30b87
AM
5230
5231 /* Transitively add all originators' originators. */
5232 EXECUTE_IF_SET_IN_BITMAP (current_originators, 0, uid, bi)
5233 if (INSN_ORIGINATORS_BY_UID (uid))
5234 bitmap_ior_into (INSN_ORIGINATORS_BY_UID (book_uid),
5235 INSN_ORIGINATORS_BY_UID (uid));
e855c69d 5236 }
72a54528
AM
5237
5238 return should_move;
e855c69d
AB
5239}
5240
5241
5242/* Debug a DFA state as an array of bytes. */
5243static void
5244debug_state (state_t state)
5245{
5246 unsigned char *p;
5247 unsigned int i, size = dfa_state_size;
5248
5249 sel_print ("state (%u):", size);
5250 for (i = 0, p = (unsigned char *) state; i < size; i++)
5251 sel_print (" %d", p[i]);
5252 sel_print ("\n");
5253}
5254
b8698a0f 5255/* Advance state on FENCE with INSN. Return true if INSN is
e855c69d
AB
5256 an ASM, and we should advance state once more. */
5257static bool
5258advance_state_on_fence (fence_t fence, insn_t insn)
5259{
5260 bool asm_p;
5261
5262 if (recog_memoized (insn) >= 0)
5263 {
5264 int res;
5265 state_t temp_state = alloca (dfa_state_size);
b8698a0f 5266
e855c69d
AB
5267 gcc_assert (!INSN_ASM_P (insn));
5268 asm_p = false;
5269
5270 memcpy (temp_state, FENCE_STATE (fence), dfa_state_size);
5271 res = state_transition (FENCE_STATE (fence), insn);
5272 gcc_assert (res < 0);
5273
5274 if (memcmp (temp_state, FENCE_STATE (fence), dfa_state_size))
5275 {
5276 FENCE_ISSUED_INSNS (fence)++;
5277
5278 /* We should never issue more than issue_rate insns. */
5279 if (FENCE_ISSUED_INSNS (fence) > issue_rate)
5280 gcc_unreachable ();
5281 }
b8698a0f 5282 }
e855c69d
AB
5283 else
5284 {
b8698a0f 5285 /* This could be an ASM insn which we'd like to schedule
e855c69d
AB
5286 on the next cycle. */
5287 asm_p = INSN_ASM_P (insn);
5288 if (!FENCE_STARTS_CYCLE_P (fence) && asm_p)
5289 advance_one_cycle (fence);
5290 }
5291
5292 if (sched_verbose >= 2)
5293 debug_state (FENCE_STATE (fence));
b5b8b0ac
AO
5294 if (!DEBUG_INSN_P (insn))
5295 FENCE_STARTS_CYCLE_P (fence) = 0;
136e01a3 5296 FENCE_ISSUE_MORE (fence) = can_issue_more;
e855c69d
AB
5297 return asm_p;
5298}
5299
5300/* Update FENCE on which INSN was scheduled and this INSN, too. NEED_STALL
5301 is nonzero if we need to stall after issuing INSN. */
5302static void
5303update_fence_and_insn (fence_t fence, insn_t insn, int need_stall)
5304{
5305 bool asm_p;
b8698a0f 5306
e855c69d
AB
5307 /* First, reflect that something is scheduled on this fence. */
5308 asm_p = advance_state_on_fence (fence, insn);
5309 FENCE_LAST_SCHEDULED_INSN (fence) = insn;
5310 VEC_safe_push (rtx, gc, FENCE_EXECUTING_INSNS (fence), insn);
5311 if (SCHED_GROUP_P (insn))
5312 {
5313 FENCE_SCHED_NEXT (fence) = INSN_SCHED_NEXT (insn);
5314 SCHED_GROUP_P (insn) = 0;
5315 }
5316 else
5317 FENCE_SCHED_NEXT (fence) = NULL_RTX;
5318 if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence))
5319 FENCE_READY_TICKS (fence) [INSN_UID (insn)] = 0;
5320
5321 /* Set instruction scheduling info. This will be used in bundling,
5322 pipelining, tick computations etc. */
5323 ++INSN_SCHED_TIMES (insn);
5324 EXPR_TARGET_AVAILABLE (INSN_EXPR (insn)) = true;
5325 EXPR_ORIG_SCHED_CYCLE (INSN_EXPR (insn)) = FENCE_CYCLE (fence);
5326 INSN_AFTER_STALL_P (insn) = FENCE_AFTER_STALL_P (fence);
5327 INSN_SCHED_CYCLE (insn) = FENCE_CYCLE (fence);
5328
5329 /* This does not account for adjust_cost hooks, just add the biggest
b8698a0f 5330 constant the hook may add to the latency. TODO: make this
e855c69d 5331 a target dependent constant. */
b8698a0f
L
5332 INSN_READY_CYCLE (insn)
5333 = INSN_SCHED_CYCLE (insn) + (INSN_CODE (insn) < 0
e855c69d
AB
5334 ? 1
5335 : maximal_insn_latency (insn) + 1);
5336
5337 /* Change these fields last, as they're used above. */
5338 FENCE_AFTER_STALL_P (fence) = 0;
5339 if (asm_p || need_stall)
5340 advance_one_cycle (fence);
b8698a0f 5341
e855c69d
AB
5342 /* Indicate that we've scheduled something on this fence. */
5343 FENCE_SCHEDULED_P (fence) = true;
5344 scheduled_something_on_previous_fence = true;
5345
5346 /* Print debug information when insn's fields are updated. */
5347 if (sched_verbose >= 2)
5348 {
5349 sel_print ("Scheduling insn: ");
5350 dump_insn_1 (insn, 1);
5351 sel_print ("\n");
5352 }
5353}
5354
b5b8b0ac
AO
5355/* Update boundary BND (and, if needed, FENCE) with INSN, remove the
5356 old boundary from BNDSP, add new boundaries to BNDS_TAIL_P and
5357 return it. */
e855c69d 5358static blist_t *
b5b8b0ac 5359update_boundaries (fence_t fence, bnd_t bnd, insn_t insn, blist_t *bndsp,
e855c69d
AB
5360 blist_t *bnds_tailp)
5361{
5362 succ_iterator si;
5363 insn_t succ;
5364
5365 advance_deps_context (BND_DC (bnd), insn);
b8698a0f 5366 FOR_EACH_SUCC_1 (succ, si, insn,
e855c69d
AB
5367 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
5368 {
5369 ilist_t ptr = ilist_copy (BND_PTR (bnd));
b8698a0f 5370
e855c69d 5371 ilist_add (&ptr, insn);
b5b8b0ac
AO
5372
5373 if (DEBUG_INSN_P (insn) && sel_bb_end_p (insn)
5374 && is_ineligible_successor (succ, ptr))
5375 {
5376 ilist_clear (&ptr);
5377 continue;
5378 }
5379
5380 if (FENCE_INSN (fence) == insn && !sel_bb_end_p (insn))
5381 {
5382 if (sched_verbose >= 9)
5383 sel_print ("Updating fence insn from %i to %i\n",
5384 INSN_UID (insn), INSN_UID (succ));
5385 FENCE_INSN (fence) = succ;
5386 }
e855c69d
AB
5387 blist_add (bnds_tailp, succ, ptr, BND_DC (bnd));
5388 bnds_tailp = &BLIST_NEXT (*bnds_tailp);
5389 }
b8698a0f 5390
e855c69d
AB
5391 blist_remove (bndsp);
5392 return bnds_tailp;
5393}
5394
5395/* Schedule EXPR_VLIW on BND. Return the insn emitted. */
5396static insn_t
5397schedule_expr_on_boundary (bnd_t bnd, expr_t expr_vliw, int seqno)
5398{
5399 av_set_t expr_seq;
5400 expr_t c_expr = XALLOCA (expr_def);
5401 insn_t place_to_insert;
5402 insn_t insn;
72a54528 5403 bool should_move;
e855c69d
AB
5404
5405 expr_seq = find_sequential_best_exprs (bnd, expr_vliw, true);
5406
5407 /* In case of scheduling a jump skipping some other instructions,
b8698a0f 5408 prepare CFG. After this, jump is at the boundary and can be
e855c69d
AB
5409 scheduled as usual insn by MOVE_OP. */
5410 if (vinsn_cond_branch_p (EXPR_VINSN (expr_vliw)))
5411 {
5412 insn = EXPR_INSN_RTX (expr_vliw);
b8698a0f 5413
e855c69d 5414 /* Speculative jumps are not handled. */
b8698a0f 5415 if (insn != BND_TO (bnd)
e855c69d
AB
5416 && !sel_insn_is_speculation_check (insn))
5417 move_cond_jump (insn, bnd);
5418 }
5419
e855c69d
AB
5420 /* Find a place for C_EXPR to schedule. */
5421 place_to_insert = prepare_place_to_insert (bnd);
72a54528 5422 should_move = move_exprs_to_boundary (bnd, expr_vliw, expr_seq, c_expr);
e855c69d 5423 clear_expr (c_expr);
b8698a0f
L
5424
5425 /* Add the instruction. The corner case to care about is when
5426 the expr_seq set has more than one expr, and we chose the one that
5427 is not equal to expr_vliw. Then expr_vliw may be insn in stream, and
e855c69d
AB
5428 we can't use it. Generate the new vinsn. */
5429 if (INSN_IN_STREAM_P (EXPR_INSN_RTX (expr_vliw)))
5430 {
5431 vinsn_t vinsn_new;
b8698a0f 5432
e855c69d
AB
5433 vinsn_new = vinsn_copy (EXPR_VINSN (expr_vliw), false);
5434 change_vinsn_in_expr (expr_vliw, vinsn_new);
72a54528 5435 should_move = false;
e855c69d 5436 }
72a54528
AM
5437 if (should_move)
5438 insn = sel_move_insn (expr_vliw, seqno, place_to_insert);
5439 else
b8698a0f 5440 insn = emit_insn_from_expr_after (expr_vliw, NULL, seqno,
e855c69d 5441 place_to_insert);
e855c69d
AB
5442
5443 /* Return the nops generated for preserving of data sets back
5444 into pool. */
5445 if (INSN_NOP_P (place_to_insert))
b5b8b0ac
AO
5446 return_nop_to_pool (place_to_insert, !DEBUG_INSN_P (insn));
5447 remove_temp_moveop_nops (!DEBUG_INSN_P (insn));
e855c69d
AB
5448
5449 av_set_clear (&expr_seq);
b8698a0f
L
5450
5451 /* Save the expression scheduled so to reset target availability if we'll
e855c69d
AB
5452 meet it later on the same fence. */
5453 if (EXPR_WAS_RENAMED (expr_vliw))
5454 vinsn_vec_add (&vec_target_unavailable_vinsns, INSN_EXPR (insn));
5455
5456 /* Check that the recent movement didn't destroyed loop
5457 structure. */
5458 gcc_assert (!pipelining_p
5459 || current_loop_nest == NULL
5460 || loop_latch_edge (current_loop_nest));
5461 return insn;
5462}
5463
5464/* Stall for N cycles on FENCE. */
5465static void
5466stall_for_cycles (fence_t fence, int n)
5467{
5468 int could_more;
b8698a0f 5469
e855c69d
AB
5470 could_more = n > 1 || FENCE_ISSUED_INSNS (fence) < issue_rate;
5471 while (n--)
5472 advance_one_cycle (fence);
5473 if (could_more)
5474 FENCE_AFTER_STALL_P (fence) = 1;
5475}
5476
b8698a0f
L
5477/* Gather a parallel group of insns at FENCE and assign their seqno
5478 to SEQNO. All scheduled insns are gathered in SCHEDULED_INSNS_TAILPP
e855c69d
AB
5479 list for later recalculation of seqnos. */
5480static void
5481fill_insns (fence_t fence, int seqno, ilist_t **scheduled_insns_tailpp)
5482{
5483 blist_t bnds = NULL, *bnds_tailp;
5484 av_set_t av_vliw = NULL;
5485 insn_t insn = FENCE_INSN (fence);
5486
5487 if (sched_verbose >= 2)
b8698a0f 5488 sel_print ("Starting fill_insns for insn %d, cycle %d\n",
e855c69d
AB
5489 INSN_UID (insn), FENCE_CYCLE (fence));
5490
5491 blist_add (&bnds, insn, NULL, FENCE_DC (fence));
5492 bnds_tailp = &BLIST_NEXT (bnds);
5493 set_target_context (FENCE_TC (fence));
136e01a3 5494 can_issue_more = FENCE_ISSUE_MORE (fence);
e855c69d
AB
5495 target_bb = INSN_BB (insn);
5496
5497 /* Do while we can add any operation to the current group. */
5498 do
5499 {
5500 blist_t *bnds_tailp1, *bndsp;
5501 expr_t expr_vliw;
5502 int need_stall;
5503 int was_stall = 0, scheduled_insns = 0, stall_iterations = 0;
5504 int max_insns = pipelining_p ? issue_rate : 2 * issue_rate;
5505 int max_stall = pipelining_p ? 1 : 3;
b5b8b0ac
AO
5506 bool last_insn_was_debug = false;
5507 bool was_debug_bb_end_p = false;
5508
e855c69d
AB
5509 compute_av_set_on_boundaries (fence, bnds, &av_vliw);
5510 remove_insns_that_need_bookkeeping (fence, &av_vliw);
5511 remove_insns_for_debug (bnds, &av_vliw);
5512
5513 /* Return early if we have nothing to schedule. */
5514 if (av_vliw == NULL)
5515 break;
5516
5517 /* Choose the best expression and, if needed, destination register
5518 for it. */
5519 do
5520 {
5521 expr_vliw = find_best_expr (&av_vliw, bnds, fence, &need_stall);
5522 if (!expr_vliw && need_stall)
5523 {
5524 /* All expressions required a stall. Do not recompute av sets
5525 as we'll get the same answer (modulo the insns between
5526 the fence and its boundary, which will not be available for
5527 pipelining). */
5528 gcc_assert (! expr_vliw && stall_iterations < 2);
5529 was_stall++;
5530 /* If we are going to stall for too long, break to recompute av
5531 sets and bring more insns for pipelining. */
5532 if (need_stall <= 3)
5533 stall_for_cycles (fence, need_stall);
5534 else
5535 {
5536 stall_for_cycles (fence, 1);
5537 break;
5538 }
5539 }
5540 }
5541 while (! expr_vliw && need_stall);
b8698a0f 5542
e855c69d
AB
5543 /* Now either we've selected expr_vliw or we have nothing to schedule. */
5544 if (!expr_vliw)
5545 {
5546 av_set_clear (&av_vliw);
5547 break;
5548 }
5549
5550 bndsp = &bnds;
5551 bnds_tailp1 = bnds_tailp;
5552
5553 do
b8698a0f 5554 /* This code will be executed only once until we'd have several
e855c69d
AB
5555 boundaries per fence. */
5556 {
5557 bnd_t bnd = BLIST_BND (*bndsp);
5558
5559 if (!av_set_is_in_p (BND_AV1 (bnd), EXPR_VINSN (expr_vliw)))
5560 {
5561 bndsp = &BLIST_NEXT (*bndsp);
5562 continue;
5563 }
b8698a0f 5564
e855c69d 5565 insn = schedule_expr_on_boundary (bnd, expr_vliw, seqno);
b5b8b0ac
AO
5566 last_insn_was_debug = DEBUG_INSN_P (insn);
5567 if (last_insn_was_debug)
5568 was_debug_bb_end_p = (insn == BND_TO (bnd) && sel_bb_end_p (insn));
e855c69d 5569 update_fence_and_insn (fence, insn, need_stall);
b5b8b0ac 5570 bnds_tailp = update_boundaries (fence, bnd, insn, bndsp, bnds_tailp);
e855c69d
AB
5571
5572 /* Add insn to the list of scheduled on this cycle instructions. */
5573 ilist_add (*scheduled_insns_tailpp, insn);
5574 *scheduled_insns_tailpp = &ILIST_NEXT (**scheduled_insns_tailpp);
5575 }
5576 while (*bndsp != *bnds_tailp1);
5577
5578 av_set_clear (&av_vliw);
b5b8b0ac
AO
5579 if (!last_insn_was_debug)
5580 scheduled_insns++;
e855c69d
AB
5581
5582 /* We currently support information about candidate blocks only for
5583 one 'target_bb' block. Hence we can't schedule after jump insn,
5584 as this will bring two boundaries and, hence, necessity to handle
5585 information for two or more blocks concurrently. */
b5b8b0ac 5586 if ((last_insn_was_debug ? was_debug_bb_end_p : sel_bb_end_p (insn))
b8698a0f
L
5587 || (was_stall
5588 && (was_stall >= max_stall
e855c69d
AB
5589 || scheduled_insns >= max_insns)))
5590 break;
5591 }
5592 while (bnds);
5593
5594 gcc_assert (!FENCE_BNDS (fence));
b8698a0f 5595
e855c69d
AB
5596 /* Update boundaries of the FENCE. */
5597 while (bnds)
5598 {
5599 ilist_t ptr = BND_PTR (BLIST_BND (bnds));
5600
5601 if (ptr)
5602 {
5603 insn = ILIST_INSN (ptr);
5604
5605 if (!ilist_is_in_p (FENCE_BNDS (fence), insn))
5606 ilist_add (&FENCE_BNDS (fence), insn);
5607 }
b8698a0f 5608
e855c69d
AB
5609 blist_remove (&bnds);
5610 }
5611
5612 /* Update target context on the fence. */
5613 reset_target_context (FENCE_TC (fence), false);
5614}
5615
5616/* All exprs in ORIG_OPS must have the same destination register or memory.
5617 Return that destination. */
5618static rtx
5619get_dest_from_orig_ops (av_set_t orig_ops)
5620{
5621 rtx dest = NULL_RTX;
5622 av_set_iterator av_it;
5623 expr_t expr;
5624 bool first_p = true;
5625
5626 FOR_EACH_EXPR (expr, av_it, orig_ops)
5627 {
5628 rtx x = EXPR_LHS (expr);
5629
5630 if (first_p)
5631 {
5632 first_p = false;
5633 dest = x;
5634 }
5635 else
5636 gcc_assert (dest == x
5637 || (dest != NULL_RTX && x != NULL_RTX
5638 && rtx_equal_p (dest, x)));
5639 }
5640
5641 return dest;
5642}
5643
5644/* Update data sets for the bookkeeping block and record those expressions
5645 which become no longer available after inserting this bookkeeping. */
5646static void
5647update_and_record_unavailable_insns (basic_block book_block)
5648{
5649 av_set_iterator i;
5650 av_set_t old_av_set = NULL;
5651 expr_t cur_expr;
5652 rtx bb_end = sel_bb_end (book_block);
5653
b8698a0f 5654 /* First, get correct liveness in the bookkeeping block. The problem is
e855c69d
AB
5655 the range between the bookeeping insn and the end of block. */
5656 update_liveness_on_insn (bb_end);
5657 if (control_flow_insn_p (bb_end))
5658 update_liveness_on_insn (PREV_INSN (bb_end));
5659
5660 /* If there's valid av_set on BOOK_BLOCK, then there might exist another
5661 fence above, where we may choose to schedule an insn which is
5662 actually blocked from moving up with the bookkeeping we create here. */
5663 if (AV_SET_VALID_P (sel_bb_head (book_block)))
5664 {
5665 old_av_set = av_set_copy (BB_AV_SET (book_block));
5666 update_data_sets (sel_bb_head (book_block));
b8698a0f 5667
e855c69d
AB
5668 /* Traverse all the expressions in the old av_set and check whether
5669 CUR_EXPR is in new AV_SET. */
5670 FOR_EACH_EXPR (cur_expr, i, old_av_set)
5671 {
b8698a0f 5672 expr_t new_expr = av_set_lookup (BB_AV_SET (book_block),
e855c69d
AB
5673 EXPR_VINSN (cur_expr));
5674
b8698a0f
L
5675 if (! new_expr
5676 /* In this case, we can just turn off the E_T_A bit, but we can't
e855c69d 5677 represent this information with the current vector. */
b8698a0f 5678 || EXPR_TARGET_AVAILABLE (new_expr)
e855c69d
AB
5679 != EXPR_TARGET_AVAILABLE (cur_expr))
5680 /* Unfortunately, the below code could be also fired up on
5681 separable insns.
5682 FIXME: add an example of how this could happen. */
5683 vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr);
5684 }
5685
5686 av_set_clear (&old_av_set);
5687 }
5688}
5689
b8698a0f 5690/* The main effect of this function is that sparams->c_expr is merged
e855c69d
AB
5691 with (or copied to) lparams->c_expr_merged. If there's only one successor,
5692 we avoid merging anything by copying sparams->c_expr to lparams->c_expr_merged.
b8698a0f
L
5693 lparams->c_expr_merged is copied back to sparams->c_expr after all
5694 successors has been traversed. lparams->c_expr_local is an expr allocated
5695 on stack in the caller function, and is used if there is more than one
5696 successor.
e855c69d
AB
5697
5698 SUCC is one of the SUCCS_NORMAL successors of INSN,
5699 MOVEOP_DRV_CALL_RES is the result of call code_motion_path_driver on succ,
5700 LPARAMS and STATIC_PARAMS contain the parameters described above. */
5701static void
b8698a0f
L
5702move_op_merge_succs (insn_t insn ATTRIBUTE_UNUSED,
5703 insn_t succ ATTRIBUTE_UNUSED,
5704 int moveop_drv_call_res,
e855c69d
AB
5705 cmpd_local_params_p lparams, void *static_params)
5706{
5707 moveop_static_params_p sparams = (moveop_static_params_p) static_params;
5708
5709 /* Nothing to do, if original expr wasn't found below. */
5710 if (moveop_drv_call_res != 1)
5711 return;
5712
5713 /* If this is a first successor. */
5714 if (!lparams->c_expr_merged)
5715 {
5716 lparams->c_expr_merged = sparams->c_expr;
5717 sparams->c_expr = lparams->c_expr_local;
5718 }
5719 else
5720 {
5721 /* We must merge all found expressions to get reasonable
5722 EXPR_SPEC_DONE_DS for the resulting insn. If we don't
5723 do so then we can first find the expr with epsilon
5724 speculation success probability and only then with the
5725 good probability. As a result the insn will get epsilon
5726 probability and will never be scheduled because of
5727 weakness_cutoff in find_best_expr.
5728
b8698a0f 5729 We call merge_expr_data here instead of merge_expr
e855c69d
AB
5730 because due to speculation C_EXPR and X may have the
5731 same insns with different speculation types. And as of
b8698a0f 5732 now such insns are considered non-equal.
e855c69d 5733
b8698a0f
L
5734 However, EXPR_SCHED_TIMES is different -- we must get
5735 SCHED_TIMES from a real insn, not a bookkeeping copy.
e855c69d 5736 We force this here. Instead, we may consider merging
b8698a0f 5737 SCHED_TIMES to the maximum instead of minimum in the
e855c69d
AB
5738 below function. */
5739 int old_times = EXPR_SCHED_TIMES (lparams->c_expr_merged);
5740
5741 merge_expr_data (lparams->c_expr_merged, sparams->c_expr, NULL);
5742 if (EXPR_SCHED_TIMES (sparams->c_expr) == 0)
5743 EXPR_SCHED_TIMES (lparams->c_expr_merged) = old_times;
5744
5745 clear_expr (sparams->c_expr);
5746 }
5747}
5748
5749/* Add used regs for the successor SUCC into SPARAMS->USED_REGS.
5750
5751 SUCC is one of the SUCCS_NORMAL successors of INSN,
5752 MOVEOP_DRV_CALL_RES is the result of call code_motion_path_driver on succ or 0,
5753 if SUCC is one of SUCCS_BACK or SUCCS_OUT.
5754 STATIC_PARAMS contain USED_REGS set. */
5755static void
b8698a0f
L
5756fur_merge_succs (insn_t insn ATTRIBUTE_UNUSED, insn_t succ,
5757 int moveop_drv_call_res,
5758 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
e855c69d
AB
5759 void *static_params)
5760{
5761 regset succ_live;
5762 fur_static_params_p sparams = (fur_static_params_p) static_params;
5763
5764 /* Here we compute live regsets only for branches that do not lie
b8698a0f 5765 on the code motion paths. These branches correspond to value
e855c69d
AB
5766 MOVEOP_DRV_CALL_RES==0 and include SUCCS_BACK and SUCCS_OUT, though
5767 for such branches code_motion_path_driver is not called. */
5768 if (moveop_drv_call_res != 0)
5769 return;
5770
5771 /* Mark all registers that do not meet the following condition:
5772 (3) not live on the other path of any conditional branch
5773 that is passed by the operation, in case original
5774 operations are not present on both paths of the
5775 conditional branch. */
5776 succ_live = compute_live (succ);
5777 IOR_REG_SET (sparams->used_regs, succ_live);
5778}
5779
5780/* This function is called after the last successor. Copies LP->C_EXPR_MERGED
5781 into SP->CEXPR. */
5782static void
5783move_op_after_merge_succs (cmpd_local_params_p lp, void *sparams)
b8698a0f 5784{
e855c69d
AB
5785 moveop_static_params_p sp = (moveop_static_params_p) sparams;
5786
5787 sp->c_expr = lp->c_expr_merged;
5788}
5789
5790/* Track bookkeeping copies created, insns scheduled, and blocks for
5791 rescheduling when INSN is found by move_op. */
5792static void
5793track_scheduled_insns_and_blocks (rtx insn)
5794{
5795 /* Even if this insn can be a copy that will be removed during current move_op,
5796 we still need to count it as an originator. */
5797 bitmap_set_bit (current_originators, INSN_UID (insn));
5798
5799 if (!bitmap_bit_p (current_copies, INSN_UID (insn)))
5800 {
5801 /* Note that original block needs to be rescheduled, as we pulled an
5802 instruction out of it. */
5803 if (INSN_SCHED_TIMES (insn) > 0)
5804 bitmap_set_bit (blocks_to_reschedule, BLOCK_FOR_INSN (insn)->index);
b5b8b0ac 5805 else if (INSN_UID (insn) < first_emitted_uid && !DEBUG_INSN_P (insn))
e855c69d
AB
5806 num_insns_scheduled++;
5807 }
5808 else
5809 bitmap_clear_bit (current_copies, INSN_UID (insn));
5810
5811 /* For instructions we must immediately remove insn from the
5812 stream, so subsequent update_data_sets () won't include this
5813 insn into av_set.
5814 For expr we must make insn look like "INSN_REG (insn) := c_expr". */
5815 if (INSN_UID (insn) > max_uid_before_move_op)
5816 stat_bookkeeping_copies--;
5817}
5818
b8698a0f 5819/* Emit a register-register copy for INSN if needed. Return true if
e855c69d
AB
5820 emitted one. PARAMS is the move_op static parameters. */
5821static bool
b8698a0f 5822maybe_emit_renaming_copy (rtx insn,
e855c69d
AB
5823 moveop_static_params_p params)
5824{
5825 bool insn_emitted = false;
5826 rtx cur_reg = expr_dest_reg (params->c_expr);
5827
5828 gcc_assert (!cur_reg || (params->dest && REG_P (params->dest)));
5829
5830 /* If original operation has expr and the register chosen for
5831 that expr is not original operation's dest reg, substitute
5832 operation's right hand side with the register chosen. */
5833 if (cur_reg != NULL_RTX && REGNO (params->dest) != REGNO (cur_reg))
5834 {
5835 insn_t reg_move_insn, reg_move_insn_rtx;
b8698a0f
L
5836
5837 reg_move_insn_rtx = create_insn_rtx_with_rhs (INSN_VINSN (insn),
e855c69d 5838 params->dest);
b8698a0f
L
5839 reg_move_insn = sel_gen_insn_from_rtx_after (reg_move_insn_rtx,
5840 INSN_EXPR (insn),
5841 INSN_SEQNO (insn),
e855c69d
AB
5842 insn);
5843 EXPR_SPEC_DONE_DS (INSN_EXPR (reg_move_insn)) = 0;
5844 replace_dest_with_reg_in_expr (params->c_expr, params->dest);
b8698a0f 5845
e855c69d
AB
5846 insn_emitted = true;
5847 params->was_renamed = true;
5848 }
b8698a0f 5849
e855c69d
AB
5850 return insn_emitted;
5851}
5852
b8698a0f
L
5853/* Emit a speculative check for INSN speculated as EXPR if needed.
5854 Return true if we've emitted one. PARAMS is the move_op static
e855c69d
AB
5855 parameters. */
5856static bool
5857maybe_emit_speculative_check (rtx insn, expr_t expr,
5858 moveop_static_params_p params)
5859{
5860 bool insn_emitted = false;
5861 insn_t x;
5862 ds_t check_ds;
5863
5864 check_ds = get_spec_check_type_for_insn (insn, expr);
5865 if (check_ds != 0)
5866 {
5867 /* A speculation check should be inserted. */
5868 x = create_speculation_check (params->c_expr, check_ds, insn);
5869 insn_emitted = true;
5870 }
5871 else
5872 {
5873 EXPR_SPEC_DONE_DS (INSN_EXPR (insn)) = 0;
5874 x = insn;
5875 }
b8698a0f 5876
e855c69d
AB
5877 gcc_assert (EXPR_SPEC_DONE_DS (INSN_EXPR (x)) == 0
5878 && EXPR_SPEC_TO_CHECK_DS (INSN_EXPR (x)) == 0);
5879 return insn_emitted;
5880}
5881
b8698a0f
L
5882/* Handle transformations that leave an insn in place of original
5883 insn such as renaming/speculation. Return true if one of such
e855c69d
AB
5884 transformations actually happened, and we have emitted this insn. */
5885static bool
b8698a0f 5886handle_emitting_transformations (rtx insn, expr_t expr,
e855c69d
AB
5887 moveop_static_params_p params)
5888{
5889 bool insn_emitted = false;
5890
5891 insn_emitted = maybe_emit_renaming_copy (insn, params);
5892 insn_emitted |= maybe_emit_speculative_check (insn, expr, params);
5893
5894 return insn_emitted;
b8698a0f 5895}
e855c69d 5896
b5b8b0ac
AO
5897/* If INSN is the only insn in the basic block (not counting JUMP,
5898 which may be a jump to next insn, and DEBUG_INSNs), we want to
5899 leave a NOP there till the return to fill_insns. */
5900
5901static bool
5902need_nop_to_preserve_insn_bb (rtx insn)
e855c69d 5903{
b5b8b0ac 5904 insn_t bb_head, bb_end, bb_next, in_next;
e855c69d
AB
5905 basic_block bb = BLOCK_FOR_INSN (insn);
5906
e855c69d
AB
5907 bb_head = sel_bb_head (bb);
5908 bb_end = sel_bb_end (bb);
e855c69d 5909
b5b8b0ac
AO
5910 if (bb_head == bb_end)
5911 return true;
5912
5913 while (bb_head != bb_end && DEBUG_INSN_P (bb_head))
5914 bb_head = NEXT_INSN (bb_head);
5915
5916 if (bb_head == bb_end)
5917 return true;
5918
5919 while (bb_head != bb_end && DEBUG_INSN_P (bb_end))
5920 bb_end = PREV_INSN (bb_end);
5921
5922 if (bb_head == bb_end)
5923 return true;
5924
5925 bb_next = NEXT_INSN (bb_head);
5926 while (bb_next != bb_end && DEBUG_INSN_P (bb_next))
5927 bb_next = NEXT_INSN (bb_next);
5928
5929 if (bb_next == bb_end && JUMP_P (bb_end))
5930 return true;
5931
5932 in_next = NEXT_INSN (insn);
5933 while (DEBUG_INSN_P (in_next))
5934 in_next = NEXT_INSN (in_next);
5935
5936 if (IN_CURRENT_FENCE_P (in_next))
5937 return true;
5938
5939 return false;
5940}
5941
5942/* Remove INSN from stream. When ONLY_DISCONNECT is true, its data
5943 is not removed but reused when INSN is re-emitted. */
5944static void
5945remove_insn_from_stream (rtx insn, bool only_disconnect)
5946{
e855c69d
AB
5947 /* If there's only one insn in the BB, make sure that a nop is
5948 inserted into it, so the basic block won't disappear when we'll
5949 delete INSN below with sel_remove_insn. It should also survive
b8698a0f 5950 till the return to fill_insns. */
b5b8b0ac 5951 if (need_nop_to_preserve_insn_bb (insn))
e855c69d 5952 {
b5b8b0ac 5953 insn_t nop = get_nop_from_pool (insn);
e855c69d
AB
5954 gcc_assert (INSN_NOP_P (nop));
5955 VEC_safe_push (insn_t, heap, vec_temp_moveop_nops, nop);
5956 }
5957
5958 sel_remove_insn (insn, only_disconnect, false);
5959}
5960
5961/* This function is called when original expr is found.
b8698a0f 5962 INSN - current insn traversed, EXPR - the corresponding expr found.
e855c69d
AB
5963 LPARAMS is the local parameters of code modion driver, STATIC_PARAMS
5964 is static parameters of move_op. */
5965static void
b8698a0f
L
5966move_op_orig_expr_found (insn_t insn, expr_t expr,
5967 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
e855c69d
AB
5968 void *static_params)
5969{
5970 bool only_disconnect, insn_emitted;
5971 moveop_static_params_p params = (moveop_static_params_p) static_params;
b8698a0f 5972
e855c69d
AB
5973 copy_expr_onside (params->c_expr, INSN_EXPR (insn));
5974 track_scheduled_insns_and_blocks (insn);
5975 insn_emitted = handle_emitting_transformations (insn, expr, params);
5976 only_disconnect = (params->uid == INSN_UID (insn)
5977 && ! insn_emitted && ! EXPR_WAS_CHANGED (expr));
72a54528
AM
5978
5979 /* Mark that we've disconnected an insn. */
5980 if (only_disconnect)
5981 params->uid = -1;
e855c69d
AB
5982 remove_insn_from_stream (insn, only_disconnect);
5983}
5984
5985/* The function is called when original expr is found.
5986 INSN - current insn traversed, EXPR - the corresponding expr found,
5987 crosses_call and original_insns in STATIC_PARAMS are updated. */
5988static void
5989fur_orig_expr_found (insn_t insn, expr_t expr ATTRIBUTE_UNUSED,
5990 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
5991 void *static_params)
5992{
5993 fur_static_params_p params = (fur_static_params_p) static_params;
5994 regset tmp;
5995
5996 if (CALL_P (insn))
5997 params->crosses_call = true;
5998
5999 def_list_add (params->original_insns, insn, params->crosses_call);
6000
6001 /* Mark the registers that do not meet the following condition:
b8698a0f
L
6002 (2) not among the live registers of the point
6003 immediately following the first original operation on
e855c69d
AB
6004 a given downward path, except for the original target
6005 register of the operation. */
6006 tmp = get_clear_regset_from_pool ();
6007 compute_live_below_insn (insn, tmp);
6008 AND_COMPL_REG_SET (tmp, INSN_REG_SETS (insn));
6009 AND_COMPL_REG_SET (tmp, INSN_REG_CLOBBERS (insn));
6010 IOR_REG_SET (params->used_regs, tmp);
6011 return_regset_to_pool (tmp);
6012
6013 /* (*1) We need to add to USED_REGS registers that are read by
6014 INSN's lhs. This may lead to choosing wrong src register.
6015 E.g. (scheduling const expr enabled):
6016
6017 429: ax=0x0 <- Can't use AX for this expr (0x0)
6018 433: dx=[bp-0x18]
6019 427: [ax+dx+0x1]=ax
6020 REG_DEAD: ax
6021 168: di=dx
6022 REG_DEAD: dx
6023 */
b8698a0f 6024 /* FIXME: see comment above and enable MEM_P
e855c69d
AB
6025 in vinsn_separable_p. */
6026 gcc_assert (!VINSN_SEPARABLE_P (INSN_VINSN (insn))
6027 || !MEM_P (INSN_LHS (insn)));
6028}
6029
6030/* This function is called on the ascending pass, before returning from
6031 current basic block. */
6032static void
b8698a0f 6033move_op_at_first_insn (insn_t insn, cmpd_local_params_p lparams,
e855c69d
AB
6034 void *static_params)
6035{
6036 moveop_static_params_p sparams = (moveop_static_params_p) static_params;
6037 basic_block book_block = NULL;
6038
b8698a0f 6039 /* When we have removed the boundary insn for scheduling, which also
e855c69d 6040 happened to be the end insn in its bb, we don't need to update sets. */
b8698a0f 6041 if (!lparams->removed_last_insn
e855c69d
AB
6042 && lparams->e1
6043 && sel_bb_head_p (insn))
6044 {
6045 /* We should generate bookkeeping code only if we are not at the
6046 top level of the move_op. */
6047 if (sel_num_cfg_preds_gt_1 (insn))
6048 book_block = generate_bookkeeping_insn (sparams->c_expr,
6049 lparams->e1, lparams->e2);
6050 /* Update data sets for the current insn. */
6051 update_data_sets (insn);
6052 }
b8698a0f 6053
e855c69d 6054 /* If bookkeeping code was inserted, we need to update av sets of basic
b8698a0f 6055 block that received bookkeeping. After generation of bookkeeping insn,
e855c69d 6056 bookkeeping block does not contain valid av set because we are not following
b8698a0f 6057 the original algorithm in every detail with regards to e.g. renaming
e855c69d 6058 simple reg-reg copies. Consider example:
b8698a0f 6059
e855c69d
AB
6060 bookkeeping block scheduling fence
6061 \ /
6062 \ join /
6063 ----------
6064 | |
6065 ----------
6066 / \
6067 / \
6068 r1 := r2 r1 := r3
6069
b8698a0f 6070 We try to schedule insn "r1 := r3" on the current
e855c69d
AB
6071 scheduling fence. Also, note that av set of bookkeeping block
6072 contain both insns "r1 := r2" and "r1 := r3". When the insn has
6073 been scheduled, the CFG is as follows:
6074
6075 r1 := r3 r1 := r3
6076 bookkeeping block scheduling fence
6077 \ /
6078 \ join /
6079 ----------
6080 | |
6081 ----------
6082 / \
6083 / \
6084 r1 := r2
6085
6086 Here, insn "r1 := r3" was scheduled at the current scheduling point
6087 and bookkeeping code was generated at the bookeeping block. This
6088 way insn "r1 := r2" is no longer available as a whole instruction
6089 (but only as expr) ahead of insn "r1 := r3" in bookkeeping block.
b8698a0f 6090 This situation is handled by calling update_data_sets.
e855c69d
AB
6091
6092 Since update_data_sets is called only on the bookkeeping block, and
b8698a0f 6093 it also may have predecessors with av_sets, containing instructions that
e855c69d
AB
6094 are no longer available, we save all such expressions that become
6095 unavailable during data sets update on the bookkeeping block in
b8698a0f
L
6096 VEC_BOOKKEEPING_BLOCKED_VINSNS. Later we avoid selecting such
6097 expressions for scheduling. This allows us to avoid recomputation of
e855c69d 6098 av_sets outside the code motion path. */
b8698a0f 6099
e855c69d
AB
6100 if (book_block)
6101 update_and_record_unavailable_insns (book_block);
6102
6103 /* If INSN was previously marked for deletion, it's time to do it. */
6104 if (lparams->removed_last_insn)
6105 insn = PREV_INSN (insn);
b8698a0f 6106
e855c69d
AB
6107 /* Do not tidy control flow at the topmost moveop, as we can erroneously
6108 kill a block with a single nop in which the insn should be emitted. */
6109 if (lparams->e1)
6110 tidy_control_flow (BLOCK_FOR_INSN (insn), true);
6111}
6112
6113/* This function is called on the ascending pass, before returning from the
6114 current basic block. */
6115static void
b8698a0f
L
6116fur_at_first_insn (insn_t insn,
6117 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
e855c69d
AB
6118 void *static_params ATTRIBUTE_UNUSED)
6119{
6120 gcc_assert (!sel_bb_head_p (insn) || AV_SET_VALID_P (insn)
6121 || AV_LEVEL (insn) == -1);
6122}
6123
6124/* Called on the backward stage of recursion to call moveup_expr for insn
6125 and sparams->c_expr. */
6126static void
6127move_op_ascend (insn_t insn, void *static_params)
6128{
6129 enum MOVEUP_EXPR_CODE res;
6130 moveop_static_params_p sparams = (moveop_static_params_p) static_params;
6131
6132 if (! INSN_NOP_P (insn))
6133 {
6134 res = moveup_expr_cached (sparams->c_expr, insn, false);
6135 gcc_assert (res != MOVEUP_EXPR_NULL);
6136 }
6137
6138 /* Update liveness for this insn as it was invalidated. */
6139 update_liveness_on_insn (insn);
6140}
6141
b8698a0f
L
6142/* This function is called on enter to the basic block.
6143 Returns TRUE if this block already have been visited and
e855c69d
AB
6144 code_motion_path_driver should return 1, FALSE otherwise. */
6145static int
b8698a0f 6146fur_on_enter (insn_t insn ATTRIBUTE_UNUSED, cmpd_local_params_p local_params,
e855c69d
AB
6147 void *static_params, bool visited_p)
6148{
6149 fur_static_params_p sparams = (fur_static_params_p) static_params;
6150
6151 if (visited_p)
6152 {
6153 /* If we have found something below this block, there should be at
6154 least one insn in ORIGINAL_INSNS. */
6155 gcc_assert (*sparams->original_insns);
6156
6157 /* Adjust CROSSES_CALL, since we may have come to this block along
6158 different path. */
6159 DEF_LIST_DEF (*sparams->original_insns)->crosses_call
6160 |= sparams->crosses_call;
6161 }
6162 else
6163 local_params->old_original_insns = *sparams->original_insns;
6164
6165 return 1;
6166}
6167
6168/* Same as above but for move_op. */
6169static int
b8698a0f
L
6170move_op_on_enter (insn_t insn ATTRIBUTE_UNUSED,
6171 cmpd_local_params_p local_params ATTRIBUTE_UNUSED,
e855c69d
AB
6172 void *static_params ATTRIBUTE_UNUSED, bool visited_p)
6173{
6174 if (visited_p)
6175 return -1;
6176 return 1;
6177}
6178
b8698a0f 6179/* This function is called while descending current basic block if current
e855c69d
AB
6180 insn is not the original EXPR we're searching for.
6181
b8698a0f 6182 Return value: FALSE, if code_motion_path_driver should perform a local
e855c69d
AB
6183 cleanup and return 0 itself;
6184 TRUE, if code_motion_path_driver should continue. */
6185static bool
6186move_op_orig_expr_not_found (insn_t insn, av_set_t orig_ops ATTRIBUTE_UNUSED,
6187 void *static_params)
6188{
6189 moveop_static_params_p sparams = (moveop_static_params_p) static_params;
6190
6191#ifdef ENABLE_CHECKING
6192 sparams->failed_insn = insn;
6193#endif
6194
6195 /* If we're scheduling separate expr, in order to generate correct code
b8698a0f 6196 we need to stop the search at bookkeeping code generated with the
e855c69d
AB
6197 same destination register or memory. */
6198 if (lhs_of_insn_equals_to_dest_p (insn, sparams->dest))
6199 return false;
6200 return true;
6201}
6202
b8698a0f 6203/* This function is called while descending current basic block if current
e855c69d
AB
6204 insn is not the original EXPR we're searching for.
6205
6206 Return value: TRUE (code_motion_path_driver should continue). */
6207static bool
6208fur_orig_expr_not_found (insn_t insn, av_set_t orig_ops, void *static_params)
6209{
6210 bool mutexed;
6211 expr_t r;
6212 av_set_iterator avi;
6213 fur_static_params_p sparams = (fur_static_params_p) static_params;
6214
6215 if (CALL_P (insn))
6216 sparams->crosses_call = true;
b5b8b0ac
AO
6217 else if (DEBUG_INSN_P (insn))
6218 return true;
e855c69d
AB
6219
6220 /* If current insn we are looking at cannot be executed together
6221 with original insn, then we can skip it safely.
6222
6223 Example: ORIG_OPS = { (p6) r14 = sign_extend (r15); }
6224 INSN = (!p6) r14 = r14 + 1;
6225
6226 Here we can schedule ORIG_OP with lhs = r14, though only
6227 looking at the set of used and set registers of INSN we must
6228 forbid it. So, add set/used in INSN registers to the
6229 untouchable set only if there is an insn in ORIG_OPS that can
6230 affect INSN. */
6231 mutexed = true;
6232 FOR_EACH_EXPR (r, avi, orig_ops)
6233 if (!sched_insns_conditions_mutex_p (insn, EXPR_INSN_RTX (r)))
6234 {
6235 mutexed = false;
6236 break;
6237 }
6238
6239 /* Mark all registers that do not meet the following condition:
6240 (1) Not set or read on any path from xi to an instance of the
6241 original operation. */
6242 if (!mutexed)
6243 {
6244 IOR_REG_SET (sparams->used_regs, INSN_REG_SETS (insn));
6245 IOR_REG_SET (sparams->used_regs, INSN_REG_USES (insn));
6246 IOR_REG_SET (sparams->used_regs, INSN_REG_CLOBBERS (insn));
6247 }
6248
6249 return true;
6250}
6251
6252/* Hooks and data to perform move_op operations with code_motion_path_driver. */
6253struct code_motion_path_driver_info_def move_op_hooks = {
6254 move_op_on_enter,
6255 move_op_orig_expr_found,
6256 move_op_orig_expr_not_found,
6257 move_op_merge_succs,
6258 move_op_after_merge_succs,
6259 move_op_ascend,
6260 move_op_at_first_insn,
6261 SUCCS_NORMAL,
6262 "move_op"
6263};
6264
b8698a0f 6265/* Hooks and data to perform find_used_regs operations
e855c69d
AB
6266 with code_motion_path_driver. */
6267struct code_motion_path_driver_info_def fur_hooks = {
6268 fur_on_enter,
6269 fur_orig_expr_found,
6270 fur_orig_expr_not_found,
6271 fur_merge_succs,
6272 NULL, /* fur_after_merge_succs */
6273 NULL, /* fur_ascend */
6274 fur_at_first_insn,
6275 SUCCS_ALL,
6276 "find_used_regs"
6277};
6278
6279/* Traverse all successors of INSN. For each successor that is SUCCS_NORMAL
b8698a0f
L
6280 code_motion_path_driver is called recursively. Original operation
6281 was found at least on one path that is starting with one of INSN's
e855c69d
AB
6282 successors (this fact is asserted). ORIG_OPS is expressions we're looking
6283 for, PATH is the path we've traversed, STATIC_PARAMS is the parameters
b8698a0f 6284 of either move_op or find_used_regs depending on the caller.
e855c69d
AB
6285
6286 Return 0 if we haven't found expression, 1 if we found it, -1 if we don't
6287 know for sure at this point. */
6288static int
b8698a0f 6289code_motion_process_successors (insn_t insn, av_set_t orig_ops,
e855c69d
AB
6290 ilist_t path, void *static_params)
6291{
6292 int res = 0;
6293 succ_iterator succ_i;
6294 rtx succ;
6295 basic_block bb;
6296 int old_index;
6297 unsigned old_succs;
6298
6299 struct cmpd_local_params lparams;
6300 expr_def _x;
6301
6302 lparams.c_expr_local = &_x;
6303 lparams.c_expr_merged = NULL;
6304
6305 /* We need to process only NORMAL succs for move_op, and collect live
b8698a0f
L
6306 registers from ALL branches (including those leading out of the
6307 region) for find_used_regs.
e855c69d
AB
6308
6309 In move_op, there can be a case when insn's bb number has changed
b8698a0f
L
6310 due to created bookkeeping. This happens very rare, as we need to
6311 move expression from the beginning to the end of the same block.
6312 Rescan successors in this case. */
e855c69d
AB
6313
6314 rescan:
6315 bb = BLOCK_FOR_INSN (insn);
b8698a0f 6316 old_index = bb->index;
e855c69d 6317 old_succs = EDGE_COUNT (bb->succs);
b8698a0f 6318
e855c69d
AB
6319 FOR_EACH_SUCC_1 (succ, succ_i, insn, code_motion_path_driver_info->succ_flags)
6320 {
6321 int b;
6322
6323 lparams.e1 = succ_i.e1;
6324 lparams.e2 = succ_i.e2;
6325
6326 /* Go deep into recursion only for NORMAL edges (non-backedges within the
6327 current region). */
6328 if (succ_i.current_flags == SUCCS_NORMAL)
b8698a0f 6329 b = code_motion_path_driver (succ, orig_ops, path, &lparams,
e855c69d
AB
6330 static_params);
6331 else
6332 b = 0;
6333
6334 /* Merge c_expres found or unify live register sets from different
6335 successors. */
6336 code_motion_path_driver_info->merge_succs (insn, succ, b, &lparams,
6337 static_params);
6338 if (b == 1)
6339 res = b;
6340 else if (b == -1 && res != 1)
6341 res = b;
6342
6343 /* We have simplified the control flow below this point. In this case,
6344 the iterator becomes invalid. We need to try again. */
6345 if (BLOCK_FOR_INSN (insn)->index != old_index
6346 || EDGE_COUNT (bb->succs) != old_succs)
6347 goto rescan;
6348 }
6349
6350#ifdef ENABLE_CHECKING
b8698a0f 6351 /* Here, RES==1 if original expr was found at least for one of the
e855c69d 6352 successors. After the loop, RES may happen to have zero value
b8698a0f
L
6353 only if at some point the expr searched is present in av_set, but is
6354 not found below. In most cases, this situation is an error.
e855c69d
AB
6355 The exception is when the original operation is blocked by
6356 bookkeeping generated for another fence or for another path in current
6357 move_op. */
b8698a0f
L
6358 gcc_assert (res == 1
6359 || (res == 0
e855c69d
AB
6360 && av_set_could_be_blocked_by_bookkeeping_p (orig_ops,
6361 static_params))
6362 || res == -1);
6363#endif
b8698a0f 6364
e855c69d 6365 /* Merge data, clean up, etc. */
72a54528 6366 if (res != -1 && code_motion_path_driver_info->after_merge_succs)
e855c69d
AB
6367 code_motion_path_driver_info->after_merge_succs (&lparams, static_params);
6368
6369 return res;
6370}
6371
6372
b8698a0f
L
6373/* Perform a cleanup when the driver is about to terminate. ORIG_OPS_P
6374 is the pointer to the av set with expressions we were looking for,
e855c69d
AB
6375 PATH_P is the pointer to the traversed path. */
6376static inline void
6377code_motion_path_driver_cleanup (av_set_t *orig_ops_p, ilist_t *path_p)
6378{
6379 ilist_remove (path_p);
6380 av_set_clear (orig_ops_p);
6381}
6382
b8698a0f
L
6383/* The driver function that implements move_op or find_used_regs
6384 functionality dependent whether code_motion_path_driver_INFO is set to
6385 &MOVE_OP_HOOKS or &FUR_HOOKS. This function implements the common parts
e855c69d
AB
6386 of code (CFG traversal etc) that are shared among both functions. INSN
6387 is the insn we're starting the search from, ORIG_OPS are the expressions
6388 we're searching for, PATH is traversed path, LOCAL_PARAMS_IN are local
6389 parameters of the driver, and STATIC_PARAMS are static parameters of
b8698a0f 6390 the caller.
e855c69d
AB
6391
6392 Returns whether original instructions were found. Note that top-level
6393 code_motion_path_driver always returns true. */
72a54528 6394static int
b8698a0f
L
6395code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path,
6396 cmpd_local_params_p local_params_in,
e855c69d
AB
6397 void *static_params)
6398{
6399 expr_t expr = NULL;
6400 basic_block bb = BLOCK_FOR_INSN (insn);
6401 insn_t first_insn, bb_tail, before_first;
6402 bool removed_last_insn = false;
6403
6404 if (sched_verbose >= 6)
6405 {
6406 sel_print ("%s (", code_motion_path_driver_info->routine_name);
6407 dump_insn (insn);
6408 sel_print (",");
6409 dump_av_set (orig_ops);
6410 sel_print (")\n");
6411 }
6412
6413 gcc_assert (orig_ops);
6414
6415 /* If no original operations exist below this insn, return immediately. */
6416 if (is_ineligible_successor (insn, path))
6417 {
6418 if (sched_verbose >= 6)
6419 sel_print ("Insn %d is ineligible successor\n", INSN_UID (insn));
6420 return false;
6421 }
b8698a0f 6422
e855c69d
AB
6423 /* The block can have invalid av set, in which case it was created earlier
6424 during move_op. Return immediately. */
6425 if (sel_bb_head_p (insn))
6426 {
6427 if (! AV_SET_VALID_P (insn))
6428 {
6429 if (sched_verbose >= 6)
6430 sel_print ("Returned from block %d as it had invalid av set\n",
6431 bb->index);
6432 return false;
6433 }
6434
6435 if (bitmap_bit_p (code_motion_visited_blocks, bb->index))
6436 {
6437 /* We have already found an original operation on this branch, do not
6438 go any further and just return TRUE here. If we don't stop here,
b8698a0f 6439 function can have exponential behaviour even on the small code
e855c69d
AB
6440 with many different paths (e.g. with data speculation and
6441 recovery blocks). */
6442 if (sched_verbose >= 6)
6443 sel_print ("Block %d already visited in this traversal\n", bb->index);
6444 if (code_motion_path_driver_info->on_enter)
b8698a0f 6445 return code_motion_path_driver_info->on_enter (insn,
e855c69d 6446 local_params_in,
b8698a0f 6447 static_params,
e855c69d
AB
6448 true);
6449 }
6450 }
b8698a0f 6451
e855c69d
AB
6452 if (code_motion_path_driver_info->on_enter)
6453 code_motion_path_driver_info->on_enter (insn, local_params_in,
6454 static_params, false);
6455 orig_ops = av_set_copy (orig_ops);
6456
6457 /* Filter the orig_ops set. */
6458 if (AV_SET_VALID_P (insn))
6459 av_set_intersect (&orig_ops, AV_SET (insn));
6460
6461 /* If no more original ops, return immediately. */
6462 if (!orig_ops)
6463 {
6464 if (sched_verbose >= 6)
6465 sel_print ("No intersection with av set of block %d\n", bb->index);
6466 return false;
6467 }
6468
6469 /* For non-speculative insns we have to leave only one form of the
b8698a0f 6470 original operation, because if we don't, we may end up with
e855c69d
AB
6471 different C_EXPRes and, consequently, with bookkeepings for different
6472 expression forms along the same code motion path. That may lead to
b8698a0f
L
6473 generation of incorrect code. So for each code motion we stick to
6474 the single form of the instruction, except for speculative insns
6475 which we need to keep in different forms with all speculation
e855c69d
AB
6476 types. */
6477 av_set_leave_one_nonspec (&orig_ops);
6478
6479 /* It is not possible that all ORIG_OPS are filtered out. */
6480 gcc_assert (orig_ops);
6481
6482 /* It is enough to place only heads and tails of visited basic blocks into
6483 the PATH. */
6484 ilist_add (&path, insn);
6485 first_insn = insn;
6486 bb_tail = sel_bb_end (bb);
6487
6488 /* Descend the basic block in search of the original expr; this part
b8698a0f 6489 corresponds to the part of the original move_op procedure executed
e855c69d
AB
6490 before the recursive call. */
6491 for (;;)
6492 {
6493 /* Look at the insn and decide if it could be an ancestor of currently
6494 scheduling operation. If it is so, then the insn "dest = op" could
6495 either be replaced with "dest = reg", because REG now holds the result
6496 of OP, or just removed, if we've scheduled the insn as a whole.
6497
6498 If this insn doesn't contain currently scheduling OP, then proceed
6499 with searching and look at its successors. Operations we're searching
b8698a0f 6500 for could have changed when moving up through this insn via
e855c69d
AB
6501 substituting. In this case, perform unsubstitution on them first.
6502
6503 When traversing the DAG below this insn is finished, insert
6504 bookkeeping code, if the insn is a joint point, and remove
6505 leftovers. */
6506
6507 expr = av_set_lookup (orig_ops, INSN_VINSN (insn));
6508 if (expr)
6509 {
6510 insn_t last_insn = PREV_INSN (insn);
6511
6512 /* We have found the original operation. */
6513 if (sched_verbose >= 6)
6514 sel_print ("Found original operation at insn %d\n", INSN_UID (insn));
6515
b8698a0f 6516 code_motion_path_driver_info->orig_expr_found
e855c69d
AB
6517 (insn, expr, local_params_in, static_params);
6518
6519 /* Step back, so on the way back we'll start traversing from the
b8698a0f 6520 previous insn (or we'll see that it's bb_note and skip that
e855c69d
AB
6521 loop). */
6522 if (insn == first_insn)
6523 {
6524 first_insn = NEXT_INSN (last_insn);
6525 removed_last_insn = sel_bb_end_p (last_insn);
6526 }
6527 insn = last_insn;
6528 break;
6529 }
6530 else
6531 {
6532 /* We haven't found the original expr, continue descending the basic
6533 block. */
b8698a0f 6534 if (code_motion_path_driver_info->orig_expr_not_found
e855c69d
AB
6535 (insn, orig_ops, static_params))
6536 {
b8698a0f 6537 /* Av set ops could have been changed when moving through this
e855c69d
AB
6538 insn. To find them below it, we have to un-substitute them. */
6539 undo_transformations (&orig_ops, insn);
6540 }
6541 else
6542 {
6543 /* Clean up and return, if the hook tells us to do so. It may
b8698a0f 6544 happen if we've encountered the previously created
e855c69d
AB
6545 bookkeeping. */
6546 code_motion_path_driver_cleanup (&orig_ops, &path);
6547 return -1;
6548 }
6549
6550 gcc_assert (orig_ops);
6551 }
6552
6553 /* Stop at insn if we got to the end of BB. */
6554 if (insn == bb_tail)
6555 break;
6556
6557 insn = NEXT_INSN (insn);
6558 }
6559
b8698a0f 6560 /* Here INSN either points to the insn before the original insn (may be
e855c69d
AB
6561 bb_note, if original insn was a bb_head) or to the bb_end. */
6562 if (!expr)
6563 {
6564 int res;
6565
6566 gcc_assert (insn == sel_bb_end (bb));
6567
6568 /* Add bb tail to PATH (but it doesn't make any sense if it's a bb_head -
6569 it's already in PATH then). */
6570 if (insn != first_insn)
6571 ilist_add (&path, insn);
6572
b8698a0f
L
6573 /* Process_successors should be able to find at least one
6574 successor for which code_motion_path_driver returns TRUE. */
6575 res = code_motion_process_successors (insn, orig_ops,
e855c69d
AB
6576 path, static_params);
6577
6578 /* Remove bb tail from path. */
6579 if (insn != first_insn)
6580 ilist_remove (&path);
6581
6582 if (res != 1)
6583 {
6584 /* This is the case when one of the original expr is no longer available
b8698a0f 6585 due to bookkeeping created on this branch with the same register.
e855c69d 6586 In the original algorithm, which doesn't have update_data_sets call
b8698a0f
L
6587 on a bookkeeping block, it would simply result in returning
6588 FALSE when we've encountered a previously generated bookkeeping
e855c69d
AB
6589 insn in moveop_orig_expr_not_found. */
6590 code_motion_path_driver_cleanup (&orig_ops, &path);
6591 return res;
6592 }
6593 }
6594
6595 /* Don't need it any more. */
6596 av_set_clear (&orig_ops);
6597
b8698a0f 6598 /* Backward pass: now, when we have C_EXPR computed, we'll drag it to
e855c69d
AB
6599 the beginning of the basic block. */
6600 before_first = PREV_INSN (first_insn);
6601 while (insn != before_first)
b8698a0f 6602 {
e855c69d
AB
6603 if (code_motion_path_driver_info->ascend)
6604 code_motion_path_driver_info->ascend (insn, static_params);
6605
6606 insn = PREV_INSN (insn);
6607 }
b8698a0f 6608
e855c69d
AB
6609 /* Now we're at the bb head. */
6610 insn = first_insn;
6611 ilist_remove (&path);
6612 local_params_in->removed_last_insn = removed_last_insn;
6613 code_motion_path_driver_info->at_first_insn (insn, local_params_in, static_params);
b8698a0f 6614
e855c69d
AB
6615 /* This should be the very last operation as at bb head we could change
6616 the numbering by creating bookkeeping blocks. */
6617 if (removed_last_insn)
6618 insn = PREV_INSN (insn);
6619 bitmap_set_bit (code_motion_visited_blocks, BLOCK_FOR_INSN (insn)->index);
6620 return true;
6621}
6622
b8698a0f 6623/* Move up the operations from ORIG_OPS set traversing the dag starting
e855c69d
AB
6624 from INSN. PATH represents the edges traversed so far.
6625 DEST is the register chosen for scheduling the current expr. Insert
6626 bookkeeping code in the join points. EXPR_VLIW is the chosen expression,
b8698a0f 6627 C_EXPR is how it looks like at the given cfg point.
72a54528
AM
6628 Set *SHOULD_MOVE to indicate whether we have only disconnected
6629 one of the insns found.
e855c69d 6630
b8698a0f 6631 Returns whether original instructions were found, which is asserted
e855c69d
AB
6632 to be true in the caller. */
6633static bool
6634move_op (insn_t insn, av_set_t orig_ops, expr_t expr_vliw,
72a54528 6635 rtx dest, expr_t c_expr, bool *should_move)
e855c69d
AB
6636{
6637 struct moveop_static_params sparams;
6638 struct cmpd_local_params lparams;
6639 bool res;
6640
b8698a0f 6641 /* Init params for code_motion_path_driver. */
e855c69d
AB
6642 sparams.dest = dest;
6643 sparams.c_expr = c_expr;
6644 sparams.uid = INSN_UID (EXPR_INSN_RTX (expr_vliw));
6645#ifdef ENABLE_CHECKING
6646 sparams.failed_insn = NULL;
6647#endif
6648 sparams.was_renamed = false;
6649 lparams.e1 = NULL;
6650
6651 /* We haven't visited any blocks yet. */
6652 bitmap_clear (code_motion_visited_blocks);
b8698a0f 6653
e855c69d
AB
6654 /* Set appropriate hooks and data. */
6655 code_motion_path_driver_info = &move_op_hooks;
6656 res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);
6657
6658 if (sparams.was_renamed)
6659 EXPR_WAS_RENAMED (expr_vliw) = true;
6660
72a54528
AM
6661 *should_move = (sparams.uid == -1);
6662
e855c69d
AB
6663 return res;
6664}
6665\f
6666
6667/* Functions that work with regions. */
6668
6669/* Current number of seqno used in init_seqno and init_seqno_1. */
6670static int cur_seqno;
6671
b8698a0f
L
6672/* A helper for init_seqno. Traverse the region starting from BB and
6673 compute seqnos for visited insns, marking visited bbs in VISITED_BBS.
e855c69d
AB
6674 Clear visited blocks from BLOCKS_TO_RESCHEDULE. */
6675static void
6676init_seqno_1 (basic_block bb, sbitmap visited_bbs, bitmap blocks_to_reschedule)
6677{
6678 int bbi = BLOCK_TO_BB (bb->index);
6679 insn_t insn, note = bb_note (bb);
6680 insn_t succ_insn;
6681 succ_iterator si;
6682
6683 SET_BIT (visited_bbs, bbi);
6684 if (blocks_to_reschedule)
6685 bitmap_clear_bit (blocks_to_reschedule, bb->index);
6686
b8698a0f 6687 FOR_EACH_SUCC_1 (succ_insn, si, BB_END (bb),
e855c69d
AB
6688 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
6689 {
6690 basic_block succ = BLOCK_FOR_INSN (succ_insn);
6691 int succ_bbi = BLOCK_TO_BB (succ->index);
6692
6693 gcc_assert (in_current_region_p (succ));
6694
6695 if (!TEST_BIT (visited_bbs, succ_bbi))
6696 {
6697 gcc_assert (succ_bbi > bbi);
6698
6699 init_seqno_1 (succ, visited_bbs, blocks_to_reschedule);
6700 }
6701 }
6702
6703 for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn))
6704 INSN_SEQNO (insn) = cur_seqno--;
6705}
6706
6707/* Initialize seqnos for the current region. NUMBER_OF_INSNS is the number
b8698a0f 6708 of instructions in the region, BLOCKS_TO_RESCHEDULE contains blocks on
e855c69d
AB
6709 which we're rescheduling when pipelining, FROM is the block where
6710 traversing region begins (it may not be the head of the region when
b8698a0f 6711 pipelining, but the head of the loop instead).
e855c69d
AB
6712
6713 Returns the maximal seqno found. */
6714static int
6715init_seqno (int number_of_insns, bitmap blocks_to_reschedule, basic_block from)
6716{
6717 sbitmap visited_bbs;
6718 bitmap_iterator bi;
6719 unsigned bbi;
6720
6721 visited_bbs = sbitmap_alloc (current_nr_blocks);
6722
6723 if (blocks_to_reschedule)
6724 {
6725 sbitmap_ones (visited_bbs);
6726 EXECUTE_IF_SET_IN_BITMAP (blocks_to_reschedule, 0, bbi, bi)
6727 {
6728 gcc_assert (BLOCK_TO_BB (bbi) < current_nr_blocks);
6729 RESET_BIT (visited_bbs, BLOCK_TO_BB (bbi));
6730 }
6731 }
6732 else
6733 {
6734 sbitmap_zero (visited_bbs);
6735 from = EBB_FIRST_BB (0);
6736 }
6737
6738 cur_seqno = number_of_insns > 0 ? number_of_insns : sched_max_luid - 1;
6739 init_seqno_1 (from, visited_bbs, blocks_to_reschedule);
6740 gcc_assert (cur_seqno == 0 || number_of_insns == 0);
6741
6742 sbitmap_free (visited_bbs);
6743 return sched_max_luid - 1;
6744}
6745
6746/* Initialize scheduling parameters for current region. */
6747static void
6748sel_setup_region_sched_flags (void)
6749{
6750 enable_schedule_as_rhs_p = 1;
6751 bookkeeping_p = 1;
b8698a0f 6752 pipelining_p = (bookkeeping_p
e855c69d
AB
6753 && (flag_sel_sched_pipelining != 0)
6754 && current_loop_nest != NULL);
6755 max_insns_to_rename = PARAM_VALUE (PARAM_SELSCHED_INSNS_TO_RENAME);
6756 max_ws = MAX_WS;
6757}
6758
6759/* Return true if all basic blocks of current region are empty. */
6760static bool
6761current_region_empty_p (void)
6762{
6763 int i;
6764 for (i = 0; i < current_nr_blocks; i++)
6765 if (! sel_bb_empty_p (BASIC_BLOCK (BB_TO_BLOCK (i))))
6766 return false;
6767
6768 return true;
6769}
6770
6771/* Prepare and verify loop nest for pipelining. */
6772static void
6773setup_current_loop_nest (int rgn)
6774{
6775 current_loop_nest = get_loop_nest_for_rgn (rgn);
6776
6777 if (!current_loop_nest)
6778 return;
6779
6780 /* If this loop has any saved loop preheaders from nested loops,
6781 add these basic blocks to the current region. */
6782 sel_add_loop_preheaders ();
6783
6784 /* Check that we're starting with a valid information. */
6785 gcc_assert (loop_latch_edge (current_loop_nest));
6786 gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest));
6787}
6788
e855c69d
AB
6789/* Compute instruction priorities for current region. */
6790static void
6791sel_compute_priorities (int rgn)
6792{
6793 sched_rgn_compute_dependencies (rgn);
6794
6795 /* Compute insn priorities in haifa style. Then free haifa style
6796 dependencies that we've calculated for this. */
6797 compute_priorities ();
6798
6799 if (sched_verbose >= 5)
6800 debug_rgn_dependencies (0);
6801
6802 free_rgn_deps ();
6803}
6804
6805/* Init scheduling data for RGN. Returns true when this region should not
6806 be scheduled. */
6807static bool
6808sel_region_init (int rgn)
6809{
6810 int i;
6811 bb_vec_t bbs;
6812
6813 rgn_setup_region (rgn);
6814
b8698a0f 6815 /* Even if sched_is_disabled_for_current_region_p() is true, we still
e855c69d
AB
6816 do region initialization here so the region can be bundled correctly,
6817 but we'll skip the scheduling in sel_sched_region (). */
6818 if (current_region_empty_p ())
6819 return true;
6820
6821 if (flag_sel_sched_pipelining)
6822 setup_current_loop_nest (rgn);
6823
6824 sel_setup_region_sched_flags ();
6825
6826 bbs = VEC_alloc (basic_block, heap, current_nr_blocks);
6827
6828 for (i = 0; i < current_nr_blocks; i++)
6829 VEC_quick_push (basic_block, bbs, BASIC_BLOCK (BB_TO_BLOCK (i)));
6830
6831 sel_init_bbs (bbs, NULL);
6832
6833 /* Initialize luids and dependence analysis which both sel-sched and haifa
6834 need. */
6835 sched_init_luids (bbs, NULL, NULL, NULL);
6836 sched_deps_init (false);
6837
6838 /* Initialize haifa data. */
6839 rgn_setup_sched_infos ();
6840 sel_set_sched_flags ();
6841 haifa_init_h_i_d (bbs, NULL, NULL, NULL);
6842
6843 sel_compute_priorities (rgn);
6844 init_deps_global ();
6845
6846 /* Main initialization. */
6847 sel_setup_sched_infos ();
6848 sel_init_global_and_expr (bbs);
6849
6850 VEC_free (basic_block, heap, bbs);
6851
6852 blocks_to_reschedule = BITMAP_ALLOC (NULL);
6853
6854 /* Init correct liveness sets on each instruction of a single-block loop.
6855 This is the only situation when we can't update liveness when calling
6856 compute_live for the first insn of the loop. */
6857 if (current_loop_nest)
6858 {
6859 int header = (sel_is_loop_preheader_p (BASIC_BLOCK (BB_TO_BLOCK (0)))
6860 ? 1
6861 : 0);
6862
6863 if (current_nr_blocks == header + 1)
b8698a0f 6864 update_liveness_on_insn
e855c69d
AB
6865 (sel_bb_head (BASIC_BLOCK (BB_TO_BLOCK (header))));
6866 }
b8698a0f 6867
e855c69d
AB
6868 /* Set hooks so that no newly generated insn will go out unnoticed. */
6869 sel_register_cfg_hooks ();
6870
6871 /* !!! We call target.sched.md_init () for the whole region, but we invoke
6872 targetm.sched.md_finish () for every ebb. */
6873 if (targetm.sched.md_init)
6874 /* None of the arguments are actually used in any target. */
6875 targetm.sched.md_init (sched_dump, sched_verbose, -1);
6876
6877 first_emitted_uid = get_max_uid () + 1;
6878 preheader_removed = false;
6879
6880 /* Reset register allocation ticks array. */
6881 memset (reg_rename_tick, 0, sizeof reg_rename_tick);
6882 reg_rename_this_tick = 0;
6883
6884 bitmap_initialize (forced_ebb_heads, 0);
6885 bitmap_clear (forced_ebb_heads);
6886
6887 setup_nop_vinsn ();
6888 current_copies = BITMAP_ALLOC (NULL);
6889 current_originators = BITMAP_ALLOC (NULL);
6890 code_motion_visited_blocks = BITMAP_ALLOC (NULL);
6891
6892 return false;
6893}
6894
6895/* Simplify insns after the scheduling. */
6896static void
6897simplify_changed_insns (void)
6898{
6899 int i;
6900
6901 for (i = 0; i < current_nr_blocks; i++)
6902 {
6903 basic_block bb = BASIC_BLOCK (BB_TO_BLOCK (i));
6904 rtx insn;
6905
6906 FOR_BB_INSNS (bb, insn)
6907 if (INSN_P (insn))
6908 {
6909 expr_t expr = INSN_EXPR (insn);
6910
b8698a0f 6911 if (EXPR_WAS_SUBSTITUTED (expr))
e855c69d
AB
6912 validate_simplify_insn (insn);
6913 }
6914 }
6915}
6916
6917/* Find boundaries of the EBB starting from basic block BB, marking blocks of
6918 this EBB in SCHEDULED_BLOCKS and appropriately filling in HEAD, TAIL,
6919 PREV_HEAD, and NEXT_TAIL fields of CURRENT_SCHED_INFO structure. */
6920static void
6921find_ebb_boundaries (basic_block bb, bitmap scheduled_blocks)
6922{
6923 insn_t head, tail;
6924 basic_block bb1 = bb;
6925 if (sched_verbose >= 2)
6926 sel_print ("Finishing schedule in bbs: ");
6927
6928 do
6929 {
6930 bitmap_set_bit (scheduled_blocks, BLOCK_TO_BB (bb1->index));
6931
6932 if (sched_verbose >= 2)
6933 sel_print ("%d; ", bb1->index);
6934 }
6935 while (!bb_ends_ebb_p (bb1) && (bb1 = bb_next_bb (bb1)));
6936
6937 if (sched_verbose >= 2)
6938 sel_print ("\n");
6939
6940 get_ebb_head_tail (bb, bb1, &head, &tail);
6941
6942 current_sched_info->head = head;
6943 current_sched_info->tail = tail;
6944 current_sched_info->prev_head = PREV_INSN (head);
6945 current_sched_info->next_tail = NEXT_INSN (tail);
6946}
6947
6948/* Regenerate INSN_SCHED_CYCLEs for insns of current EBB. */
6949static void
6950reset_sched_cycles_in_current_ebb (void)
6951{
6952 int last_clock = 0;
6953 int haifa_last_clock = -1;
6954 int haifa_clock = 0;
6955 insn_t insn;
6956
6957 if (targetm.sched.md_init)
6958 {
6959 /* None of the arguments are actually used in any target.
6960 NB: We should have md_reset () hook for cases like this. */
6961 targetm.sched.md_init (sched_dump, sched_verbose, -1);
6962 }
6963
6964 state_reset (curr_state);
6965 advance_state (curr_state);
b8698a0f 6966
e855c69d
AB
6967 for (insn = current_sched_info->head;
6968 insn != current_sched_info->next_tail;
6969 insn = NEXT_INSN (insn))
6970 {
6971 int cost, haifa_cost;
6972 int sort_p;
6973 bool asm_p, real_insn, after_stall;
6974 int clock;
6975
6976 if (!INSN_P (insn))
6977 continue;
6978
6979 asm_p = false;
6980 real_insn = recog_memoized (insn) >= 0;
6981 clock = INSN_SCHED_CYCLE (insn);
6982
6983 cost = clock - last_clock;
6984
6985 /* Initialize HAIFA_COST. */
6986 if (! real_insn)
6987 {
6988 asm_p = INSN_ASM_P (insn);
6989
6990 if (asm_p)
6991 /* This is asm insn which *had* to be scheduled first
6992 on the cycle. */
6993 haifa_cost = 1;
6994 else
b8698a0f 6995 /* This is a use/clobber insn. It should not change
e855c69d
AB
6996 cost. */
6997 haifa_cost = 0;
6998 }
6999 else
7000 haifa_cost = estimate_insn_cost (insn, curr_state);
7001
7002 /* Stall for whatever cycles we've stalled before. */
7003 after_stall = 0;
7004 if (INSN_AFTER_STALL_P (insn) && cost > haifa_cost)
7005 {
7006 haifa_cost = cost;
7007 after_stall = 1;
7008 }
7009
7010 if (haifa_cost > 0)
7011 {
7012 int i = 0;
7013
7014 while (haifa_cost--)
7015 {
7016 advance_state (curr_state);
7017 i++;
7018
7019 if (sched_verbose >= 2)
7020 {
7021 sel_print ("advance_state (state_transition)\n");
7022 debug_state (curr_state);
7023 }
7024
b8698a0f
L
7025 /* The DFA may report that e.g. insn requires 2 cycles to be
7026 issued, but on the next cycle it says that insn is ready
e855c69d
AB
7027 to go. Check this here. */
7028 if (!after_stall
b8698a0f 7029 && real_insn
e855c69d
AB
7030 && haifa_cost > 0
7031 && estimate_insn_cost (insn, curr_state) == 0)
7032 break;
7033 }
7034
7035 haifa_clock += i;
7036 }
7037 else
7038 gcc_assert (haifa_cost == 0);
7039
7040 if (sched_verbose >= 2)
7041 sel_print ("Haifa cost for insn %d: %d\n", INSN_UID (insn), haifa_cost);
7042
7043 if (targetm.sched.dfa_new_cycle)
7044 while (targetm.sched.dfa_new_cycle (sched_dump, sched_verbose, insn,
7045 haifa_last_clock, haifa_clock,
7046 &sort_p))
7047 {
7048 advance_state (curr_state);
7049 haifa_clock++;
7050 if (sched_verbose >= 2)
7051 {
7052 sel_print ("advance_state (dfa_new_cycle)\n");
7053 debug_state (curr_state);
7054 }
7055 }
7056
7057 if (real_insn)
7058 {
7059 cost = state_transition (curr_state, insn);
7060
7061 if (sched_verbose >= 2)
7062 debug_state (curr_state);
7063
7064 gcc_assert (cost < 0);
7065 }
7066
7067 if (targetm.sched.variable_issue)
7068 targetm.sched.variable_issue (sched_dump, sched_verbose, insn, 0);
7069
7070 INSN_SCHED_CYCLE (insn) = haifa_clock;
7071
7072 last_clock = clock;
7073 haifa_last_clock = haifa_clock;
7074 }
7075}
7076
7077/* Put TImode markers on insns starting a new issue group. */
7078static void
7079put_TImodes (void)
7080{
7081 int last_clock = -1;
7082 insn_t insn;
7083
7084 for (insn = current_sched_info->head; insn != current_sched_info->next_tail;
7085 insn = NEXT_INSN (insn))
7086 {
7087 int cost, clock;
7088
7089 if (!INSN_P (insn))
7090 continue;
7091
7092 clock = INSN_SCHED_CYCLE (insn);
7093 cost = (last_clock == -1) ? 1 : clock - last_clock;
7094
7095 gcc_assert (cost >= 0);
7096
7097 if (issue_rate > 1
7098 && GET_CODE (PATTERN (insn)) != USE
7099 && GET_CODE (PATTERN (insn)) != CLOBBER)
7100 {
7101 if (reload_completed && cost > 0)
7102 PUT_MODE (insn, TImode);
7103
7104 last_clock = clock;
7105 }
7106
7107 if (sched_verbose >= 2)
7108 sel_print ("Cost for insn %d is %d\n", INSN_UID (insn), cost);
7109 }
7110}
7111
b8698a0f 7112/* Perform MD_FINISH on EBBs comprising current region. When
e855c69d
AB
7113 RESET_SCHED_CYCLES_P is true, run a pass emulating the scheduler
7114 to produce correct sched cycles on insns. */
7115static void
7116sel_region_target_finish (bool reset_sched_cycles_p)
7117{
7118 int i;
7119 bitmap scheduled_blocks = BITMAP_ALLOC (NULL);
7120
7121 for (i = 0; i < current_nr_blocks; i++)
7122 {
7123 if (bitmap_bit_p (scheduled_blocks, i))
7124 continue;
7125
7126 /* While pipelining outer loops, skip bundling for loop
7127 preheaders. Those will be rescheduled in the outer loop. */
7128 if (sel_is_loop_preheader_p (EBB_FIRST_BB (i)))
7129 continue;
7130
7131 find_ebb_boundaries (EBB_FIRST_BB (i), scheduled_blocks);
7132
7133 if (no_real_insns_p (current_sched_info->head, current_sched_info->tail))
7134 continue;
7135
7136 if (reset_sched_cycles_p)
7137 reset_sched_cycles_in_current_ebb ();
7138
7139 if (targetm.sched.md_init)
7140 targetm.sched.md_init (sched_dump, sched_verbose, -1);
7141
7142 put_TImodes ();
7143
7144 if (targetm.sched.md_finish)
7145 {
7146 targetm.sched.md_finish (sched_dump, sched_verbose);
7147
7148 /* Extend luids so that insns generated by the target will
7149 get zero luid. */
7150 sched_init_luids (NULL, NULL, NULL, NULL);
7151 }
7152 }
7153
7154 BITMAP_FREE (scheduled_blocks);
7155}
7156
7157/* Free the scheduling data for the current region. When RESET_SCHED_CYCLES_P
b8698a0f 7158 is true, make an additional pass emulating scheduler to get correct insn
e855c69d
AB
7159 cycles for md_finish calls. */
7160static void
7161sel_region_finish (bool reset_sched_cycles_p)
7162{
7163 simplify_changed_insns ();
7164 sched_finish_ready_list ();
7165 free_nop_pool ();
7166
7167 /* Free the vectors. */
7168 if (vec_av_set)
7169 VEC_free (expr_t, heap, vec_av_set);
7170 BITMAP_FREE (current_copies);
7171 BITMAP_FREE (current_originators);
7172 BITMAP_FREE (code_motion_visited_blocks);
7173 vinsn_vec_free (&vec_bookkeeping_blocked_vinsns);
7174 vinsn_vec_free (&vec_target_unavailable_vinsns);
7175
7176 /* If LV_SET of the region head should be updated, do it now because
7177 there will be no other chance. */
7178 {
7179 succ_iterator si;
7180 insn_t insn;
7181
7182 FOR_EACH_SUCC_1 (insn, si, bb_note (EBB_FIRST_BB (0)),
7183 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
7184 {
7185 basic_block bb = BLOCK_FOR_INSN (insn);
7186
7187 if (!BB_LV_SET_VALID_P (bb))
7188 compute_live (insn);
7189 }
7190 }
7191
7192 /* Emulate the Haifa scheduler for bundling. */
7193 if (reload_completed)
7194 sel_region_target_finish (reset_sched_cycles_p);
7195
7196 sel_finish_global_and_expr ();
7197
7198 bitmap_clear (forced_ebb_heads);
7199
7200 free_nop_vinsn ();
7201
7202 finish_deps_global ();
7203 sched_finish_luids ();
7204
7205 sel_finish_bbs ();
7206 BITMAP_FREE (blocks_to_reschedule);
7207
7208 sel_unregister_cfg_hooks ();
7209
7210 max_issue_size = 0;
7211}
7212\f
7213
7214/* Functions that implement the scheduler driver. */
7215
7216/* Schedule a parallel instruction group on each of FENCES. MAX_SEQNO
7217 is the current maximum seqno. SCHEDULED_INSNS_TAILPP is the list
7218 of insns scheduled -- these would be postprocessed later. */
7219static void
7220schedule_on_fences (flist_t fences, int max_seqno,
7221 ilist_t **scheduled_insns_tailpp)
7222{
7223 flist_t old_fences = fences;
7224
7225 if (sched_verbose >= 1)
7226 {
7227 sel_print ("\nScheduling on fences: ");
7228 dump_flist (fences);
7229 sel_print ("\n");
7230 }
7231
7232 scheduled_something_on_previous_fence = false;
7233 for (; fences; fences = FLIST_NEXT (fences))
7234 {
7235 fence_t fence = NULL;
7236 int seqno = 0;
7237 flist_t fences2;
7238 bool first_p = true;
b8698a0f 7239
e855c69d
AB
7240 /* Choose the next fence group to schedule.
7241 The fact that insn can be scheduled only once
7242 on the cycle is guaranteed by two properties:
7243 1. seqnos of parallel groups decrease with each iteration.
7244 2. If is_ineligible_successor () sees the larger seqno, it
7245 checks if candidate insn is_in_current_fence_p (). */
7246 for (fences2 = old_fences; fences2; fences2 = FLIST_NEXT (fences2))
7247 {
7248 fence_t f = FLIST_FENCE (fences2);
7249
7250 if (!FENCE_PROCESSED_P (f))
7251 {
7252 int i = INSN_SEQNO (FENCE_INSN (f));
7253
7254 if (first_p || i > seqno)
7255 {
7256 seqno = i;
7257 fence = f;
7258 first_p = false;
7259 }
7260 else
7261 /* ??? Seqnos of different groups should be different. */
7262 gcc_assert (1 || i != seqno);
7263 }
7264 }
7265
7266 gcc_assert (fence);
7267
7268 /* As FENCE is nonnull, SEQNO is initialized. */
7269 seqno -= max_seqno + 1;
7270 fill_insns (fence, seqno, scheduled_insns_tailpp);
7271 FENCE_PROCESSED_P (fence) = true;
7272 }
7273
7274 /* All av_sets are invalidated by GLOBAL_LEVEL increase, thus we
b8698a0f 7275 don't need to keep bookkeeping-invalidated and target-unavailable
e855c69d
AB
7276 vinsns any more. */
7277 vinsn_vec_clear (&vec_bookkeeping_blocked_vinsns);
7278 vinsn_vec_clear (&vec_target_unavailable_vinsns);
7279}
7280
7281/* Calculate MIN_SEQNO and MAX_SEQNO. */
7282static void
7283find_min_max_seqno (flist_t fences, int *min_seqno, int *max_seqno)
7284{
7285 *min_seqno = *max_seqno = INSN_SEQNO (FENCE_INSN (FLIST_FENCE (fences)));
7286
7287 /* The first element is already processed. */
7288 while ((fences = FLIST_NEXT (fences)))
7289 {
7290 int seqno = INSN_SEQNO (FENCE_INSN (FLIST_FENCE (fences)));
b8698a0f 7291
e855c69d
AB
7292 if (*min_seqno > seqno)
7293 *min_seqno = seqno;
7294 else if (*max_seqno < seqno)
7295 *max_seqno = seqno;
7296 }
7297}
7298
7299/* Calculate new fences from FENCES. */
b8698a0f 7300static flist_t
e855c69d
AB
7301calculate_new_fences (flist_t fences, int orig_max_seqno)
7302{
7303 flist_t old_fences = fences;
7304 struct flist_tail_def _new_fences, *new_fences = &_new_fences;
7305
7306 flist_tail_init (new_fences);
7307 for (; fences; fences = FLIST_NEXT (fences))
7308 {
7309 fence_t fence = FLIST_FENCE (fences);
7310 insn_t insn;
b8698a0f 7311
e855c69d
AB
7312 if (!FENCE_BNDS (fence))
7313 {
7314 /* This fence doesn't have any successors. */
7315 if (!FENCE_SCHEDULED_P (fence))
7316 {
7317 /* Nothing was scheduled on this fence. */
7318 int seqno;
7319
7320 insn = FENCE_INSN (fence);
7321 seqno = INSN_SEQNO (insn);
7322 gcc_assert (seqno > 0 && seqno <= orig_max_seqno);
7323
7324 if (sched_verbose >= 1)
b8698a0f 7325 sel_print ("Fence %d[%d] has not changed\n",
e855c69d
AB
7326 INSN_UID (insn),
7327 BLOCK_NUM (insn));
7328 move_fence_to_fences (fences, new_fences);
7329 }
7330 }
7331 else
7332 extract_new_fences_from (fences, new_fences, orig_max_seqno);
7333 }
7334
7335 flist_clear (&old_fences);
7336 return FLIST_TAIL_HEAD (new_fences);
7337}
7338
7339/* Update seqnos of insns given by PSCHEDULED_INSNS. MIN_SEQNO and MAX_SEQNO
7340 are the miminum and maximum seqnos of the group, HIGHEST_SEQNO_IN_USE is
7341 the highest seqno used in a region. Return the updated highest seqno. */
7342static int
b8698a0f
L
7343update_seqnos_and_stage (int min_seqno, int max_seqno,
7344 int highest_seqno_in_use,
e855c69d
AB
7345 ilist_t *pscheduled_insns)
7346{
7347 int new_hs;
7348 ilist_iterator ii;
7349 insn_t insn;
b8698a0f 7350
e855c69d
AB
7351 /* Actually, new_hs is the seqno of the instruction, that was
7352 scheduled first (i.e. it is the first one in SCHEDULED_INSNS). */
7353 if (*pscheduled_insns)
7354 {
7355 new_hs = (INSN_SEQNO (ILIST_INSN (*pscheduled_insns))
7356 + highest_seqno_in_use + max_seqno - min_seqno + 2);
7357 gcc_assert (new_hs > highest_seqno_in_use);
7358 }
7359 else
7360 new_hs = highest_seqno_in_use;
7361
7362 FOR_EACH_INSN (insn, ii, *pscheduled_insns)
7363 {
7364 gcc_assert (INSN_SEQNO (insn) < 0);
7365 INSN_SEQNO (insn) += highest_seqno_in_use + max_seqno - min_seqno + 2;
7366 gcc_assert (INSN_SEQNO (insn) <= new_hs);
bcf33775
AB
7367
7368 /* When not pipelining, purge unneeded insn info on the scheduled insns.
7369 For example, having reg_last array of INSN_DEPS_CONTEXT in memory may
7370 require > 1GB of memory e.g. on limit-fnargs.c. */
7371 if (! pipelining_p)
7372 free_data_for_scheduled_insn (insn);
e855c69d
AB
7373 }
7374
7375 ilist_clear (pscheduled_insns);
7376 global_level++;
7377
7378 return new_hs;
7379}
7380
b8698a0f
L
7381/* The main driver for scheduling a region. This function is responsible
7382 for correct propagation of fences (i.e. scheduling points) and creating
7383 a group of parallel insns at each of them. It also supports
e855c69d
AB
7384 pipelining. ORIG_MAX_SEQNO is the maximal seqno before this pass
7385 of scheduling. */
7386static void
7387sel_sched_region_2 (int orig_max_seqno)
7388{
7389 int highest_seqno_in_use = orig_max_seqno;
7390
7391 stat_bookkeeping_copies = 0;
7392 stat_insns_needed_bookkeeping = 0;
7393 stat_renamed_scheduled = 0;
7394 stat_substitutions_total = 0;
7395 num_insns_scheduled = 0;
7396
7397 while (fences)
7398 {
7399 int min_seqno, max_seqno;
7400 ilist_t scheduled_insns = NULL;
7401 ilist_t *scheduled_insns_tailp = &scheduled_insns;
7402
7403 find_min_max_seqno (fences, &min_seqno, &max_seqno);
7404 schedule_on_fences (fences, max_seqno, &scheduled_insns_tailp);
7405 fences = calculate_new_fences (fences, orig_max_seqno);
7406 highest_seqno_in_use = update_seqnos_and_stage (min_seqno, max_seqno,
7407 highest_seqno_in_use,
7408 &scheduled_insns);
7409 }
7410
7411 if (sched_verbose >= 1)
7412 sel_print ("Scheduled %d bookkeeping copies, %d insns needed "
7413 "bookkeeping, %d insns renamed, %d insns substituted\n",
7414 stat_bookkeeping_copies,
7415 stat_insns_needed_bookkeeping,
7416 stat_renamed_scheduled,
7417 stat_substitutions_total);
7418}
7419
b8698a0f
L
7420/* Schedule a region. When pipelining, search for possibly never scheduled
7421 bookkeeping code and schedule it. Reschedule pipelined code without
e855c69d
AB
7422 pipelining after. */
7423static void
7424sel_sched_region_1 (void)
7425{
7426 int number_of_insns;
7427 int orig_max_seqno;
7428
b8698a0f 7429 /* Remove empty blocks that might be in the region from the beginning.
e855c69d 7430 We need to do save sched_max_luid before that, as it actually shows
b8698a0f 7431 the number of insns in the region, and purge_empty_blocks can
e855c69d
AB
7432 alter it. */
7433 number_of_insns = sched_max_luid - 1;
7434 purge_empty_blocks ();
7435
7436 orig_max_seqno = init_seqno (number_of_insns, NULL, NULL);
7437 gcc_assert (orig_max_seqno >= 1);
7438
7439 /* When pipelining outer loops, create fences on the loop header,
7440 not preheader. */
7441 fences = NULL;
7442 if (current_loop_nest)
7443 init_fences (BB_END (EBB_FIRST_BB (0)));
7444 else
7445 init_fences (bb_note (EBB_FIRST_BB (0)));
7446 global_level = 1;
7447
7448 sel_sched_region_2 (orig_max_seqno);
7449
7450 gcc_assert (fences == NULL);
7451
7452 if (pipelining_p)
7453 {
7454 int i;
7455 basic_block bb;
7456 struct flist_tail_def _new_fences;
7457 flist_tail_t new_fences = &_new_fences;
7458 bool do_p = true;
7459
7460 pipelining_p = false;
7461 max_ws = MIN (max_ws, issue_rate * 3 / 2);
7462 bookkeeping_p = false;
7463 enable_schedule_as_rhs_p = false;
7464
7465 /* Schedule newly created code, that has not been scheduled yet. */
7466 do_p = true;
7467
7468 while (do_p)
7469 {
7470 do_p = false;
7471
7472 for (i = 0; i < current_nr_blocks; i++)
7473 {
7474 basic_block bb = EBB_FIRST_BB (i);
7475
7476 if (sel_bb_empty_p (bb))
7477 {
7478 bitmap_clear_bit (blocks_to_reschedule, bb->index);
7479 continue;
7480 }
7481
7482 if (bitmap_bit_p (blocks_to_reschedule, bb->index))
7483 {
7484 clear_outdated_rtx_info (bb);
7485 if (sel_insn_is_speculation_check (BB_END (bb))
7486 && JUMP_P (BB_END (bb)))
7487 bitmap_set_bit (blocks_to_reschedule,
7488 BRANCH_EDGE (bb)->dest->index);
7489 }
7490 else if (INSN_SCHED_TIMES (sel_bb_head (bb)) <= 0)
7491 bitmap_set_bit (blocks_to_reschedule, bb->index);
7492 }
7493
7494 for (i = 0; i < current_nr_blocks; i++)
7495 {
7496 bb = EBB_FIRST_BB (i);
7497
b8698a0f 7498 /* While pipelining outer loops, skip bundling for loop
e855c69d
AB
7499 preheaders. Those will be rescheduled in the outer
7500 loop. */
7501 if (sel_is_loop_preheader_p (bb))
7502 {
7503 clear_outdated_rtx_info (bb);
7504 continue;
7505 }
b8698a0f 7506
e855c69d
AB
7507 if (bitmap_bit_p (blocks_to_reschedule, bb->index))
7508 {
7509 flist_tail_init (new_fences);
7510
7511 orig_max_seqno = init_seqno (0, blocks_to_reschedule, bb);
7512
7513 /* Mark BB as head of the new ebb. */
7514 bitmap_set_bit (forced_ebb_heads, bb->index);
7515
7516 bitmap_clear_bit (blocks_to_reschedule, bb->index);
b8698a0f 7517
e855c69d
AB
7518 gcc_assert (fences == NULL);
7519
7520 init_fences (bb_note (bb));
b8698a0f 7521
e855c69d 7522 sel_sched_region_2 (orig_max_seqno);
b8698a0f 7523
e855c69d
AB
7524 do_p = true;
7525 break;
7526 }
7527 }
7528 }
7529 }
7530}
7531
7532/* Schedule the RGN region. */
7533void
7534sel_sched_region (int rgn)
7535{
7536 bool schedule_p;
7537 bool reset_sched_cycles_p;
7538
7539 if (sel_region_init (rgn))
7540 return;
7541
7542 if (sched_verbose >= 1)
7543 sel_print ("Scheduling region %d\n", rgn);
7544
7545 schedule_p = (!sched_is_disabled_for_current_region_p ()
7546 && dbg_cnt (sel_sched_region_cnt));
7547 reset_sched_cycles_p = pipelining_p;
7548 if (schedule_p)
7549 sel_sched_region_1 ();
7550 else
7551 /* Force initialization of INSN_SCHED_CYCLEs for correct bundling. */
7552 reset_sched_cycles_p = true;
b8698a0f 7553
e855c69d
AB
7554 sel_region_finish (reset_sched_cycles_p);
7555}
7556
7557/* Perform global init for the scheduler. */
7558static void
7559sel_global_init (void)
7560{
7561 calculate_dominance_info (CDI_DOMINATORS);
7562 alloc_sched_pools ();
7563
7564 /* Setup the infos for sched_init. */
7565 sel_setup_sched_infos ();
7566 setup_sched_dump ();
7567
7568 sched_rgn_init (false);
7569 sched_init ();
7570
7571 sched_init_bbs ();
7572 /* Reset AFTER_RECOVERY if it has been set by the 1st scheduler pass. */
7573 after_recovery = 0;
b8698a0f 7574 can_issue_more = issue_rate;
e855c69d
AB
7575
7576 sched_extend_target ();
7577 sched_deps_init (true);
7578 setup_nop_and_exit_insns ();
7579 sel_extend_global_bb_info ();
7580 init_lv_sets ();
7581 init_hard_regs_data ();
7582}
7583
7584/* Free the global data of the scheduler. */
7585static void
7586sel_global_finish (void)
7587{
7588 free_bb_note_pool ();
7589 free_lv_sets ();
7590 sel_finish_global_bb_info ();
7591
7592 free_regset_pool ();
7593 free_nop_and_exit_insns ();
7594
7595 sched_rgn_finish ();
7596 sched_deps_finish ();
7597 sched_finish ();
7598
7599 if (current_loops)
7600 sel_finish_pipelining ();
7601
7602 free_sched_pools ();
7603 free_dominance_info (CDI_DOMINATORS);
7604}
7605
7606/* Return true when we need to skip selective scheduling. Used for debugging. */
7607bool
7608maybe_skip_selective_scheduling (void)
7609{
7610 return ! dbg_cnt (sel_sched_cnt);
7611}
7612
7613/* The entry point. */
7614void
7615run_selective_scheduling (void)
7616{
7617 int rgn;
7618
7619 if (n_basic_blocks == NUM_FIXED_BLOCKS)
7620 return;
7621
7622 sel_global_init ();
7623
7624 for (rgn = 0; rgn < nr_regions; rgn++)
7625 sel_sched_region (rgn);
7626
7627 sel_global_finish ();
7628}
7629
7630#endif