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