GCC Middle and Back End API Reference
reorg.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "diagnostic-core.h"
#include "rtl.h"
#include "tm_p.h"
#include "expr.h"
#include "function.h"
#include "insn-config.h"
#include "conditions.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "regs.h"
#include "recog.h"
#include "flags.h"
#include "obstack.h"
#include "insn-attr.h"
#include "resource.h"
#include "except.h"
#include "params.h"
#include "target.h"
#include "tree-pass.h"
#include "emit-rtl.h"
Include dependency graph for reorg.c:

Functions

static bool gate_handle_delay_slots ()
static unsigned int rest_of_handle_delay_slots ()
rtl_opt_passmake_pass_delay_slots ()
static bool gate_handle_machine_reorg ()
static unsigned int rest_of_handle_machine_reorg ()
rtl_opt_passmake_pass_machine_reorg ()

Function Documentation

static bool gate_handle_delay_slots ( )
static

Perform instruction reorganizations for delay slot filling. Copyright (C) 1992-2013 Free Software Foundation, Inc. Contributed by Richard Kenner (kenne.nosp@m.r@vl.nosp@m.si1.u.nosp@m.ltra.nosp@m..nyu..nosp@m.edu). Hacked by Michael Tiemann (tiema.nosp@m.nn@c.nosp@m.ygnus.nosp@m..com).

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/. Instruction reorganization pass.

This pass runs after register allocation and final jump optimization. It should be the last pass to run before peephole. It serves primarily to fill delay slots of insns, typically branch and call insns. Other insns typically involve more complicated interactions of data dependencies and resource constraints, and are better handled by scheduling before register allocation (by the function `schedule_insns').

The Branch Penalty is the number of extra cycles that are needed to execute a branch insn. On an ideal machine, branches take a single cycle, and the Branch Penalty is 0. Several RISC machines approach branch delays differently:

The MIPS has a single branch delay slot. Most insns (except other branches) can be used to fill this slot. When the slot is filled, two insns execute in two cycles, reducing the branch penalty to zero.

The SPARC always has a branch delay slot, but its effects can be annulled when the branch is not taken. This means that failing to find other sources of insns, we can hoist an insn from the branch target that would only be safe to execute knowing that the branch is taken.

The HP-PA always has a branch delay slot. For unconditional branches its effects can be annulled when the branch is taken. The effects of the delay slot in a conditional branch can be nullified for forward taken branches, or for untaken backward branches. This means we can hoist insns from the fall-through path for forward branches or steal insns from the target of backward branches.

The TMS320C3x and C4x have three branch delay slots. When the three slots are filled, the branch penalty is zero. Most insns can fill the delay slots except jump insns.

Three techniques for filling delay slots have been implemented so far:

(1) `fill_simple_delay_slots' is the simplest, most efficient way to fill delay slots. This pass first looks for insns which come from before the branch and which are safe to execute after the branch. Then it searches after the insn requiring delay slots or, in the case of a branch, for insns that are after the point at which the branch merges into the fallthrough code, if such a point exists. When such insns are found, the branch penalty decreases and no code expansion takes place.

(2) `fill_eager_delay_slots' is more complicated: it is used for scheduling conditional jumps, or for scheduling jumps which cannot be filled using (1). A machine need not have annulled jumps to use this strategy, but it helps (by keeping more options open). `fill_eager_delay_slots' tries to guess the direction the branch will go; if it guesses right 100% of the time, it can reduce the branch penalty as much as `fill_simple_delay_slots' does. If it guesses wrong 100% of the time, it might as well schedule nops. When `fill_eager_delay_slots' takes insns from the fall-through path of the jump, usually there is no code expansion; when it takes insns from the branch target, there is code expansion if it is not the only way to reach that target.

(3) `relax_delay_slots' uses a set of rules to simplify code that has been reorganized by (1) and (2). It finds cases where conditional test can be eliminated, jumps can be threaded, extra insns can be eliminated, etc. It is the job of (1) and (2) to do a good job of scheduling locally; `relax_delay_slots' takes care of making the various individual schedules work well together. It is especially tuned to handle the control flow interactions of branch insns. It does nothing for insns with delay slots that do not branch.

On machines that use CC0, we are very conservative. We will not make a copy of an insn involving CC0 since we want to maintain a 1-1 correspondence between the insn that sets and uses CC0. The insns are allowed to be separated by placing an insn that sets CC0 (but not an insn that uses CC0; we could do this, but it doesn't seem worthwhile) in a delay slot. In that case, we point each insn at the other with REG_CC_USER and REG_CC_SETTER notes. Note that these restrictions affect very few machines because most RISC machines with delay slots will not use CC0 (the RT is the only known exception at this point).

static bool gate_handle_machine_reorg ( )
static

Machine dependent reorg pass.

rtl_opt_pass* make_pass_delay_slots ( )
rtl_opt_pass* make_pass_machine_reorg ( )
static unsigned int rest_of_handle_delay_slots ( )
static

Run delay slot optimization.

static unsigned int rest_of_handle_machine_reorg ( )
static