Node:Scheduling, Next:, Previous:Costs, Up:Target Macros



Adjusting the Instruction Scheduler

The instruction scheduler may need a fair amount of machine-specific adjustment in order to produce good code. GCC provides several target hooks for this purpose. It is usually enough to define just a few of them: try the first ones in this list first.

int TARGET_SCHED_ISSUE_RATE (void) Target Hook
This hook returns the maximum number of instructions that can ever issue at the same time on the target machine. The default is one. Although the insn scheduler can define itself the possibility of issue an insn on the same cycle, the value can serve as an additional constraint to issue insns on the same simulated processor cycle (see hooks TARGET_SCHED_REORDER and TARGET_SCHED_REORDER2). This value must be constant over the entire compilation. If you need it to vary depending on what the instructions are, you must use TARGET_SCHED_VARIABLE_ISSUE.

For the automaton based pipeline interface, you could define this hook to return the value of the macro MAX_DFA_ISSUE_RATE.

int TARGET_SCHED_VARIABLE_ISSUE (FILE *file, int verbose, rtx insn, int more) Target Hook
This hook is executed by the scheduler after it has scheduled an insn from the ready list. It should return the number of insns which can still be issued in the current cycle. The default is more - 1 for insns other than CLOBBER and USE, which normally are not counted against the issue rate. You should define this hook if some insns take more machine resources than others, so that fewer insns can follow them in the same cycle. file is either a null pointer, or a stdio stream to write any debug output to. verbose is the verbose level provided by -fsched-verbose-n. insn is the instruction that was scheduled.

int TARGET_SCHED_ADJUST_COST (rtx insn, rtx link, rtx dep_insn, int cost) Target Hook
This function corrects the value of cost based on the relationship between insn and dep_insn through the dependence link. It should return the new value. The default is to make no adjustment to cost. This can be used for example to specify to the scheduler using the traditional pipeline description that an output- or anti-dependence does not incur the same cost as a data-dependence. If the scheduler using the automaton based pipeline description, the cost of anti-dependence is zero and the cost of output-dependence is maximum of one and the difference of latency times of the first and the second insns. If these values are not acceptable, you could use the hook to modify them too. See also see Automaton pipeline description.

int TARGET_SCHED_ADJUST_PRIORITY (rtx insn, int priority) Target Hook
This hook adjusts the integer scheduling priority priority of insn. It should return the new priority. Reduce the priority to execute insn earlier, increase the priority to execute insn later. Do not define this hook if you do not need to adjust the scheduling priorities of insns.

int TARGET_SCHED_REORDER (FILE *file, int verbose, rtx *ready, int *n_readyp, int clock) Target Hook
This hook is executed by the scheduler after it has scheduled the ready list, to allow the machine description to reorder it (for example to combine two small instructions together on VLIW machines). file is either a null pointer, or a stdio stream to write any debug output to. verbose is the verbose level provided by -fsched-verbose-n. ready is a pointer to the ready list of instructions that are ready to be scheduled. n_readyp is a pointer to the number of elements in the ready list. The scheduler reads the ready list in reverse order, starting with ready[*n_readyp-1] and going to ready[0]. clock is the timer tick of the scheduler. You may modify the ready list and the number of ready insns. The return value is the number of insns that can issue this cycle; normally this is just issue_rate. See also TARGET_SCHED_REORDER2.

int TARGET_SCHED_REORDER2 (FILE *file, int verbose, rtx *ready, int *n_ready, clock) Target Hook
Like TARGET_SCHED_REORDER, but called at a different time. That function is called whenever the scheduler starts a new cycle. This one is called once per iteration over a cycle, immediately after TARGET_SCHED_VARIABLE_ISSUE; it can reorder the ready list and return the number of insns to be scheduled in the same cycle. Defining this hook can be useful if there are frequent situations where scheduling one insn causes other insns to become ready in the same cycle. These other insns can then be taken into account properly.

void TARGET_SCHED_INIT (FILE *file, int verbose, int max_ready) Target Hook
This hook is executed by the scheduler at the beginning of each block of instructions that are to be scheduled. file is either a null pointer, or a stdio stream to write any debug output to. verbose is the verbose level provided by -fsched-verbose-n. max_ready is the maximum number of insns in the current scheduling region that can be live at the same time. This can be used to allocate scratch space if it is needed, e.g. by TARGET_SCHED_REORDER.

void TARGET_SCHED_FINISH (FILE *file, int verbose) Target Hook
This hook is executed by the scheduler at the end of each block of instructions that are to be scheduled. It can be used to perform cleanup of any actions done by the other scheduling hooks. file is either a null pointer, or a stdio stream to write any debug output to. verbose is the verbose level provided by -fsched-verbose-n.

int TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE (void) Target Hook
This hook is called many times during insn scheduling. If the hook returns nonzero, the automaton based pipeline description is used for insn scheduling. Otherwise the traditional pipeline description is used. The default is usage of the traditional pipeline description.

You should also remember that to simplify the insn scheduler sources an empty traditional pipeline description interface is generated even if there is no a traditional pipeline description in the .md file. The same is true for the automaton based pipeline description. That means that you should be accurate in defining the hook.

int TARGET_SCHED_DFA_PRE_CYCLE_INSN (void) Target Hook
The hook returns an RTL insn. The automaton state used in the pipeline hazard recognizer is changed as if the insn were scheduled when the new simulated processor cycle starts. Usage of the hook may simplify the automaton pipeline description for some VLIW processors. If the hook is defined, it is used only for the automaton based pipeline description. The default is not to change the state when the new simulated processor cycle starts.

void TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN (void) Target Hook
The hook can be used to initialize data used by the previous hook.

int TARGET_SCHED_DFA_POST_CYCLE_INSN (void) Target Hook
The hook is analogous to TARGET_SCHED_DFA_PRE_CYCLE_INSN but used to changed the state as if the insn were scheduled when the new simulated processor cycle finishes.

void TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN (void) Target Hook
The hook is analogous to TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN but used to initialize data used by the previous hook.

int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD (void) Target Hook
This hook controls better choosing an insn from the ready insn queue for the DFA-based insn scheduler. Usually the scheduler chooses the first insn from the queue. If the hook returns a positive value, an additional scheduler code tries all permutations of TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD () subsequent ready insns to choose an insn whose issue will result in maximal number of issued insns on the same cycle. For the VLIW processor, the code could actually solve the problem of packing simple insns into the VLIW insn. Of course, if the rules of VLIW packing are described in the automaton.

This code also could be used for superscalar RISC processors. Let us consider a superscalar RISC processor with 3 pipelines. Some insns can be executed in pipelines A or B, some insns can be executed only in pipelines B or C, and one insn can be executed in pipeline B. The processor may issue the 1st insn into A and the 2nd one into B. In this case, the 3rd insn will wait for freeing B until the next cycle. If the scheduler issues the 3rd insn the first, the processor could issue all 3 insns per cycle.

Actually this code demonstrates advantages of the automaton based pipeline hazard recognizer. We try quickly and easy many insn schedules to choose the best one.

The default is no multipass scheduling.

void TARGET_SCHED_INIT_DFA_BUBBLES (void) Target Hook
The DFA-based scheduler could take the insertion of nop operations for better insn scheduling into account. It can be done only if the multi-pass insn scheduling works (see hook TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD).

Let us consider a VLIW processor insn with 3 slots. Each insn can be placed only in one of the three slots. We have 3 ready insns A, B, and C. A and C can be placed only in the 1st slot, B can be placed only in the 3rd slot. We described the automaton which does not permit empty slot gaps between insns (usually such description is simpler). Without this code the scheduler would place each insn in 3 separate VLIW insns. If the scheduler places a nop insn into the 2nd slot, it could place the 3 insns into 2 VLIW insns. What is the nop insn is returned by hook TARGET_SCHED_DFA_BUBBLE. Hook TARGET_SCHED_INIT_DFA_BUBBLES can be used to initialize or create the nop insns.

You should remember that the scheduler does not insert the nop insns. It is not wise because of the following optimizations. The scheduler only considers such possibility to improve the result schedule. The nop insns should be inserted lately, e.g. on the final phase.

rtx TARGET_SCHED_DFA_BUBBLE (int index) Target Hook
This hook FIRST_CYCLE_MULTIPASS_SCHEDULING is used to insert nop operations for better insn scheduling when DFA-based scheduler makes multipass insn scheduling (see also description of hook TARGET_SCHED_INIT_DFA_BUBBLES). This hook returns a nop insn with given index. The indexes start with zero. The hook should return NULL if there are no more nop insns with indexes greater than given index.

Macros in the following table are generated by the program genattr and can be useful for writing the hooks.

TRADITIONAL_PIPELINE_INTERFACE
The macro definition is generated if there is a traditional pipeline description in .md file. You should also remember that to simplify the insn scheduler sources an empty traditional pipeline description interface is generated even if there is no a traditional pipeline description in the .md file. The macro can be used to distinguish the two types of the traditional interface.
DFA_PIPELINE_INTERFACE
The macro definition is generated if there is an automaton pipeline description in .md file. You should also remember that to simplify the insn scheduler sources an empty automaton pipeline description interface is generated even if there is no an automaton pipeline description in the .md file. The macro can be used to distinguish the two types of the automaton interface.
MAX_DFA_ISSUE_RATE
The macro definition is generated in the automaton based pipeline description interface. Its value is calculated from the automaton based pipeline description and is equal to maximal number of all insns described in constructions define_insn_reservation which can be issued on the same processor cycle.