GCC Middle and Back End API Reference
sel-sched-ir.h
Go to the documentation of this file.
1/* Instruction scheduling pass. This file contains definitions used
2 internally in the scheduler.
3 Copyright (C) 2006-2026 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#ifndef GCC_SEL_SCHED_IR_H
22#define GCC_SEL_SCHED_IR_H
23
24/* tc_t is a short for target context. This is a state of the target
25 backend. */
26typedef void *tc_t;
27
28/* List data types used for av sets, fences, paths, and boundaries. */
29
30/* Forward declarations for types that are part of some list nodes. */
31struct _list_node;
32
33/* List backend. */
34typedef struct _list_node *_list_t;
35#define _LIST_NEXT(L) ((L)->next)
36
37/* Instruction data that is part of vinsn type. */
38struct idata_def;
39typedef struct idata_def *idata_t;
40
41/* A virtual instruction, i.e. an instruction as seen by the scheduler. */
42struct vinsn_def;
43typedef struct vinsn_def *vinsn_t;
44
45/* RTX list.
46 This type is the backend for ilist. */
48#define _XLIST_X(L) ((L)->u.x)
49#define _XLIST_NEXT(L) (_LIST_NEXT (L))
50
51/* Instruction. */
53
54/* List of insns. */
56#define ILIST_INSN(L) ((L)->u.insn)
57#define ILIST_NEXT(L) (_LIST_NEXT (L))
58
59/* This lists possible transformations that done locally, i.e. in
60 moveup_expr. */
66
67/* This struct is used to record the history of expression's
68 transformations. */
70{
71 /* UID of the insn. */
72 unsigned uid;
73
74 /* How the expression looked like. */
76
77 /* How the expression looks after the transformation. */
79
80 /* And its speculative status. */
81 ds_t spec_ds;
82
83 /* Type of the transformation. */
85};
86
88
89
90/* Expression information. */
91struct _expr
92{
93 /* Insn description. */
95
96 /* SPEC is the degree of speculativeness.
97 FIXME: now spec is increased when an rhs is moved through a
98 conditional, thus showing only control speculativeness. In the
99 future we'd like to count data spec separately to allow a better
100 control on scheduling. */
101 int spec;
102
103 /* Degree of speculativeness measured as probability of executing
104 instruction's original basic block given relative to
105 the current scheduling point. */
107
108 /* A priority of this expression. */
110
111 /* A priority adjustment of this expression. */
113
114 /* Number of times the insn was scheduled. */
116
117 /* A basic block index this was originated from. Zero when there is
118 more than one originator. */
120
121 /* Instruction should be of SPEC_DONE_DS type in order to be moved to this
122 point. */
124
125 /* SPEC_TO_CHECK_DS hold speculation types that should be checked
126 (used only during move_op ()). */
128
129 /* Cycle on which original insn was scheduled. Zero when it has not yet
130 been scheduled or more than one originator. */
132
133 /* This vector contains the history of insn's transformations. */
135
136 /* True (1) when original target (register or memory) of this instruction
137 is available for scheduling, false otherwise. -1 means we're not sure;
138 please run find_used_regs to clarify. */
139 signed char target_available;
140
141 /* True when this expression needs a speculation check to be scheduled.
142 This is used during find_used_regs. */
144
145 /* True when the expression was substituted. Used for statistical
146 purposes. */
148
149 /* True when the expression was renamed. */
151
152 /* True when expression can't be moved. */
154};
155
156typedef struct _expr expr_def;
158
159#define EXPR_VINSN(EXPR) ((EXPR)->vinsn)
160#define EXPR_INSN_RTX(EXPR) (VINSN_INSN_RTX (EXPR_VINSN (EXPR)))
161#define EXPR_PATTERN(EXPR) (VINSN_PATTERN (EXPR_VINSN (EXPR)))
162#define EXPR_LHS(EXPR) (VINSN_LHS (EXPR_VINSN (EXPR)))
163#define EXPR_RHS(EXPR) (VINSN_RHS (EXPR_VINSN (EXPR)))
164#define EXPR_TYPE(EXPR) (VINSN_TYPE (EXPR_VINSN (EXPR)))
165#define EXPR_SEPARABLE_P(EXPR) (VINSN_SEPARABLE_P (EXPR_VINSN (EXPR)))
166
167#define EXPR_SPEC(EXPR) ((EXPR)->spec)
168#define EXPR_USEFULNESS(EXPR) ((EXPR)->usefulness)
169#define EXPR_PRIORITY(EXPR) ((EXPR)->priority)
170#define EXPR_PRIORITY_ADJ(EXPR) ((EXPR)->priority_adj)
171#define EXPR_SCHED_TIMES(EXPR) ((EXPR)->sched_times)
172#define EXPR_ORIG_BB_INDEX(EXPR) ((EXPR)->orig_bb_index)
173#define EXPR_ORIG_SCHED_CYCLE(EXPR) ((EXPR)->orig_sched_cycle)
174#define EXPR_SPEC_DONE_DS(EXPR) ((EXPR)->spec_done_ds)
175#define EXPR_SPEC_TO_CHECK_DS(EXPR) ((EXPR)->spec_to_check_ds)
176#define EXPR_HISTORY_OF_CHANGES(EXPR) ((EXPR)->history_of_changes)
177#define EXPR_TARGET_AVAILABLE(EXPR) ((EXPR)->target_available)
178#define EXPR_NEEDS_SPEC_CHECK_P(EXPR) ((EXPR)->needs_spec_check_p)
179#define EXPR_WAS_SUBSTITUTED(EXPR) ((EXPR)->was_substituted)
180#define EXPR_WAS_RENAMED(EXPR) ((EXPR)->was_renamed)
181#define EXPR_CANT_MOVE(EXPR) ((EXPR)->cant_move)
182
183/* Insn definition for list of original insns in find_used_regs. */
184struct _def
185{
187
188 /* FIXME: Get rid of CROSSED_CALL_ABIS in each def, since if we're moving up
189 rhs from two different places, but only one of the code motion paths
190 crosses a call, we can't use any of the call_used_regs, no matter which
191 path or whether all paths crosses a call. Thus we should move
192 CROSSED_CALL_ABIS to static params. */
193 unsigned int crossed_call_abis;
194};
195typedef struct _def *def_t;
196
197
198/* Availability sets are sets of expressions we're scheduling. */
200#define _AV_SET_EXPR(L) (&(L)->u.expr)
201#define _AV_SET_NEXT(L) (_LIST_NEXT (L))
202
203
204/* Boundary of the current fence group. */
205struct _bnd
206{
207 /* The actual boundary instruction. */
209
210 /* Its path to the fence. */
212
213 /* Availability set at the boundary. */
215
216 /* This set moved to the fence. */
218
219 /* Deps context at this boundary. As long as we have one boundary per fence,
220 this is just a pointer to the same deps context as in the corresponding
221 fence. */
222 deps_t dc;
223};
224typedef struct _bnd *bnd_t;
225#define BND_TO(B) ((B)->to)
226
227/* PTR stands not for pointer as you might think, but as a Path To Root of the
228 current instruction group from boundary B. */
229#define BND_PTR(B) ((B)->ptr)
230#define BND_AV(B) ((B)->av)
231#define BND_AV1(B) ((B)->av1)
232#define BND_DC(B) ((B)->dc)
233
234/* List of boundaries. */
236#define BLIST_BND(L) (&(L)->u.bnd)
237#define BLIST_NEXT(L) (_LIST_NEXT (L))
238
239
240/* Fence information. A fence represents current scheduling point and also
241 blocks code motion through it when pipelining. */
242struct _fence
243{
244 /* Insn before which we gather an instruction group.*/
246
247 /* Modeled state of the processor pipeline. */
249
250 /* Current cycle that is being scheduled on this fence. */
251 int cycle;
252
253 /* Number of insns that were scheduled on the current cycle.
254 This information has to be local to a fence. */
256
257 /* At the end of fill_insns () this field holds the list of the instructions
258 that are inner boundaries of the scheduled parallel group. */
260
261 /* Deps context at this fence. It is used to model dependencies at the
262 fence so that insn ticks can be properly evaluated. */
263 deps_t dc;
264
265 /* Target context at this fence. Used to save and load any local target
266 scheduling information when changing fences. */
268
269 /* A vector of insns that are scheduled but not yet completed. */
271
272 /* A vector indexed by UIDs that caches the earliest cycle on which
273 an insn can be scheduled on this fence. */
275
276 /* Its size. */
278
279 /* Insn, which has been scheduled last on this fence. */
281
282 /* The last value of can_issue_more variable on this fence. */
284
285 /* If non-NULL force the next scheduled insn to be SCHED_NEXT. */
287
288 /* True if fill_insns processed this fence. */
290
291 /* True if fill_insns actually scheduled something on this fence. */
293
294 /* True when the next insn scheduled here would start a cycle. */
296
297 /* True when the next insn scheduled here would be scheduled after a stall. */
299};
300typedef struct _fence *fence_t;
301
302#define FENCE_INSN(F) ((F)->insn)
303#define FENCE_STATE(F) ((F)->state)
304#define FENCE_BNDS(F) ((F)->bnds)
305#define FENCE_PROCESSED_P(F) ((F)->processed_p)
306#define FENCE_SCHEDULED_P(F) ((F)->scheduled_p)
307#define FENCE_ISSUED_INSNS(F) ((F)->cycle_issued_insns)
308#define FENCE_CYCLE(F) ((F)->cycle)
309#define FENCE_STARTS_CYCLE_P(F) ((F)->starts_cycle_p)
310#define FENCE_AFTER_STALL_P(F) ((F)->after_stall_p)
311#define FENCE_DC(F) ((F)->dc)
312#define FENCE_TC(F) ((F)->tc)
313#define FENCE_LAST_SCHEDULED_INSN(F) ((F)->last_scheduled_insn)
314#define FENCE_ISSUE_MORE(F) ((F)->issue_more)
315#define FENCE_EXECUTING_INSNS(F) ((F)->executing_insns)
316#define FENCE_READY_TICKS(F) ((F)->ready_ticks)
317#define FENCE_READY_TICKS_SIZE(F) ((F)->ready_ticks_size)
318#define FENCE_SCHED_NEXT(F) ((F)->sched_next)
319
320/* List of fences. */
322#define FLIST_FENCE(L) (&(L)->u.fence)
323#define FLIST_NEXT(L) (_LIST_NEXT (L))
324
325/* List of fences with pointer to the tail node. */
331
333#define FLIST_TAIL_HEAD(L) ((L)->head)
334#define FLIST_TAIL_TAILP(L) ((L)->tailp)
335
336/* List node information. A list node can be any of the types above. */
338{
340
341 union
342 {
345 struct _bnd bnd;
347 struct _fence fence;
348 struct _def def;
349 void *data;
350 } u;
351};
352
353
354/* _list_t functions.
355 All of _*list_* functions are used through accessor macros, thus
356 we can't move them in sel-sched-ir.cc. */
358
359inline _list_t
361{
362 return sched_lists_pool.allocate ();
363}
364
365inline void
367{
368 _list_t l = _list_alloc ();
369
370 _LIST_NEXT (l) = *lp;
371 *lp = l;
372}
373
374inline void
376{
377 _list_t n = *lp;
378
379 *lp = _LIST_NEXT (n);
380}
381
382inline void
384{
385 _list_t n = *lp;
386
387 *lp = _LIST_NEXT (n);
388 sched_lists_pool.remove (n);
389}
390
391inline void
393{
394 while (*l)
395 _list_remove (l);
396}
397
398
399/* List iterator backend. */
401{
402 /* The list we're iterating. */
404
405 /* True when this iterator supports removing. */
407
408 /* True when we've actually removed something. */
410};
411
412inline void
413_list_iter_start (_list_iterator *ip, _list_t *lp, bool can_remove_p)
414{
415 ip->lp = lp;
416 ip->can_remove_p = can_remove_p;
417 ip->removed_p = false;
418}
419
420inline void
422{
423 if (!ip->removed_p)
424 ip->lp = &_LIST_NEXT (*ip->lp);
425 else
426 ip->removed_p = false;
427}
428
429inline void
431{
432 gcc_assert (!ip->removed_p && ip->can_remove_p);
433 _list_remove (ip->lp);
434 ip->removed_p = true;
435}
436
437inline void
439{
440 gcc_assert (!ip->removed_p && ip->can_remove_p);
442 ip->removed_p = true;
443}
444
445/* General macros to traverse a list. FOR_EACH_* interfaces are
446 implemented using these. */
447#define _FOR_EACH(TYPE, ELEM, I, L) \
448 for (_list_iter_start (&(I), &(L), false); \
449 _list_iter_cond_##TYPE (*(I).lp, &(ELEM)); \
450 _list_iter_next (&(I)))
451
452#define _FOR_EACH_1(TYPE, ELEM, I, LP) \
453 for (_list_iter_start (&(I), (LP), true); \
454 _list_iter_cond_##TYPE (*(I).lp, &(ELEM)); \
455 _list_iter_next (&(I)))
456
457
458/* _xlist_t functions. */
459
460inline void
462{
463 _list_add (lp);
464 _XLIST_X (*lp) = x;
465}
466
467#define _xlist_remove(LP) (_list_remove (LP))
468#define _xlist_clear(LP) (_list_clear (LP))
469
470inline bool
472{
473 while (l)
474 {
475 if (_XLIST_X (l) == x)
476 return true;
477 l = _XLIST_NEXT (l);
478 }
479
480 return false;
481}
482
483/* Used through _FOR_EACH. */
484inline bool
486{
487 if (l)
488 {
489 *xp = _XLIST_X (l);
490 return true;
491 }
492
493 return false;
494}
495
496#define _xlist_iter_remove(IP) (_list_iter_remove (IP))
497
499#define _FOR_EACH_X(X, I, L) _FOR_EACH (x, (X), (I), (L))
500#define _FOR_EACH_X_1(X, I, LP) _FOR_EACH_1 (x, (X), (I), (LP))
501
502
503/* ilist_t functions. */
504
505inline void
507{
508 _list_add (lp);
509 ILIST_INSN (*lp) = insn;
510}
511#define ilist_remove(LP) (_list_remove (LP))
512#define ilist_clear(LP) (_list_clear (LP))
513
514inline bool
516{
517 while (l)
518 {
519 if (ILIST_INSN (l) == insn)
520 return true;
521 l = ILIST_NEXT (l);
522 }
523
524 return false;
525}
526
527/* Used through _FOR_EACH. */
528inline bool
530{
531 if (l)
532 {
533 *ip = ILIST_INSN (l);
534 return true;
535 }
536
537 return false;
538}
539
540#define ilist_iter_remove(IP) (_list_iter_remove (IP))
541
543#define FOR_EACH_INSN(INSN, I, L) _FOR_EACH (insn, (INSN), (I), (L))
544#define FOR_EACH_INSN_1(INSN, I, LP) _FOR_EACH_1 (insn, (INSN), (I), (LP))
545
546
547/* Av set iterators. */
549#define FOR_EACH_EXPR(EXPR, I, AV) _FOR_EACH (expr, (EXPR), (I), (AV))
550#define FOR_EACH_EXPR_1(EXPR, I, AV) _FOR_EACH_1 (expr, (EXPR), (I), (AV))
551
552inline bool
554{
555 if (av)
556 {
557 *exprp = _AV_SET_EXPR (av);
558 return true;
559 }
560
561 return false;
562}
563
564
565/* Def list iterators. */
568
569#define DEF_LIST_NEXT(L) (_LIST_NEXT (L))
570#define DEF_LIST_DEF(L) (&(L)->u.def)
571
572#define FOR_EACH_DEF(DEF, I, DEF_LIST) _FOR_EACH (def, (DEF), (I), (DEF_LIST))
573
574inline bool
576{
577 if (def_list)
578 {
579 *def = DEF_LIST_DEF (def_list);
580 return true;
581 }
582
583 return false;
584}
585
586
587/* InstructionData. Contains information about insn pattern. */
589{
590 /* Type of the insn.
591 o CALL_INSN - Call insn
592 o JUMP_INSN - Jump insn
593 o INSN - INSN that cannot be cloned
594 o USE - INSN that can be cloned
595 o SET - INSN that can be cloned and separable into lhs and rhs
596 o PC - simplejump. Insns that simply redirect control flow should not
597 have any dependencies. Sched-deps.c, though, might consider them as
598 producers or consumers of certain registers. To avoid that we handle
599 dependency for simple jumps ourselves. */
600 int type;
601
602 /* If insn is a SET, this is its left hand side. */
604
605 /* If insn is a SET, this is its right hand side. */
607
608 /* Registers that are set/used by this insn. This info is now gathered
609 via sched-deps.cc. The downside of this is that we also use live info
610 from flow that is accumulated in the basic blocks. These two infos
611 can be slightly inconsistent, hence in the beginning we make a pass
612 through CFG and calculating the conservative solution for the info in
613 basic blocks. When this scheduler will be switched to use dataflow,
614 this can be unified as df gives us both per basic block and per
615 instruction info. Actually, we don't do that pass and just hope
616 for the best. */
618
620
622};
623
624#define IDATA_TYPE(ID) ((ID)->type)
625#define IDATA_LHS(ID) ((ID)->lhs)
626#define IDATA_RHS(ID) ((ID)->rhs)
627#define IDATA_REG_SETS(ID) ((ID)->reg_sets)
628#define IDATA_REG_USES(ID) ((ID)->reg_uses)
629#define IDATA_REG_CLOBBERS(ID) ((ID)->reg_clobbers)
630
631/* Type to represent all needed info to emit an insn.
632 This is a virtual equivalent of the insn.
633 Every insn in the stream has an associated vinsn. This is used
634 to reduce memory consumption basing on the fact that many insns
635 don't change through the scheduler.
636
637 vinsn can be either normal or unique.
638 * Normal vinsn is the one, that can be cloned multiple times and typically
639 corresponds to normal instruction.
640
641 * Unique vinsn derivates from CALL, ASM, JUMP (for a while) and other
642 unusual stuff. Such a vinsn is described by its INSN field, which is a
643 reference to the original instruction. */
645{
646 /* Associated insn. */
648
649 /* Its description. */
650 struct idata_def id;
651
652 /* Hash of vinsn. It is computed either from pattern or from rhs using
653 hash_rtx. It is not placed in ID for faster compares. */
654 unsigned hash;
655
656 /* Hash of the insn_rtx pattern. */
657 unsigned hash_rtx;
658
659 /* Smart pointer counter. */
660 int count;
661
662 /* Cached cost of the vinsn. To access it please use vinsn_cost (). */
663 int cost;
664
665 /* Mark insns that may trap so we don't move them through jumps. */
667};
668
669#define VINSN_INSN_RTX(VI) ((VI)->insn_rtx)
670#define VINSN_PATTERN(VI) (PATTERN (VINSN_INSN_RTX (VI)))
671
672#define VINSN_ID(VI) (&((VI)->id))
673#define VINSN_HASH(VI) ((VI)->hash)
674#define VINSN_HASH_RTX(VI) ((VI)->hash_rtx)
675#define VINSN_TYPE(VI) (IDATA_TYPE (VINSN_ID (VI)))
676#define VINSN_SEPARABLE_P(VI) (VINSN_TYPE (VI) == SET)
677#define VINSN_CLONABLE_P(VI) (VINSN_SEPARABLE_P (VI) || VINSN_TYPE (VI) == USE)
678#define VINSN_UNIQUE_P(VI) (!VINSN_CLONABLE_P (VI))
679#define VINSN_LHS(VI) (IDATA_LHS (VINSN_ID (VI)))
680#define VINSN_RHS(VI) (IDATA_RHS (VINSN_ID (VI)))
681#define VINSN_REG_SETS(VI) (IDATA_REG_SETS (VINSN_ID (VI)))
682#define VINSN_REG_USES(VI) (IDATA_REG_USES (VINSN_ID (VI)))
683#define VINSN_REG_CLOBBERS(VI) (IDATA_REG_CLOBBERS (VINSN_ID (VI)))
684#define VINSN_COUNT(VI) ((VI)->count)
685#define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p)
686
687
688/* An entry of the hashtable describing transformations happened when
689 moving up through an insn. */
691{
692 /* Previous vinsn. Used to find the proper element. */
694
695 /* A new vinsn. */
697
698 /* Speculative status. */
699 ds_t ds;
700
701 /* Type of transformation happened. */
703
704 /* Whether a conflict on the target register happened. */
706
707 /* Whether a check was needed. */
709};
710
711/* Indexed by INSN_LUID, the collection of all data associated with
712 a single instruction that is in the stream. */
714{
715public:
716 /* The expression that contains vinsn for this insn and some
717 flow-sensitive data like priority. */
719
720 /* If (WS_LEVEL == GLOBAL_LEVEL) then AV is empty. */
722
723 /* A number that helps in defining a traversing order for a region. */
724 int seqno;
725
726 /* A liveness data computed above this insn. */
728
729 /* An INSN_UID bit is set when deps analysis result is already known. */
731
732 /* An INSN_UID bit is set when a hard dep was found, not set when
733 no dependence is found. This is meaningful only when the analyzed_deps
734 bitmap has its bit set. */
736
737 /* An INSN_UID bit is set when this is a bookkeeping insn generated from
738 a parent with this uid. If a parent is a bookkeeping copy, all its
739 originators are transitively included in this set. */
741
742 /* A hashtable caching the result of insn transformations through this one. */
744
745 /* A context incapsulating this insn. */
746 class deps_desc deps_context;
747
748 /* This field is initialized at the beginning of scheduling and is used
749 to handle sched group instructions. If it is non-null, then it points
750 to the instruction, which should be forced to schedule next. Such
751 instructions are unique. */
753
754 /* Cycle at which insn was scheduled. It is greater than zero if insn was
755 scheduled. This is used for bundling. */
757
758 /* Cycle at which insn's data will be fully ready. */
760
761 /* Speculations that are being checked by this insn. */
763
764 /* Whether the live set valid or not. */
766 /* Insn is an ASM. */
768
769 /* True when an insn is scheduled after we've determined that a stall is
770 required.
771 This is used when emulating the Haifa scheduler for bundling. */
773};
774
777
779
780/* Accessor macros for s_i_d. */
781#define SID(INSN) (&s_i_d[INSN_LUID (INSN)])
782#define SID_BY_UID(UID) (&s_i_d[LUID_BY_UID (UID)])
783
785
786#define INSN_ASM_P(INSN) (SID (INSN)->asm_p)
787#define INSN_SCHED_NEXT(INSN) (SID (INSN)->sched_next)
788#define INSN_ANALYZED_DEPS(INSN) (SID (INSN)->analyzed_deps)
789#define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps)
790#define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context)
791#define INSN_ORIGINATORS(INSN) (SID (INSN)->originators)
792#define INSN_ORIGINATORS_BY_UID(UID) (SID_BY_UID (UID)->originators)
793#define INSN_TRANSFORMED_INSNS(INSN) (SID (INSN)->transformed_insns)
794
795#define INSN_EXPR(INSN) (&SID (INSN)->expr)
796#define INSN_LIVE(INSN) (SID (INSN)->live)
797#define INSN_LIVE_VALID_P(INSN) (SID (INSN)->live_valid_p)
798#define INSN_VINSN(INSN) (EXPR_VINSN (INSN_EXPR (INSN)))
799#define INSN_TYPE(INSN) (VINSN_TYPE (INSN_VINSN (INSN)))
800#define INSN_SIMPLEJUMP_P(INSN) (INSN_TYPE (INSN) == PC)
801#define INSN_LHS(INSN) (VINSN_LHS (INSN_VINSN (INSN)))
802#define INSN_RHS(INSN) (VINSN_RHS (INSN_VINSN (INSN)))
803#define INSN_REG_SETS(INSN) (VINSN_REG_SETS (INSN_VINSN (INSN)))
804#define INSN_REG_CLOBBERS(INSN) (VINSN_REG_CLOBBERS (INSN_VINSN (INSN)))
805#define INSN_REG_USES(INSN) (VINSN_REG_USES (INSN_VINSN (INSN)))
806#define INSN_SCHED_TIMES(INSN) (EXPR_SCHED_TIMES (INSN_EXPR (INSN)))
807#define INSN_SEQNO(INSN) (SID (INSN)->seqno)
808#define INSN_AFTER_STALL_P(INSN) (SID (INSN)->after_stall_p)
809#define INSN_SCHED_CYCLE(INSN) (SID (INSN)->sched_cycle)
810#define INSN_READY_CYCLE(INSN) (SID (INSN)->ready_cycle)
811#define INSN_SPEC_CHECKED_DS(INSN) (SID (INSN)->spec_checked_ds)
812
813/* A global level shows whether an insn is valid or not. */
814extern int global_level;
815
816#define INSN_WS_LEVEL(INSN) (SID (INSN)->ws_level)
817
819extern int get_av_level (insn_t);
820
821#define AV_SET(INSN) (get_av_set (INSN))
822#define AV_LEVEL(INSN) (get_av_level (INSN))
823#define AV_SET_VALID_P(INSN) (AV_LEVEL (INSN) == global_level)
824
825/* A list of fences currently in the works. */
826extern flist_t fences;
827
828/* A NOP pattern used as a placeholder for real insns. */
829extern rtx nop_pattern;
830
831/* An insn that 'contained' in EXIT block. */
832extern rtx_insn *exit_insn;
833
834/* Provide a separate luid for the insn. */
835#define INSN_INIT_TODO_LUID (1)
836
837/* Initialize s_s_i_d. */
838#define INSN_INIT_TODO_SSID (2)
839
840/* Initialize data for simplejump. */
841#define INSN_INIT_TODO_SIMPLEJUMP (4)
842
843/* Return true if INSN is a local NOP. The nop is local in the sense that
844 it was emitted by the scheduler as a temporary insn and will soon be
845 deleted. These nops are identified by their pattern. */
846#define INSN_NOP_P(INSN) (PATTERN (INSN) == nop_pattern)
847
848/* Return true if INSN is linked into instruction stream.
849 NB: It is impossible for INSN to have one field null and the other not
850 null: gcc_assert ((PREV_INSN (INSN) == NULL_RTX)
851 == (NEXT_INSN (INSN) == NULL_RTX)) is valid. */
852#define INSN_IN_STREAM_P(INSN) (PREV_INSN (INSN) && NEXT_INSN (INSN))
853
854/* Return true if INSN is in current fence. */
855#define IN_CURRENT_FENCE_P(INSN) (flist_lookup (fences, INSN) != NULL)
856
857/* Marks loop as being considered for pipelining. */
858#define MARK_LOOP_FOR_PIPELINING(LOOP) ((LOOP)->aux = (void *)(size_t)(1))
859#define LOOP_MARKED_FOR_PIPELINING_P(LOOP) ((size_t)((LOOP)->aux))
860
861/* Saved loop preheader to transfer when scheduling the loop. */
862#define LOOP_PREHEADER_BLOCKS(LOOP) ((size_t)((LOOP)->aux) == 1 \
863 ? NULL \
864 : ((vec<basic_block> *) (LOOP)->aux))
865#define SET_LOOP_PREHEADER_BLOCKS(LOOP,BLOCKS) ((LOOP)->aux \
866 = (BLOCKS != NULL \
867 ? BLOCKS \
868 : (LOOP)->aux))
869
871
872
873/* A variable to track which part of rtx we are scanning in
874 sched-deps.cc: sched_analyze_insn (). */
882
883
884/* Per basic block data for the whole CFG. */
886{
887 /* For each bb header this field contains a set of live registers.
888 For all other insns this field has a NULL.
889 We also need to know LV sets for the instructions, that are immediately
890 after the border of the region. */
892
893 /* Status of LV_SET.
894 true - block has usable LV_SET.
895 false - block's LV_SET should be recomputed. */
897};
898
900
901
902/* Per basic block data. This array is indexed by basic block index. */
904
905extern void sel_extend_global_bb_info (void);
906extern void sel_finish_global_bb_info (void);
907
908/* Get data for BB. */
909#define SEL_GLOBAL_BB_INFO(BB) \
910 (&sel_global_bb_info[(BB)->index])
911
912/* Access macros. */
913#define BB_LV_SET(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set)
914#define BB_LV_SET_VALID_P(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set_valid_p)
915
916/* Per basic block data for the region. */
918{
919 /* This insn stream is constructed in such a way that it should be
920 traversed by PREV_INSN field - (*not* NEXT_INSN). */
922
923 /* Cached availability set at the beginning of a block.
924 See also AV_LEVEL () for conditions when this av_set can be used. */
926
927 /* If (AV_LEVEL == GLOBAL_LEVEL) then AV is valid. */
929};
930
932
933
934/* Per basic block data. This array is indexed by basic block index. */
936
937/* Get data for BB. */
938#define SEL_REGION_BB_INFO(BB) (&sel_region_bb_info[(BB)->index])
939
940/* Get BB's note_list.
941 A note_list is a list of various notes that was scattered across BB
942 before scheduling, and will be appended at the beginning of BB after
943 scheduling is finished. */
944#define BB_NOTE_LIST(BB) (SEL_REGION_BB_INFO (BB)->note_list)
945
946#define BB_AV_SET(BB) (SEL_REGION_BB_INFO (BB)->av_set)
947#define BB_AV_LEVEL(BB) (SEL_REGION_BB_INFO (BB)->av_level)
948#define BB_AV_SET_VALID_P(BB) (BB_AV_LEVEL (BB) == global_level)
949
950/* Used in bb_in_ebb_p. */
952
953/* The loop nest being pipelined. */
954extern class loop *current_loop_nest;
955
956/* Saves pipelined blocks. Bitmap is indexed by bb->index. */
958
959/* Various flags. */
960extern bool enable_moveup_set_path_p;
961extern bool pipelining_p;
962extern bool bookkeeping_p;
963extern int max_insns_to_rename;
964extern bool preheader_removed;
965
966/* Software lookahead window size.
967 According to the results in Nakatani and Ebcioglu [1993], window size of 16
968 is enough to extract most ILP in integer code. */
969#define MAX_WS (param_selsched_max_lookahead)
970
971extern regset sel_all_regs;
972
973
974/* Successor iterator backend. */
976{
977 /* True if we're at BB end. */
978 bool bb_end;
979
980 /* An edge on which we're iterating. */
982
983 /* The previous edge saved after skipping empty blocks. */
985
986 /* Edge iterator used when there are successors in other basic blocks. */
988
989 /* Successor block we're traversing. */
991
992 /* Flags that are passed to the iterator. We return only successors
993 that comply to these flags. */
994 short flags;
995
996 /* When flags include SUCCS_ALL, this will be set to the exact type
997 of the successor we're traversing now. */
999
1000 /* If skip to loop exits, save here information about loop exits. */
1003};
1004
1005/* A structure returning all successor's information. */
1007{
1008 /* Flags that these successors were computed with. */
1009 short flags;
1010
1011 /* Successors that correspond to the flags. */
1012 insn_vec_t succs_ok;
1013
1014 /* Their probabilities. As of now, we don't need this for other
1015 successors. */
1017
1018 /* Other successors. */
1019 insn_vec_t succs_other;
1020
1021 /* Probability of all successors. */
1023
1024 /* The number of all successors. */
1026
1027 /* The number of good successors. */
1029};
1030
1031/* Some needed definitions. */
1033
1038
1039/* True when BB is a header of the inner loop. */
1040inline bool
1042{
1043 class loop *inner_loop;
1044
1045 if (!current_loop_nest)
1046 return false;
1047
1048 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1049 return false;
1050
1051 inner_loop = bb->loop_father;
1052 if (inner_loop == current_loop_nest)
1053 return false;
1054
1055 /* If successor belongs to another loop. */
1056 if (bb == inner_loop->header
1058 {
1059 /* Could be '=' here because of wrong loop depths. */
1061 return true;
1062 }
1063
1064 return false;
1065}
1066
1067/* Return exit edges of LOOP, filtering out edges with the same dest bb. */
1068inline vec<edge>
1070{
1071 vec<edge> edges = vNULL;
1072 struct loop_exit *exit;
1073
1076
1077 for (exit = loop->exits->next; exit->e; exit = exit->next)
1078 {
1079 int i;
1080 edge e;
1081 bool was_dest = false;
1082
1083 for (i = 0; edges.iterate (i, &e); i++)
1084 if (e->dest == exit->e->dest)
1085 {
1086 was_dest = true;
1087 break;
1088 }
1089
1090 if (!was_dest)
1091 edges.safe_push (exit->e);
1092 }
1093 return edges;
1094}
1095
1096inline bool
1098{
1099 insn_t first = sel_bb_head (bb), last;
1100
1101 if (first == NULL_RTX)
1102 return true;
1103
1104 if (!INSN_NOP_P (first))
1105 return false;
1106
1107 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
1108 return false;
1109
1110 last = sel_bb_end (bb);
1111 if (first != last)
1112 return false;
1113
1114 return true;
1115}
1116
1117/* Collect all loop exits recursively, skipping empty BBs between them.
1118 E.g. if BB is a loop header which has several loop exits,
1119 traverse all of them and if any of them turns out to be another loop header
1120 (after skipping empty BBs), add its loop exits to the resulting vector
1121 as well. */
1122inline vec<edge>
1124{
1125 vec<edge> exits = vNULL;
1126
1127 /* If bb is empty, and we're skipping to loop exits, then
1128 consider bb as a possible gate to the inner loop now. */
1129 while (sel_bb_empty_or_nop_p (bb)
1130 && in_current_region_p (bb)
1131 && EDGE_COUNT (bb->succs) > 0)
1132 {
1133 bb = single_succ (bb);
1134
1135 /* This empty block could only lead outside the region. */
1137 }
1138
1139 /* And now check whether we should skip over inner loop. */
1140 if (inner_loop_header_p (bb))
1141 {
1142 class loop *this_loop;
1143 class loop *pred_loop = NULL;
1144 int i;
1145 unsigned this_depth;
1146 edge e;
1147
1148 for (this_loop = bb->loop_father;
1149 this_loop && this_loop != current_loop_nest;
1150 this_loop = loop_outer (this_loop))
1151 pred_loop = this_loop;
1152
1153 this_loop = pred_loop;
1154 gcc_assert (this_loop != NULL);
1155
1157 this_depth = loop_depth (this_loop);
1158
1159 /* Traverse all loop headers. Be careful not to go back
1160 to the outer loop's header (see PR 84206). */
1161 for (i = 0; exits.iterate (i, &e); i++)
1162 if ((in_current_region_p (e->dest)
1163 || (inner_loop_header_p (e->dest)))
1164 && loop_depth (e->dest->loop_father) >= this_depth)
1165 {
1166 auto_vec<edge> next_exits = get_all_loop_exits (e->dest);
1167
1168 if (next_exits.exists ())
1169 {
1170 int j;
1171 edge ne;
1172
1173 /* Add all loop exits for the current edge into the
1174 resulting vector. */
1175 for (j = 0; next_exits.iterate (j, &ne); j++)
1176 exits.safe_push (ne);
1177
1178 /* Remove the original edge. */
1179 exits.ordered_remove (i);
1180
1181 /* Decrease the loop counter so we won't skip anything. */
1182 i--;
1183 continue;
1184 }
1185 }
1186 }
1187
1188 return exits;
1189}
1190
1191/* Flags to pass to compute_succs_info and FOR_EACH_SUCC.
1192 Any successor will fall into exactly one category. */
1193
1194/* Include normal successors. */
1195#define SUCCS_NORMAL (1)
1196
1197/* Include back-edge successors. */
1198#define SUCCS_BACK (2)
1199
1200/* Include successors that are outside of the current region. */
1201#define SUCCS_OUT (4)
1202
1203/* When pipelining of the outer loops is enabled, skip innermost loops
1204 to their exits. */
1205#define SUCCS_SKIP_TO_LOOP_EXITS (8)
1206
1207/* Include all successors. */
1208#define SUCCS_ALL (SUCCS_NORMAL | SUCCS_BACK | SUCCS_OUT)
1209
1210/* We need to return a succ_iterator to avoid 'uninitialized' warning
1211 during bootstrap. */
1212inline succ_iterator
1213_succ_iter_start (insn_t *succp, insn_t insn, int flags)
1214{
1216
1217 basic_block bb = BLOCK_FOR_INSN (insn);
1218
1219 gcc_assert (INSN_P (insn) || NOTE_INSN_BASIC_BLOCK_P (insn));
1220
1221 i.flags = flags;
1222
1223 /* Avoid 'uninitialized' warning. */
1224 *succp = NULL;
1225 i.e1 = NULL;
1226 i.e2 = NULL;
1227 i.bb = bb;
1228 i.current_flags = 0;
1229 i.current_exit = -1;
1230 i.loop_exits.create (0);
1231
1232 if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun) && BB_END (bb) != insn)
1233 {
1234 i.bb_end = false;
1235
1236 /* Avoid 'uninitialized' warning. */
1237 i.ei.index = 0;
1238 i.ei.container = 0;
1239 }
1240 else
1241 {
1242 i.ei = ei_start (bb->succs);
1243 i.bb_end = true;
1244 }
1245
1246 return i;
1247}
1248
1249inline bool
1251 bool check (edge, succ_iterator *))
1252{
1253 if (!ip->bb_end)
1254 {
1255 /* When we're in a middle of a basic block, return
1256 the next insn immediately, but only when SUCCS_NORMAL is set. */
1257 if (*succp != NULL || (ip->flags & SUCCS_NORMAL) == 0)
1258 return false;
1259
1260 *succp = NEXT_INSN (insn);
1262 return true;
1263 }
1264 else
1265 {
1266 while (1)
1267 {
1268 edge e_tmp = NULL;
1269
1270 /* First, try loop exits, if we have them. */
1271 if (ip->loop_exits.exists ())
1272 {
1273 do
1274 {
1275 ip->loop_exits.iterate (ip->current_exit, &e_tmp);
1276 ip->current_exit++;
1277 }
1278 while (e_tmp && !check (e_tmp, ip));
1279
1280 if (!e_tmp)
1281 ip->loop_exits.release ();
1282 }
1283
1284 /* If we have found a successor, then great. */
1285 if (e_tmp)
1286 {
1287 ip->e1 = e_tmp;
1288 break;
1289 }
1290
1291 /* If not, then try the next edge. */
1292 while (ei_cond (ip->ei, &(ip->e1)))
1293 {
1294 basic_block bb = ip->e1->dest;
1295
1296 /* Consider bb as a possible loop header. */
1298 && flag_sel_sched_pipelining_outer_loops
1299 && (!in_current_region_p (bb)
1300 || BLOCK_TO_BB (ip->bb->index)
1301 < BLOCK_TO_BB (bb->index)))
1302 {
1303 /* Get all loop exits recursively. */
1304 ip->loop_exits = get_all_loop_exits (bb);
1305
1306 if (ip->loop_exits.exists ())
1307 {
1308 ip->current_exit = 0;
1309 /* Move the iterator now, because we won't do
1310 succ_iter_next until loop exits will end. */
1311 ei_next (&(ip->ei));
1312 break;
1313 }
1314 }
1315
1316 /* bb is not a loop header, check as usual. */
1317 if (check (ip->e1, ip))
1318 break;
1319
1320 ei_next (&(ip->ei));
1321 }
1322
1323 /* If loop_exits are non null, we have found an inner loop;
1324 do one more iteration to fetch an edge from these exits. */
1325 if (ip->loop_exits.exists ())
1326 continue;
1327
1328 /* Otherwise, we've found an edge in a usual way. Break now. */
1329 break;
1330 }
1331
1332 if (ip->e1)
1333 {
1334 basic_block bb = ip->e2->dest;
1335
1336 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || bb == after_recovery)
1337 *succp = exit_insn;
1338 else
1339 {
1340 *succp = sel_bb_head (bb);
1341
1343 || *succp == NEXT_INSN (bb_note (bb)));
1344 gcc_assert (BLOCK_FOR_INSN (*succp) == bb);
1345 }
1346
1347 return true;
1348 }
1349 else
1350 return false;
1351 }
1352}
1353
1354inline void
1356{
1357 gcc_assert (!ip->e2 || ip->e1);
1358
1359 if (ip->bb_end && ip->e1 && !ip->loop_exits.exists ())
1360 ei_next (&(ip->ei));
1361}
1362
1363/* Returns true when E1 is an eligible successor edge, possibly skipping
1364 empty blocks. When E2P is not null, the resulting edge is written there.
1365 FLAGS are used to specify whether back edges and out-of-region edges
1366 should be considered. */
1367inline bool
1369{
1370 edge e2 = e1;
1371 basic_block bb;
1372 int flags = ip->flags;
1373 bool src_outside_rgn = !in_current_region_p (e1->src);
1374
1375 gcc_assert (flags != 0);
1376
1377 if (src_outside_rgn)
1378 {
1379 /* Any successor of the block that is outside current region is
1380 ineligible, except when we're skipping to loop exits. */
1382
1383 if (flags & SUCCS_OUT)
1384 return false;
1385 }
1386
1387 bb = e2->dest;
1388
1389 /* Skip empty blocks, but be careful not to leave the region. */
1390 while (1)
1391 {
1392 if (!sel_bb_empty_p (bb))
1393 {
1394 edge ne;
1395 basic_block nbb;
1396
1397 if (!sel_bb_empty_or_nop_p (bb))
1398 break;
1399
1400 ne = EDGE_SUCC (bb, 0);
1401 nbb = ne->dest;
1402
1403 if (!in_current_region_p (nbb)
1404 && !(flags & SUCCS_OUT))
1405 break;
1406
1407 e2 = ne;
1408 bb = nbb;
1409 continue;
1410 }
1411
1412 if (!in_current_region_p (bb)
1413 && !(flags & SUCCS_OUT))
1414 return false;
1415
1416 if (EDGE_COUNT (bb->succs) == 0)
1417 return false;
1418
1419 e2 = EDGE_SUCC (bb, 0);
1420 bb = e2->dest;
1421 }
1422
1423 /* Save the second edge for later checks. */
1424 ip->e2 = e2;
1425
1426 if (in_current_region_p (bb))
1427 {
1428 /* BLOCK_TO_BB sets topological order of the region here.
1429 It is important to use real predecessor here, which is ip->bb,
1430 as we may well have e1->src outside current region,
1431 when skipping to loop exits. */
1432 bool succeeds_in_top_order = (BLOCK_TO_BB (ip->bb->index)
1433 < BLOCK_TO_BB (bb->index));
1434
1435 /* This is true for the all cases except the last one. */
1437
1438 /* We are advancing forward in the region, as usual. */
1439 if (succeeds_in_top_order)
1440 {
1441 /* We are skipping to loop exits here. */
1442 gcc_assert (!src_outside_rgn
1443 || flag_sel_sched_pipelining_outer_loops);
1444 return !!(flags & SUCCS_NORMAL);
1445 }
1446
1447 /* This is a back edge. During pipelining we ignore back edges,
1448 but only when it leads to the same loop. It can lead to the header
1449 of the outer loop, which will also be the preheader of
1450 the current loop. */
1451 if (pipelining_p
1452 && e1->src->loop_father == bb->loop_father)
1453 return !!(flags & SUCCS_NORMAL);
1454
1455 /* A back edge should be requested explicitly. */
1457 return !!(flags & SUCCS_BACK);
1458 }
1459
1461 return !!(flags & SUCCS_OUT);
1462}
1463
1464#define FOR_EACH_SUCC_1(SUCC, ITER, INSN, FLAGS) \
1465 for ((ITER) = _succ_iter_start (&(SUCC), (INSN), (FLAGS)); \
1466 _succ_iter_cond (&(ITER), &(SUCC), (INSN), _eligible_successor_edge_p); \
1467 _succ_iter_next (&(ITER)))
1468
1469#define FOR_EACH_SUCC(SUCC, ITER, INSN) \
1470 FOR_EACH_SUCC_1 (SUCC, ITER, INSN, SUCCS_NORMAL)
1471
1472/* Return the current edge along which a successor was built. */
1473#define SUCC_ITER_EDGE(ITER) ((ITER)->e1)
1474
1475/* Return the next block of BB not running into inconsistencies. */
1476inline basic_block
1478{
1479 switch (EDGE_COUNT (bb->succs))
1480 {
1481 case 0:
1482 return bb->next_bb;
1483
1484 case 1:
1485 return single_succ (bb);
1486
1487 case 2:
1488 return FALLTHRU_EDGE (bb)->dest;
1489
1490 default:
1491 return bb->next_bb;
1492 }
1493}
1494
1495
1496
1497/* Functions that are used in sel-sched.cc. */
1498
1499/* List functions. */
1502extern void blist_add (blist_t *, insn_t, ilist_t, deps_t);
1503extern void blist_remove (blist_t *);
1505
1507extern void flist_clear (flist_t *);
1508extern void def_list_add (def_list_t *, insn_t, unsigned int);
1509
1510/* Target context functions. */
1513extern void reset_target_context (tc_t, bool);
1514
1515/* Deps context functions. */
1516extern void advance_deps_context (deps_t, insn_t);
1517
1518/* Fences functions. */
1519extern void init_fences (insn_t);
1523
1524/* Pool functions. */
1528extern void free_regset_pool (void);
1529
1531extern void return_nop_to_pool (insn_t, bool);
1532extern void free_nop_pool (void);
1533
1534/* Vinsns functions. */
1543extern void vinsn_attach (vinsn_t);
1544extern void vinsn_detach (vinsn_t);
1547
1548/* EXPR functions. */
1549extern void copy_expr (expr_t, expr_t);
1553extern void clear_expr (expr_t);
1554extern unsigned expr_dest_regno (expr_t);
1557 rtx, vinsn_t, bool);
1559 unsigned, enum local_trans_type,
1560 vinsn_t, vinsn_t, ds_t);
1562extern int speculate_expr (expr_t, ds_t);
1563
1564/* Av set functions. */
1565extern void av_set_add (av_set_t *, expr_t);
1573extern void av_set_clear (av_set_t *);
1577extern void av_set_split_usefulness (av_set_t, int, int);
1579
1580extern void sel_save_haifa_priorities (void);
1581
1582extern void sel_init_global_and_expr (bb_vec_t);
1584
1587
1588/* Dependence analysis functions. */
1589extern void sel_clear_has_dependence (void);
1590extern ds_t has_dependence_p (expr_t, insn_t, ds_t **);
1591
1592extern int tick_check_p (expr_t, deps_t, fence_t);
1593
1594/* Functions to work with insns. */
1597extern void get_dest_and_mode (rtx, rtx *, machine_mode *);
1598
1600extern bool sel_remove_insn (insn_t, bool, bool);
1601extern bool bb_header_p (insn_t);
1604
1605/* Basic block and CFG functions. */
1606
1608extern bool sel_bb_head_p (insn_t);
1610extern bool sel_bb_end_p (insn_t);
1611extern bool sel_bb_empty_p (basic_block);
1612
1613extern bool in_current_region_p (basic_block);
1615
1616extern void sel_init_bbs (bb_vec_t);
1617extern void sel_finish_bbs (void);
1618
1619extern struct succs_info * compute_succs_info (insn_t, short);
1620extern void free_succs_info (struct succs_info *);
1624
1627
1628extern bool tidy_control_flow (basic_block, bool);
1629extern void free_bb_note_pool (void);
1630
1631extern void purge_empty_blocks (void);
1636extern void sel_init_pipelining (void);
1637extern void sel_finish_pipelining (void);
1638extern void sel_sched_region (int);
1639extern loop_p get_loop_nest_for_rgn (unsigned int);
1640extern bool considered_for_pipelining_p (class loop *);
1642extern void sel_add_loop_preheaders (bb_vec_t *);
1648
1649extern void sel_register_cfg_hooks (void);
1650extern void sel_unregister_cfg_hooks (void);
1651
1652/* Expression transformation routines. */
1657
1658/* Various initialization functions. */
1659extern void init_lv_sets (void);
1660extern void free_lv_sets (void);
1661extern void setup_nop_and_exit_insns (void);
1662extern void free_nop_and_exit_insns (void);
1664extern void setup_nop_vinsn (void);
1665extern void free_nop_vinsn (void);
1666extern void sel_set_sched_flags (void);
1667extern void sel_setup_sched_infos (void);
1668extern void alloc_sched_pools (void);
1669extern void free_sched_pools (void);
1670
1671#endif /* GCC_SEL_SCHED_IR_H */
#define EDGE_COUNT(ev)
Definition basic-block.h:300
#define ei_start(iter)
Definition basic-block.h:373
basic_block single_succ(const_basic_block bb)
Definition basic-block.h:345
#define EDGE_SUCC(bb, i)
Definition basic-block.h:303
#define BB_END(B)
Definition basic-block.h:255
bool ei_cond(edge_iterator ei, edge *p)
Definition basic-block.h:453
#define FALLTHRU_EDGE(bb)
Definition basic-block.h:286
#define EXIT_BLOCK_PTR_FOR_FN(FN)
Definition basic-block.h:195
void ei_next(edge_iterator *i)
Definition basic-block.h:418
bool flow_bb_inside_loop_p(const class loop *loop, const_basic_block bb)
Definition cfgloop.cc:838
class loop * loop_outer(const class loop *loop)
Definition cfgloop.h:547
unsigned loop_depth(const class loop *loop)
Definition cfgloop.h:538
class loop * loop_p
Definition cfgloop.h:98
@ LOOPS_HAVE_RECORDED_EXITS
Definition cfgloop.h:312
rtx_note * bb_note(basic_block bb)
Definition cfgrtl.cc:698
Definition sel-sched-ir.h:714
bitmap found_deps
Definition sel-sched-ir.h:735
bitmap originators
Definition sel-sched-ir.h:740
int seqno
Definition sel-sched-ir.h:724
insn_t sched_next
Definition sel-sched-ir.h:752
BOOL_BITFIELD asm_p
Definition sel-sched-ir.h:767
BOOL_BITFIELD live_valid_p
Definition sel-sched-ir.h:765
expr_def expr
Definition sel-sched-ir.h:718
bitmap analyzed_deps
Definition sel-sched-ir.h:730
int sched_cycle
Definition sel-sched-ir.h:756
class deps_desc deps_context
Definition sel-sched-ir.h:746
htab_t transformed_insns
Definition sel-sched-ir.h:743
int ready_cycle
Definition sel-sched-ir.h:759
ds_t spec_checked_ds
Definition sel-sched-ir.h:762
int ws_level
Definition sel-sched-ir.h:721
BOOL_BITFIELD after_stall_p
Definition sel-sched-ir.h:772
regset live
Definition sel-sched-ir.h:727
Definition vec.h:1667
Definition bitmap.h:330
Definition cfgloop.h:120
basic_block latch
Definition cfgloop.h:133
struct loop_exit * exits
Definition cfgloop.h:268
basic_block header
Definition cfgloop.h:130
Definition alloc-pool.h:482
struct basic_block_def * basic_block
Definition coretypes.h:348
struct rtx_def * rtx
Definition coretypes.h:57
class edge_def * edge
Definition coretypes.h:345
struct simple_bitmap_def * sbitmap
Definition coretypes.h:54
class bitmap_head * bitmap
Definition coretypes.h:51
#define current_loops
Definition function.h:549
#define cfun
Definition function.h:485
struct state * state_t
Definition genautomata.cc:195
static struct filedep ** last
Definition genmddeps.cc:33
i
Definition poly-int.h:776
bitmap regset
Definition regset.h:38
#define INSN_P(X)
Definition rtl.h:869
basic_block BLOCK_FOR_INSN(const_rtx insn)
Definition rtl.h:1498
#define NULL_RTX
Definition rtl.h:706
rtx_insn * NEXT_INSN(const rtx_insn *insn)
Definition rtl.h:1487
#define NOTE_INSN_BASIC_BLOCK_P(INSN)
Definition rtl.h:1702
bool considered_for_pipelining_p(class loop *)
_list_t ilist_t
Definition sel-sched-ir.h:55
void av_set_iter_remove(av_set_iterator *)
bool _list_iter_cond_def(def_list_t def_list, def_t *def)
Definition sel-sched-ir.h:575
vec< sel_insn_data_def > s_i_d
int speculate_expr(expr_t, ds_t)
deps_where_t
Definition sel-sched-ir.h:876
@ DEPS_IN_LHS
Definition sel-sched-ir.h:878
@ DEPS_IN_INSN
Definition sel-sched-ir.h:877
@ DEPS_IN_NOWHERE
Definition sel-sched-ir.h:880
@ DEPS_IN_RHS
Definition sel-sched-ir.h:879
bool sel_is_loop_preheader_p(basic_block)
void exchange_data_sets(basic_block, basic_block)
void get_dest_and_mode(rtx, rtx *, machine_mode *)
void init_lv_sets(void)
void sel_redirect_edge_and_branch_force(edge, basic_block)
bool register_unavailable_p(regset, rtx)
bool in_same_ebb_p(insn_t, insn_t)
void av_set_union_and_live(av_set_t *, av_set_t *, regset, regset, insn_t)
bool _list_iter_cond_expr(av_set_t av, expr_t *exprp)
Definition sel-sched-ir.h:553
bool ilist_is_in_p(ilist_t l, insn_t insn)
Definition sel-sched-ir.h:515
void clear_expr(expr_t)
vec< edge > get_all_loop_exits(basic_block bb)
Definition sel-sched-ir.h:1123
void sel_sched_region(int)
expr_def * expr_t
Definition sel-sched-ir.h:157
void change_vinsn_in_expr(expr_t, vinsn_t)
void flist_tail_init(flist_tail_t)
unsigned expr_dest_regno(expr_t)
int global_level
vec< sel_region_bb_info_def > sel_region_bb_info
int tick_check_p(expr_t, deps_t, fence_t)
bool _eligible_successor_edge_p(edge e1, succ_iterator *ip)
Definition sel-sched-ir.h:1368
void _list_iter_next(_list_iterator *ip)
Definition sel-sched-ir.h:421
void av_set_code_motion_filter(av_set_t *, av_set_t)
void _xlist_add(_xlist_t *lp, rtx x)
Definition sel-sched-ir.h:461
void av_set_leave_one_nonspec(av_set_t *)
#define ILIST_NEXT(L)
Definition sel-sched-ir.h:57
#define SUCCS_SKIP_TO_LOOP_EXITS
Definition sel-sched-ir.h:1205
fence_t flist_lookup(flist_t, insn_t)
bool bookkeeping_can_be_created_if_moved_through_p(insn_t)
regset sel_all_regs
void _list_clear(_list_t *l)
Definition sel-sched-ir.h:392
void alloc_sched_pools(void)
bool sel_bb_empty_p(basic_block)
void setup_nop_vinsn(void)
expr_t av_set_lookup(av_set_t, vinsn_t)
struct expr_history_def_1 expr_history_def
Definition sel-sched-ir.h:87
#define SUCCS_OUT
Definition sel-sched-ir.h:1201
bool bookkeeping_p
void sel_finish_global_bb_info(void)
vec< sel_global_bb_info_def > sel_global_bb_info
void set_target_context(tc_t)
void sel_save_haifa_priorities(void)
bool tidy_control_flow(basic_block, bool)
insn_t sel_gen_insn_from_expr_after(expr_t, vinsn_t, int, insn_t)
void add_dirty_fence_to_fences(flist_tail_t, insn_t, fence_t)
sbitmap bbs_pipelined
class loop * current_loop_nest
regset compute_live(insn_t)
insn_t get_nop_from_pool(insn_t)
insn_t sel_gen_recovery_insn_from_rtx_after(rtx, expr_t, int, insn_t)
struct flist_tail_def * flist_tail_t
Definition sel-sched-ir.h:332
void free_lv_sets(void)
void sel_add_loop_preheaders(bb_vec_t *)
bool _succ_iter_cond(succ_iterator *ip, insn_t *succp, insn_t insn, bool check(edge, succ_iterator *))
Definition sel-sched-ir.h:1250
local_trans_type
Definition sel-sched-ir.h:62
@ TRANS_SUBSTITUTION
Definition sel-sched-ir.h:63
@ TRANS_SPECULATION
Definition sel-sched-ir.h:64
int get_av_level(insn_t)
#define INSN_NOP_P(INSN)
Definition sel-sched-ir.h:846
sel_global_bb_info_def * sel_global_bb_info_t
Definition sel-sched-ir.h:899
bool enable_moveup_set_path_p
struct _fence * fence_t
Definition sel-sched-ir.h:300
sel_insn_data_def * sel_insn_data_t
Definition sel-sched-ir.h:776
bool sel_bb_head_p(insn_t)
basic_block after_recovery
void init_fences(insn_t)
object_allocator< _list_node > sched_lists_pool
void sel_extend_global_bb_info(void)
rtx_insn * insn_t
Definition sel-sched-ir.h:52
vinsn_t vinsn_copy(vinsn_t, bool)
bool sel_remove_insn(insn_t, bool, bool)
bool vinsn_separable_p(vinsn_t)
#define _LIST_NEXT(L)
Definition sel-sched-ir.h:35
void return_regset_to_pool(regset)
void av_set_union_and_clear(av_set_t *, av_set_t *, insn_t)
void _list_remove(_list_t *lp)
Definition sel-sched-ir.h:383
void sel_init_pipelining(void)
bool sel_num_cfg_preds_gt_1(insn_t)
#define _AV_SET_EXPR(L)
Definition sel-sched-ir.h:200
void move_fence_to_fences(flist_t, flist_tail_t)
bool av_set_is_in_p(av_set_t, vinsn_t)
_list_t flist_t
Definition sel-sched-ir.h:321
struct succs_info * compute_succs_info(insn_t, short)
regset get_clear_regset_from_pool(void)
void _list_iter_remove(_list_iterator *ip)
Definition sel-sched-ir.h:430
tc_t create_target_context(bool)
vec< edge > get_loop_exit_edges_unique_dests(const class loop *loop)
Definition sel-sched-ir.h:1069
void free_nop_vinsn(void)
void reset_target_context(tc_t, bool)
void * tc_t
Definition sel-sched-ir.h:26
void return_nop_to_pool(insn_t, bool)
void free_data_for_scheduled_insn(insn_t)
succ_iterator _succ_iter_start(insn_t *succp, insn_t insn, int flags)
Definition sel-sched-ir.h:1213
void flist_clear(flist_t *)
void add_clean_fence_to_fences(flist_tail_t, insn_t, fence_t)
bool vinsn_cond_branch_p(vinsn_t)
int max_insns_to_rename
void blist_add(blist_t *, insn_t, ilist_t, deps_t)
void av_set_substract_cond_branches(av_set_t *)
regset get_regset_from_pool(void)
rtx_insn * create_copy_of_insn_rtx(rtx)
bool sel_bb_end_p(insn_t)
void _list_remove_nofree(_list_t *lp)
Definition sel-sched-ir.h:375
bool in_current_region_p(basic_block)
void recompute_vinsn_lhs_rhs(vinsn_t)
void sel_unregister_cfg_hooks(void)
void blist_remove(blist_t *)
bool bb_header_p(insn_t)
#define DEF_LIST_DEF(L)
Definition sel-sched-ir.h:570
bool inner_loop_header_p(basic_block bb)
Definition sel-sched-ir.h:1041
rtx nop_pattern
void free_nop_pool(void)
struct vinsn_def * vinsn_t
Definition sel-sched-ir.h:43
void sel_register_cfg_hooks(void)
void copy_data_sets(basic_block, basic_block)
av_set_t av_set_copy(av_set_t)
void ilist_add(ilist_t *lp, insn_t insn)
Definition sel-sched-ir.h:506
void free_regset_pool(void)
void merge_expr_data(expr_t, expr_t, insn_t)
bool _xlist_is_in_p(_xlist_t l, rtx x)
Definition sel-sched-ir.h:471
#define _XLIST_NEXT(L)
Definition sel-sched-ir.h:49
av_set_t get_av_set(insn_t)
int get_seqno_by_preds(rtx_insn *)
void vinsn_attach(vinsn_t)
void sel_init_invalid_data_sets(insn_t)
bool sel_insn_has_single_succ_p(insn_t, int)
basic_block sel_create_recovery_block(insn_t)
void free_data_sets(basic_block)
bool insn_at_boundary_p(insn_t)
ds_t has_dependence_p(expr_t, insn_t, ds_t **)
sel_region_bb_info_def * sel_region_bb_info_t
Definition sel-sched-ir.h:931
insn_t sel_gen_insn_from_rtx_after(rtx, expr_t, int, insn_t)
bool lhs_of_insn_equals_to_dest_p(insn_t, rtx)
loop_p get_loop_nest_for_rgn(unsigned int)
_list_t av_set_t
Definition sel-sched-ir.h:199
struct _def * def_t
Definition sel-sched-ir.h:195
void sel_set_sched_flags(void)
bool bb_ends_ebb_p(basic_block)
void av_set_split_usefulness(av_set_t, int, int)
bool insn_eligible_for_subst_p(insn_t)
expr_t merge_with_other_exprs(av_set_t *, av_set_iterator *, expr_t)
void insert_in_history_vect(vec< expr_history_def > *, unsigned, enum local_trans_type, vinsn_t, vinsn_t, ds_t)
_list_iterator def_list_iterator
Definition sel-sched-ir.h:567
void sel_init_global_and_expr(bb_vec_t)
ilist_t ilist_invert(ilist_t)
_list_iterator _xlist_iterator
Definition sel-sched-ir.h:498
void free_sched_pools(void)
void free_succs_info(struct succs_info *)
ilist_t ilist_copy(ilist_t)
void free_bb_note_pool(void)
void sel_finish_global_and_expr(void)
void merge_expr(expr_t, expr_t, insn_t)
void sel_finish_bbs(void)
expr_t av_set_element(av_set_t, int)
void purge_empty_blocks(void)
void copy_expr_onside(expr_t, expr_t)
bool _list_iter_cond_insn(ilist_t l, insn_t *ip)
Definition sel-sched-ir.h:529
void sel_clear_has_dependence(void)
bool sel_redirect_edge_and_branch(edge, basic_block)
void av_set_add(av_set_t *, expr_t)
class _sel_insn_data sel_insn_data_def
Definition sel-sched-ir.h:775
#define ILIST_INSN(L)
Definition sel-sched-ir.h:56
void def_list_add(def_list_t *, insn_t, unsigned int)
void clear_outdated_rtx_info(basic_block)
_list_t _xlist_t
Definition sel-sched-ir.h:47
struct _bnd * bnd_t
Definition sel-sched-ir.h:224
void sel_init_bbs(bb_vec_t)
void copy_expr(expr_t, expr_t)
bool sel_bb_empty_or_nop_p(basic_block bb)
Definition sel-sched-ir.h:1097
_list_iterator av_set_iterator
Definition sel-sched-ir.h:548
void _succ_iter_next(succ_iterator *ip)
Definition sel-sched-ir.h:1355
#define SUCCS_NORMAL
Definition sel-sched-ir.h:1195
sel_insn_data_def insn_sid(insn_t)
flist_t fences
rtx_insn * exit_insn
_list_t def_list_t
Definition sel-sched-ir.h:566
#define _XLIST_X(L)
Definition sel-sched-ir.h:48
_list_t blist_t
Definition sel-sched-ir.h:235
basic_block fallthru_bb_of_jump(const rtx_insn *)
bool vinsn_equal_p(vinsn_t, vinsn_t)
void sel_setup_sched_infos(void)
void vinsn_detach(vinsn_t)
rtx_insn * sel_bb_end(basic_block)
void setup_nop_and_exit_insns(void)
void sel_finish_pipelining(void)
bool preheader_removed
vinsn_t create_vinsn_from_insn_rtx(rtx_insn *, bool)
void _list_iter_start(_list_iterator *ip, _list_t *lp, bool can_remove_p)
Definition sel-sched-ir.h:413
void advance_deps_context(deps_t, insn_t)
_list_iterator ilist_iterator
Definition sel-sched-ir.h:542
rtx_insn * sel_bb_head(basic_block)
void av_set_clear(av_set_t *)
int sel_vinsn_cost(vinsn_t)
void _list_iter_remove_nofree(_list_iterator *ip)
Definition sel-sched-ir.h:438
void _list_add(_list_t *lp)
Definition sel-sched-ir.h:366
#define SUCCS_BACK
Definition sel-sched-ir.h:1198
basic_block sel_split_edge(edge)
bool pipelining_p
struct _list_node * _list_t
Definition sel-sched-ir.h:34
struct idata_def * idata_t
Definition sel-sched-ir.h:39
rtx_insn * create_insn_rtx_from_pattern(rtx, rtx)
bitmap blocks_to_reschedule
bitmap_head * forced_ebb_heads
void free_nop_and_exit_insns(void)
basic_block bb_next_bb(basic_block bb)
Definition sel-sched-ir.h:1477
void make_region_from_loop_preheader(vec< basic_block > *&)
rtx expr_dest_reg(expr_t)
_list_t _list_alloc(void)
Definition sel-sched-ir.h:360
int find_in_history_vect(vec< expr_history_def >, rtx, vinsn_t, bool)
struct _expr expr_def
Definition sel-sched-ir.h:156
insn_t sel_move_insn(expr_t, int, insn_t)
void mark_unavailable_targets(av_set_t, av_set_t, regset)
bool _list_iter_cond_x(_xlist_t l, rtx *xp)
Definition sel-sched-ir.h:485
Definition sel-sched-ir.h:206
av_set_t av1
Definition sel-sched-ir.h:217
insn_t to
Definition sel-sched-ir.h:208
av_set_t av
Definition sel-sched-ir.h:214
ilist_t ptr
Definition sel-sched-ir.h:211
deps_t dc
Definition sel-sched-ir.h:222
Definition sel-sched-ir.h:185
insn_t orig_insn
Definition sel-sched-ir.h:186
unsigned int crossed_call_abis
Definition sel-sched-ir.h:193
Definition sel-sched-ir.h:92
BOOL_BITFIELD needs_spec_check_p
Definition sel-sched-ir.h:143
int spec
Definition sel-sched-ir.h:101
ds_t spec_done_ds
Definition sel-sched-ir.h:123
int orig_bb_index
Definition sel-sched-ir.h:119
signed char target_available
Definition sel-sched-ir.h:139
vec< expr_history_def > history_of_changes
Definition sel-sched-ir.h:134
ds_t spec_to_check_ds
Definition sel-sched-ir.h:127
int priority_adj
Definition sel-sched-ir.h:112
int sched_times
Definition sel-sched-ir.h:115
int usefulness
Definition sel-sched-ir.h:106
BOOL_BITFIELD was_renamed
Definition sel-sched-ir.h:150
vinsn_t vinsn
Definition sel-sched-ir.h:94
int priority
Definition sel-sched-ir.h:109
int orig_sched_cycle
Definition sel-sched-ir.h:131
BOOL_BITFIELD was_substituted
Definition sel-sched-ir.h:147
BOOL_BITFIELD cant_move
Definition sel-sched-ir.h:153
Definition sel-sched-ir.h:243
ilist_t bnds
Definition sel-sched-ir.h:259
int ready_ticks_size
Definition sel-sched-ir.h:277
insn_t insn
Definition sel-sched-ir.h:245
int cycle
Definition sel-sched-ir.h:251
tc_t tc
Definition sel-sched-ir.h:267
rtx_insn * sched_next
Definition sel-sched-ir.h:286
int * ready_ticks
Definition sel-sched-ir.h:274
BOOL_BITFIELD scheduled_p
Definition sel-sched-ir.h:292
rtx_insn * last_scheduled_insn
Definition sel-sched-ir.h:280
BOOL_BITFIELD processed_p
Definition sel-sched-ir.h:289
deps_t dc
Definition sel-sched-ir.h:263
BOOL_BITFIELD starts_cycle_p
Definition sel-sched-ir.h:295
int issue_more
Definition sel-sched-ir.h:283
vec< rtx_insn *, va_gc > * executing_insns
Definition sel-sched-ir.h:270
state_t state
Definition sel-sched-ir.h:248
BOOL_BITFIELD after_stall_p
Definition sel-sched-ir.h:298
int cycle_issued_insns
Definition sel-sched-ir.h:255
Definition sel-sched-ir.h:401
bool removed_p
Definition sel-sched-ir.h:409
_list_t * lp
Definition sel-sched-ir.h:403
bool can_remove_p
Definition sel-sched-ir.h:406
Definition sel-sched-ir.h:338
void * data
Definition sel-sched-ir.h:349
insn_t insn
Definition sel-sched-ir.h:344
struct _fence fence
Definition sel-sched-ir.h:347
_list_t next
Definition sel-sched-ir.h:339
rtx x
Definition sel-sched-ir.h:343
struct _def def
Definition sel-sched-ir.h:348
union _list_node::@270251122236364104100307341173245104044375370020 u
expr_def expr
Definition sel-sched-ir.h:346
struct _bnd bnd
Definition sel-sched-ir.h:345
vec< edge, va_gc > * succs
Definition basic-block.h:120
basic_block next_bb
Definition basic-block.h:133
class loop * loop_father
Definition basic-block.h:126
int index
Definition basic-block.h:147
Definition loop-invariant.cc:88
Definition basic-block.h:361
Definition sel-sched-ir.h:70
enum local_trans_type type
Definition sel-sched-ir.h:84
ds_t spec_ds
Definition sel-sched-ir.h:81
vinsn_t old_expr_vinsn
Definition sel-sched-ir.h:75
unsigned uid
Definition sel-sched-ir.h:72
vinsn_t new_expr_vinsn
Definition sel-sched-ir.h:78
Definition sel-sched-ir.h:327
flist_t head
Definition sel-sched-ir.h:328
flist_t * tailp
Definition sel-sched-ir.h:329
Definition sel-sched-ir.h:589
regset reg_uses
Definition sel-sched-ir.h:621
int type
Definition sel-sched-ir.h:600
rtx rhs
Definition sel-sched-ir.h:606
regset reg_sets
Definition sel-sched-ir.h:617
rtx lhs
Definition sel-sched-ir.h:603
regset reg_clobbers
Definition sel-sched-ir.h:619
Definition cfgloop.h:77
struct loop_exit * next
Definition cfgloop.h:83
edge e
Definition cfgloop.h:79
Definition rtl.h:546
Definition sel-sched-ir.h:886
regset lv_set
Definition sel-sched-ir.h:891
bool lv_set_valid_p
Definition sel-sched-ir.h:896
Definition sel-sched-ir.h:918
av_set_t av_set
Definition sel-sched-ir.h:925
rtx_insn * note_list
Definition sel-sched-ir.h:921
int av_level
Definition sel-sched-ir.h:928
Definition sel-sched-ir.h:976
vec< edge > loop_exits
Definition sel-sched-ir.h:1002
short current_flags
Definition sel-sched-ir.h:998
bool bb_end
Definition sel-sched-ir.h:978
short flags
Definition sel-sched-ir.h:994
edge e2
Definition sel-sched-ir.h:984
basic_block bb
Definition sel-sched-ir.h:990
edge e1
Definition sel-sched-ir.h:981
int current_exit
Definition sel-sched-ir.h:1001
edge_iterator ei
Definition sel-sched-ir.h:987
Definition sel-sched-ir.h:1007
vec< int > probs_ok
Definition sel-sched-ir.h:1016
insn_vec_t succs_ok
Definition sel-sched-ir.h:1012
insn_vec_t succs_other
Definition sel-sched-ir.h:1019
int all_succs_n
Definition sel-sched-ir.h:1025
int succs_ok_n
Definition sel-sched-ir.h:1028
short flags
Definition sel-sched-ir.h:1009
int all_prob
Definition sel-sched-ir.h:1022
Definition sel-sched-ir.h:691
BOOL_BITFIELD needs_check
Definition sel-sched-ir.h:708
ds_t ds
Definition sel-sched-ir.h:699
BOOL_BITFIELD was_target_conflict
Definition sel-sched-ir.h:705
enum local_trans_type type
Definition sel-sched-ir.h:702
vinsn_t vinsn_old
Definition sel-sched-ir.h:693
vinsn_t vinsn_new
Definition sel-sched-ir.h:696
Definition vec.h:450
Definition sel-sched-ir.h:645
unsigned hash
Definition sel-sched-ir.h:654
rtx_insn * insn_rtx
Definition sel-sched-ir.h:647
bool may_trap_p
Definition sel-sched-ir.h:666
int cost
Definition sel-sched-ir.h:663
unsigned hash_rtx
Definition sel-sched-ir.h:657
struct idata_def id
Definition sel-sched-ir.h:650
int count
Definition sel-sched-ir.h:660
#define NULL
Definition system.h:50
#define gcc_assert(EXPR)
Definition system.h:817
#define BOOL_BITFIELD
Definition system.h:899
constexpr vnull vNULL
Definition vec.h:569