GCC Middle and Back End API Reference
|
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "regs.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
#include "conditions.h"
#include "flags.h"
#include "hard-reg-set.h"
#include "output.h"
#include "except.h"
#include "function.h"
#include "rtl-error.h"
#include "toplev.h"
#include "reload.h"
#include "intl.h"
#include "basic-block.h"
#include "target.h"
#include "targhooks.h"
#include "debug.h"
#include "expr.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "tree-ssa.h"
#include "coverage.h"
#include "df.h"
#include "ggc.h"
#include "cfgloop.h"
#include "params.h"
#include "tree-pretty-print.h"
#include "dwarf2out.h"
Data Structures | |
struct | label_alignment |
struct | debug_prefix_map |
Macros | |
#define | CC_STATUS_INIT |
#define | IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';') |
#define | JUMP_TABLES_IN_TEXT_SECTION 0 |
#define | SEEN_BB 1 |
#define | SEEN_NOTE 2 |
#define | SEEN_EMITTED 4 |
#define | LABEL_ALIGN(LABEL) align_labels_log |
#define | LOOP_ALIGN(LABEL) align_loops_log |
#define | LABEL_ALIGN_AFTER_BARRIER(LABEL) 0 |
#define | JUMP_ALIGN(LABEL) align_jumps_log |
#define | ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC) |
#define | INSN_LENGTH_ALIGNMENT(INSN) length_unit_log |
#define | INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)]) |
#define | LABEL_TO_ALIGNMENT(LABEL) (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment) |
#define | LABEL_TO_MAX_SKIP(LABEL) (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip) |
#define | MAX_CODE_ALIGN 16 |
#define | NO_PROFILE_COUNTERS 0 |
Typedefs | |
typedef struct debug_prefix_map | debug_prefix_map |
Variables | |
static rtx | debug_insn |
rtx | current_output_insn |
static int | last_linenum |
static int | last_discriminator |
static int | discriminator |
static int | high_block_linenum |
static int | high_function_linenum |
static const char * | last_filename |
static const char * | override_filename |
static int | override_linenum |
static bool | force_source_line = false |
const int | length_unit_log |
rtx | this_is_asm_operands |
static unsigned int | insn_noperands |
static rtx | last_ignored_compare = 0 |
static int | insn_counter = 0 |
static int | block_depth |
static int | app_on |
rtx | final_sequence |
rtx | current_insn_predicate |
bool | final_insns_dump_p |
static bool | need_profile_function |
static int * | insn_lengths |
vec< int > | insn_addresses_ |
static int | insn_lengths_max_uid |
int | insn_current_address |
int | insn_last_address |
int | insn_current_align |
static rtx * | uid_align |
static int * | uid_shuid |
static struct label_alignment * | label_align |
static int | min_labelno |
static int | max_labelno |
static debug_prefix_map * | debug_prefix_maps |
#define ADDR_VEC_ALIGN | ( | ADDR_VEC | ) | final_addr_vec_align (ADDR_VEC) |
#define CC_STATUS_INIT |
Convert RTL to assembler code and output it, for GNU compiler. Copyright (C) 1987-2013 Free Software Foundation, Inc.
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/. This is the final pass of the compiler. It looks at the rtl code for a function and outputs assembler code.
Call `final_start_function' to output the assembler code for function entry, `final' to output assembler code for some RTL code, `final_end_function' to output assembler code for function exit. If a function is compiled in several pieces, each piece is output separately with `final'.
Some optimizations are also done at this level. Move instructions that were made unnecessary by good register allocation are detected and omitted from the output. (Though most of these are removed by the last jump pass.)
Instructions to set the condition codes are omitted when it can be seen that the condition codes already had the desired values.
In some cases it is sufficient if the inherited condition codes have related values, but this may require the following insn (the one that tests the condition codes) to be modified.
The code for the function prologue and epilogue are generated directly in assembler by the target functions function_prologue and function_epilogue. Those instructions never exist as rtl. Most ports that aren't using cc0 don't need to define CC_STATUS_INIT. So define a null default for it to save conditionalization later.
Referenced by profile_function().
#define INSN_LENGTH_ALIGNMENT | ( | INSN | ) | length_unit_log |
Referenced by sprint_ul_rev(), and update_alignments().
#define IS_ASM_LOGICAL_LINE_SEPARATOR | ( | C, | |
STR | |||
) | ((C) == ';') |
Is the given character a logical line separator for the assembler?
#define JUMP_ALIGN | ( | LABEL | ) | align_jumps_log |
#define JUMP_TABLES_IN_TEXT_SECTION 0 |
#define LABEL_ALIGN | ( | LABEL | ) | align_labels_log |
Code to handle alignment inside shorten_branches. Here is an explanation how the algorithm in align_fuzz can give proper results:
Call a sequence of instructions beginning with alignment point X and continuing until the next alignment point `block X'. When `X' is used in an expression, it means the alignment value of the alignment point.
Call the distance between the start of the first insn of block X, and the end of the last insn of block X `IX', for the `inner size of X'. This is clearly the sum of the instruction lengths.
Likewise with the next alignment-delimited block following X, which we shall call block Y.
Call the distance between the start of the first insn of block X, and the start of the first insn of block Y `OX', for the `outer size of X'.
The estimated padding is then OX - IX.
OX can be safely estimated as
if (X >= Y) OX = round_up(IX, Y) else OX = round_up(IX, X) + Y - X
Clearly est(IX) >= real(IX), because that only depends on the instruction lengths, and those being overestimated is a given.
Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so we needn't worry about that when thinking about OX.
When X >= Y, the alignment provided by Y adds no uncertainty factor for branch ranges starting before X, so we can just round what we have. But when X < Y, we don't know anything about the, so to speak, `middle bits', so we have to assume the worst when aligning up from an address mod X to one mod Y, which is Y - X.
Referenced by make_pass_compute_alignments().
#define LABEL_ALIGN_AFTER_BARRIER | ( | LABEL | ) | 0 |
#define LABEL_TO_ALIGNMENT | ( | LABEL | ) | (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].alignment) |
Referenced by make_pass_compute_alignments().
#define LABEL_TO_MAX_SKIP | ( | LABEL | ) | (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno].max_skip) |
Referenced by default_jump_align_max_skip(), and make_pass_compute_alignments().
#define LOOP_ALIGN | ( | LABEL | ) | align_loops_log |
#define MAX_CODE_ALIGN 16 |
Referenced by update_alignments().
#define NO_PROFILE_COUNTERS 0 |
#define SEEN_BB 1 |
Bitflags used by final_scan_insn.
#define SEEN_EMITTED 4 |
#define SEEN_NOTE 2 |
typedef struct debug_prefix_map debug_prefix_map |
??? This is probably the wrong place for these. Structure recording the mapping from source file and directory names at compile time to those to be embedded in debug information.
void add_debug_prefix_map | ( | ) |
Record a debug file prefix mapping. ARG is the argument to -fdebug-prefix-map and must be of the form OLD=NEW.
References BLOCK_SUPERCONTEXT, emit_note_before(), and NOTE_BLOCK.
|
static |
The differences in addresses between a branch and its target might grow or shrink depending on the alignment the start insn of the range (the branch for a forward branch or the label for a backward branch) starts out on; if these differences are used naively, they can even oscillate infinitely. We therefore want to compute a 'worst case' address difference that is independent of the alignment the start insn of the range end up on, and that is at least as large as the actual difference. The function align_fuzz calculates the amount we have to add to the naively computed difference, by traversing the part of the alignment chain of the start insn of the range that is in front of the end insn of the range, and considering for each alignment the maximum amount that it might contribute to a size increase.
For casesi tables, we also want to know worst case minimum amounts of address difference, in case a machine description wants to introduce some common offset that is added to all offsets in a table. For this purpose, align_fuzz with a growth argument of 0 computes the appropriate adjustment. Compute the maximum delta by which the difference of the addresses of START and END might grow / shrink due to a different address for start which changes the size of alignment insns between START and END. KNOWN_ALIGN_LOG is the alignment known for START. GROWTH should be ~0 if the objective is to compute potential code size increase, and 0 if the objective is to compute potential shrink. The return value is undefined for any other value of GROWTH.
rtx alter_subreg | ( | ) |
If X is a SUBREG, try to replace it with a REG or a MEM, based on the thing it is a subreg of. Do it anyway if FINAL_P.
simplify_subreg does not remove subreg from volatile references. We are required to.
For paradoxical subregs on big-endian machines, SUBREG_BYTE contains 0 instead of the proper offset. See simplify_subreg.
Simplify_subreg can't handle some REG cases, but we have to.
Referenced by output_asm_insn().
void app_disable | ( | void | ) |
Disable APP processing of subsequent output. Called from varasm.c before most kinds of output.
References label_alignment::alignment, and label_alignment::max_skip.
void app_enable | ( | void | ) |
Enable APP processing of subsequent output. Used before the output from an `asm' statement.
void asm_fprintf | ( | ) |
A poor man's fprintf, with the added features of I, R, L, and U. R prints the value of REGISTER_PREFIX. L prints the value of LOCAL_LABEL_PREFIX. U prints the value of USER_LABEL_PREFIX. I prints the value of IMMEDIATE_PREFIX. O runs ASM_OUTPUT_OPCODE to transform what follows in the string. Also supported are d, i, u, x, X, o, c, s and %%.
We handle alternate assembler dialects here, just like output_asm_insn.
This is a prefix to the 'd', 'i', 'u', 'x', 'X', and 'o' cases, but we do not check for those cases. It means that the value is a HOST_WIDE_INT, which may be either `long' or `long long'.
|
static |
|
static |
Given the body of an INSN known to be generated by an ASM statement, return the number of machine instructions likely to be generated for this insn. This is used to compute its length.
int asm_str_count | ( | ) |
Return the number of machine instructions likely to be generated for the inline-asm template.
References BLOCK_NUMBER.
|
static |
Given a CALL_INSN, find and return the nested CALL.
|
static |
Emit lexical block notes needed to change scope from S1 to S2.
Close scopes.
Open scopes.
|
static |
Return scope resulting from combination of S1 and S2.
References cfun, DECL_INITIAL, INSN_LOCATION, and UNKNOWN_LOCATION.
void cleanup_subreg_operands | ( | ) |
For each operand in INSN, simplify (subreg (reg)) so that it refers directly to the desired hard register.
The following test cannot use recog_data.operand when testing for a SUBREG: the underlying object might have been changed already if we are inside a match_operator expression that matches the else clause. Instead we test the underlying expression directly.
unsigned int compute_alignments | ( | void | ) |
Compute branch alignments based on frequency information in the CFG.
If not optimizing or optimizing for size, don't assign any alignments.
There are two purposes to align block with no fallthru incoming edge: 1) to avoid fetch stalls when branch destination is near cache boundary 2) to improve cache efficiency in case the previous block is not executed (so it does not need to be in the cache). We to catch first case, we align frequently executed blocks. To catch the second, we align blocks that are executed more frequently than the predecessor and the predecessor is likely to not be executed when function is called.
In case block is frequent and reached mostly by non-fallthru edge, align it. It is most likely a first block of loop.
References EDGE_FREQUENCY, and edge_def::flags.
void default_function_pro_epilogue | ( | FILE * | file, |
HOST_WIDE_INT | size | ||
) |
Default target function prologue and epilogue assembler output.
If not overridden for epilogue code, then the function body itself contains return instructions wherever needed.
Referenced by reemit_insn_block_notes().
Default target function switched text sections.
References app_on.
int default_jump_align_max_skip | ( | ) |
References CODE_LABEL_NUMBER, and LABEL_TO_MAX_SKIP.
int default_label_align_after_barrier_max_skip | ( | ) |
int default_label_align_max_skip | ( | ) |
int default_loop_align_max_skip | ( | ) |
References CODE_LABEL_NUMBER.
|
static |
Dumper helper for basic block information. FILE is the assembly output file, and INSN is the instruction being emitted.
|
static |
Return true if DWARF2 debug info can be emitted for DECL.
void final | ( | ) |
Output assembler code for some insns: all or part of a function. For description of args, see `final_start_function', above.
Used for -dA dump.
There is no cfg for a thunk.
Output the insns.
This can be triggered by bugs elsewhere in the compiler if new insns are created after init_insn_lengths is called.
Remove CFI notes, to avoid compare-debug failures.
References targetm.
|
static |
|
static |
void final_end_function | ( | void | ) |
Output assembler code for the end of a function. For clarity, args are same as those of `final_start_function' even though not all of them are needed.
Finally, output the function epilogue: code to restore the stack frame and return to the caller.
And debug output.
int final_forward_branch_p | ( | ) |
Return 1 if branch is a forward branch. Uses insn_shuid array, so it works only in the final pass. May be used by output templates to customary add branch prediction hints.
We've hit some insns that does not have id information available.
References OPTGROUP_NONE, and RTL_PASS.
The final scan for one insn, INSN. Args are same as in `final', except that INSN is the insn being scanned. Value returned is the next insn to be scanned.
NOPEEPHOLES is the flag to disallow peephole processing (currently used for within delayed branch sequence output).
SEEN is used to track the end of the prologue, for emitting debug information. We force the emission of a line note after both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG, or at the beginning of the second basic block, whichever comes first.
Ignore deleted insns. These can occur when we split insns (due to a template of "#") while not optimizing.
Output debugging info about the symbol-block beginning.
Mark this block as output.
End of a symbol-block.
Emit the label. We may have deleted the CODE_LABEL because the label could be proved to be unreachable, though still referenced (in the form of having its address taken.
Similarly, but need to use different namespace for it.
The target port might emit labels in the output function for some insn, e.g. sh.c output_branchy_insn.
If this label is followed by a jump-table, make sure we put the label in the read-only section. Also possibly write the label and jump table together.
Reset this early so it is correct for ASM statements.
An INSN, JUMP_INSN or CALL_INSN. First check for special kinds that recog doesn't recognize.
Detect insns that are really jump-tables and output them as such.
Output this line note if it is the first or the last line note in a row.
There's no telling what that did to the condition codes.
Detect `asm' construct with operands.
There's no telling what that did to the condition codes.
Get out the operand values.
Inhibit dying on what would otherwise be compiler bugs.
Output the insn using them.
A delayed-branch sequence
The first insn in this SEQUENCE might be a JUMP_INSN that will force the restoration of a comparison that was previously thought unnecessary. If that happens, cancel this sequence and cause that insn to be restored.
We loop in case any instruction in a delay slot gets split.
If the insn requiring the delay slot was a CALL_INSN, the insns in the delay slot are actually executed before the called function. Hence we don't preserve any CC-setting actions in these insns and the CC must be marked as being clobbered by the function.
We have a real machine instruction as rtl.
Try to recognize the instruction. If successful, verify that the operands satisfy the constraints for the instruction. Crash if they don't, since `reload' should have changed them so that they do.
Dump the insn in the assembly for debugging (-dAP). If the final dump is requested as slim RTL, dump slim RTL to the assembly file also.
Some target machines need to prescan each insn before it is output.
Find the proper template for this insn.
If the C code returns 0, it means that it is a jump insn which follows a deleted test insn, and that test insn needs to be reinserted.
We have already processed the notes between the setter and the user. Make sure we don't process them again, this is particularly important if one of the notes is a block scope note or an EH note.
If the template is the string "#", it means that this insn must be split.
If we didn't split the insn, go away.
If we have a length attribute, this instruction should have been split in shorten_branches, to ensure that we would have valid length info for the splitees.
??? This will put the directives in the wrong place if get_insn_template outputs assembly directly. However calling it before get_insn_template breaks if the insns is split.
Output assembler code from the template.
Some target machines need to postscan each insn after it is output.
References debug_hooks.
void final_start_function | ( | rtx | first, |
FILE * | file, | ||
int | optimize_p | ||
) |
Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated assembler pseudo-ops have already been output in `assemble_start_function'.
FIRST is the first insn of the rtl for the function being compiled. FILE is the file to write assembler code to. OPTIMIZE_P is nonzero if we should eliminate redundant test and compare insns.
The Sun386i and perhaps other machines don't work right if the profiling code comes after the prologue.
If debugging, assign block numbers to all of the blocks in this function.
We never actually put out begin/end notes for the top-level block in the function. But, conceptually, that block is always needed.
Issue a warning
First output the function prologue: code to set up the stack frame.
If the machine represents the prologue as RTL, the profiling code must be emitted when NOTE_INSN_PROLOGUE_END is scanned.
References assemble_integer(), BITS_PER_UNIT, const0_rtx, current_function_funcdef_no, data_section, floor_log2(), LONG_TYPE_SIZE, MIN, switch_to_section(), and targetm.
void fprint_ul | ( | ) |
Write an unsigned long as decimal to a file, fast.
python says: len(str(2**64)) == 20
It's probably too small to bother with string reversal and fputs.
References crtl, df_regs_ever_live_p(), global_regs, pic_offset_table_rtx, REG_P, and REGNO.
void fprint_whex | ( | ) |
Write a HOST_WIDE_INT number in hex form 0x1234, fast.
References CALL_P, crtl, GET_CODE, get_insns(), NEXT_INSN, NONJUMP_INSN_P, PATTERN, SIBLING_CALL_P, and XVECEXP.
Referenced by dw2_asm_output_data_uleb128_raw().
int get_attr_length | ( | ) |
Obtain the current length of an insn. If branch shortening has been done, get its actual length. Otherwise, get its maximum length.
Obtain the current length of an insn. If branch shortening has been done, get its actual length. Otherwise, use FALLBACK_FN to calculate the length.
int get_attr_min_length | ( | ) |
Obtain the current length of an insn. If branch shortening has been done, get its actual length. Otherwise, get its minimum length.
Referenced by decls_for_scope(), and reorder_basic_blocks().
const char* get_insn_template | ( | ) |
References need_profile_function, and profile_function().
|
static |
If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it or its address, return that expr . Set *PADDRESSP to 1 if the expr corresponds to the address of the object and 0 if to the object.
Otherwise we have an address, so indicate it and look at the address.
First check if we have a decl for the address, then look at the right side if it is a PLUS. Otherwise, strip off arithmetic and keep looking. But don't allow the address to itself be indirect.
|
static |
Grow the LABEL_ALIGN array after new labels are created.
Range of labels grows monotonically in the function. Failing here means that the initialization of array got lost.
Referenced by update_alignments().
void init_final | ( | ) |
Initialize data in final at the beginning of a compilation.
void init_insn_lengths | ( | void | ) |
Indicate that branch shortening hasn't yet been done.
int insn_current_reference_address | ( | ) |
Compute a worst-case reference address of a branch so that it can be safely used in the presence of aligned labels. Since the size of the branch itself is unknown, the size of the branch is not included in the range. I.e. for a forward branch, the reference address is the end address of the branch as known from the previous branch shortening pass, minus a value to account for possible size increase due to alignment. For a backward branch, it is the start address of the branch as known from the current pass, plus a value to account for possible size increase due to alignment. NB.: Therefore, the maximum offset allowed for backward branches needs to exclude the branch size.
This can happen for example on the PA; the objective is to know the offset to address something in front of the start of the function. Thus, we can treat it like a backward branch. We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than any alignment we'd encounter, so we skip the call to align_fuzz.
BRANCH has no proper alignment chain set, so use SEQ. BRANCH also has no INSN_SHUID.
Forward branch.
Backward branch.
int label_to_alignment | ( | ) |
For the benefit of port specific code do this also as a function.
int label_to_max_skip | ( | ) |
int leaf_function_p | ( | void | ) |
Return nonzero if this function has no function calls.
Referenced by split_live_ranges_for_shrink_wrap().
rtl_opt_pass* make_pass_clean_state | ( | ) |
rtl_opt_pass* make_pass_compute_alignments | ( | ) |
References JUMP_TABLE_DATA_P, LABEL_ALIGN, LABEL_TO_ALIGNMENT, LABEL_TO_MAX_SKIP, log(), and next_nonnote_insn().
rtl_opt_pass* make_pass_final | ( | ) |
rtl_opt_pass* make_pass_shorten_branches | ( | ) |
|
static |
Helper rtx-iteration-function for mark_symbol_refs_as_used and output_operand. Marks SYMBOL_REFs as referenced through use of assemble_external.
If we have a used symbol, we may have to emit assembly annotations corresponding to whether the symbol is external, weak or has non-default visibility.
Referenced by output_asm_insn().
void mark_symbol_refs_as_used | ( | ) |
Marks SYMBOL_REFs in x as referenced through use of assemble_external.
void no_asm_to_stream | ( | ) |
Default target hook that outputs nothing to a stream.
|
static |
Return whether a source line note needs to be emitted before INSN. Sets IS_STMT to TRUE if the line should be marked as a possible breakpoint location.
If the discriminator changed, but the line number did not, output the line table entry with is_stmt false so the debugger does not treat this as a breakpoint location.
References GET_CODE, PUT_CODE, reverse_condition(), and swap_condition().
void output_addr_const | ( | ) |
Print an integer constant expression in assembler syntax. Addition and subtraction are the only arithmetic that may appear in these expressions.
Fall through.
This used to output parentheses around the expression, but that does not work on the 386 (either ATT or BSD assembler).
We can use %d if the number is one word and positive.
We can't handle floating point constants; PRINT_OPERAND must handle them.
Some assemblers need integer constants to appear last (eg masm).
Avoid outputting things like x-x or x+5-x, since some assemblers can't handle that.
Referenced by output_asm_operand_names().
void output_address | ( | ) |
Print a memory reference operand for address X using machine-dependent assembler syntax.
Referenced by output_asm_operand_names().
|
static |
|
static |
Emit the appropriate declaration for an alternate-entry-point symbol represented by INSN, to FILE. INSN is a CODE_LABEL with LABEL_KIND != LABEL_NORMAL.
The case fall-through in this function is intentional.
References targetm.
void output_asm_insn | ( | ) |
Output text from TEMPLATE to the assembler output file, obeying %-directions to substitute operands taken from the vector OPERANDS.
N (for N a digit) means print operand N in usual manner. lN means require operand N to be a CODE_LABEL or LABEL_REF and print the label name with no punctuation. cN means require operand N to be a constant and print the constant expression with no punctuation. aN means expect operand N to be a memory address (not a memory reference!) and print a reference to that address. nN means expect operand N to be a constant and print a constant expression for minus the value of the operand, with no other punctuation.
An insn may return a null string template in a case where no assembler code is needed.
%% outputs a single %. %{, %} and %| print {, } and | respectively if ASSEMBLER_DIALECT defined and these characters have a special meaning as dialect delimiters.
%= outputs a number which is unique to each insn in the entire compilation. This is useful for making local labels that are referred to more than once in a given insn.
% followed by a letter and some digits outputs an operand in a special way depending on the letter. Letters `acln' are implemented directly. Other letters are passed to `output_operand' so that the TARGET_PRINT_OPERAND hook can define them.
% followed by a digit outputs an operand the default way.
% followed by punctuation: output something for that punctuation character alone, with no operand. The TARGET_PRINT_OPERAND hook decides what is actually done.
Write out the variable names for operands, if we know them.
References alter_subreg(), for_each_rtx(), gcc_assert, GET_CODE, mark_symbol_ref_as_used(), NULL, NULL_RTX, REG_P, REGNO, and targetm.
void output_asm_label | ( | ) |
Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.
Referenced by output_asm_operand_names().
|
static |
Output of assembler code from a template, and its subroutines. Annotate the assembly with a comment describing the pattern and alternative used.
Clear this so only the first assembler insn of any rtl insn will get the special comment for -dp.
|
static |
|
static |
Output operand names for assembler instructions. OPERANDS is the operand vector, OPORDER is the order to write the operands, and NOPS is the number of operands to write.
References CONST_INT_P, CONSTANT_ADDRESS_P, HOST_WIDE_INT_PRINT_DEC, insn_noperands, INTVAL, output_addr_const(), output_address(), output_asm_label(), output_operand(), and output_operand_lossage().
void output_operand | ( | ) |
Print operand X using machine-dependent assembler syntax. CODE is a non-digit that preceded the operand-number in the % spec, such as 'z' if the spec was `z3'. CODE is 0 if there was no char between the % and the digits. When CODE is a non-letter, X is 0.
The meanings of the letters are machine-dependent and controlled by TARGET_PRINT_OPERAND.
X must not be a pseudo reg.
Referenced by output_asm_operand_names().
void output_operand_lossage | ( | ) |
Report inconsistency between the assembler template and the operands. In an `asm', it's the user's fault; otherwise, the compiler's fault.
Referenced by get_random_seed(), and output_asm_operand_names().
void output_quoted_string | ( | ) |
Output a quoted string.
|
static |
|
static |
|
static |
Referenced by get_insn_template(), and reemit_insn_block_notes().
|
static |
References BB_HEAD, CC_STATUS_INIT, cfun, FOR_EACH_BB_REVERSE, get_max_uid(), init_recog(), INSN_UID, JUMP_LABEL, JUMP_P, LABEL_NUSES, LABEL_P, LABEL_REFS, debug_prefix_map::next, NEXT_INSN, and NULL.
|
static |
Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based on the scope tree and the newly reordered instructions.
Prevent lexical blocks from straddling section boundaries.
Avoid putting scope notes between jump table and its label.
For sequences compute scope resulting from merging all scopes of instructions nested inside.
change_scope emits before the insn, not after.
References default_function_pro_epilogue(), HAVE_prologue, need_profile_function, NEXT_INSN, NOTE_KIND, NOTE_P, NULL_RTX, profile_function(), and targetm.
const char* remap_debug_filename | ( | ) |
Perform user-specified mapping of debug filename prefixes. Return the new name corresponding to FILENAME.
|
static |
It is very important to decompose the RTL instruction chain here: debug information keeps pointing into CODE_LABEL insns inside the function body. If these remain pointing to the other insns, we end up preserving whole RTL chain and attached detailed debug info in memory.
In case the function was not output, don't leave any temporary anonymous types queued up for sdb output.
Clear out the insn_length contents now that they are no longer valid.
Show no temporary slots allocated.
We can reduce stack alignment on call site only when we are sure that the function body just produced will be actually used in the final executable.
Make sure volatile mem refs aren't considered valid operands for arithmetic insns. We must call this here if this is a nested inline function, since the above code leaves us in the init_recog state, and the function context push/pop code does not save/restore volatile_ok. ??? Maybe it isn't necessary for expand_start_function to call this anymore if we do it here?
We're done with this function. Free up memory if we can.
|
static |
On some machines, a function with no call insns can run faster if it doesn't create its own register window. When output, the leaf function should use only the "output" registers. Ordinarily, the function would be compiled to use the "input" registers to find its arguments; it is a candidate for leaf treatment if it uses only the "input" registers. Leaf function treatment means renumbering so the function uses the "output" registers instead. Turn the RTL into assembly.
Get the function's name, as described by its RTL. This may be different from the DECL_NAME name used in the source file.
The IA-64 ".handlerdata" directive must be issued before the ".endp" directive that closes the procedure descriptor. Similarly, for x64 SEH. Otherwise it's not strictly necessary, but it doesn't hurt either.
Free up reg info memory.
Write DBX symbols if requested.
Note that for those inline functions where we don't initially know for certain that we will be generating an out-of-line copy, the first invocation of this routine (rest_of_compilation) will skip over this code by doing a `goto exit_rest_of_compilation;'. Later on, wrapup_global_declarations will (indirectly) call rest_of_compilation again for those inline functions that need to have out-of-line copies generated. During that call, we *will* be routed past here.
Release the blocks that are linked to DECL_INITIAL() to free the memory.
|
static |
Shorten branches.
void shorten_branches | ( | ) |
Make a pass over all insns and compute their actual lengths by shortening any branches of variable length if possible. shorten_branches might be called multiple times: for example, the SH port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG. In order to do this, it needs proper length information, which it obtains by calling shorten_branches. This cannot be collapsed with shorten_branches itself into a single pass unless we also want to integrate reorg.c, since the branch splitting exposes new instructions with delay slots.
Compute maximum UID and allocate label_align / uid_shuid.
Free uid_shuid before reallocating it.
Initialize label_align and set up uid_shuid to be strictly monotonically rising with insn order.
We use max_log here to keep track of the maximum alignment we want to impose on the next CODE_LABEL (or the current one if we are processing the CODE_LABEL itself).
Merge in alignments computed by compute_alignments.
ADDR_VECs only take room if read-only data goes into the text section.
Allocate the rest of the arrays.
Syntax errors can lead to labels being outside of the main insn stream. Initialize insn_addresses, so that we get reproducible results.
Initialize uid_align. We scan instructions from end to start, and keep in align_tab[n] the last seen insn that does an alignment of at least n+1, i.e. the successor in the alignment chain for an insn that does / has a known alignment of n.
Found an alignment label.
When optimizing, we start assuming minimum length, and keep increasing lengths as we find the need for this, till nothing changes. When not optimizing, we start assuming maximum lengths, and do a single pass to update the lengths.
Compute initial lengths, addresses, and varying flags for each insn.
This only takes room if read-only data goes into the text section.
Alignment is handled by ADDR_VEC_ALIGN.
Inside a delay slot sequence, we do not do any branch shortening if the shortening could change the number of delay slots of the branch.
If needed, do any adjustment.
Now loop over all the insns finding varying length insns. For each, get the current insn length. If it has changed, reflect the change. When nothing changes for a full pass, we are done.
insn_current_length returns 0 for insns with a non-varying length.
For a non-optimizing compile, do only a single pass.
References targetm.
int sprint_ul | ( | ) |
Write an unsigned long as decimal to a string, fast. s must be wide enough to not overflow, at least 21 chars. Returns the length of the string (without terminating '\0').
Reverse the string.
References INSN_P, leaf_renumber_regs_insn(), NEXT_INSN, and PATTERN.
|
static |
Internal function that prints an unsigned long in decimal in reverse. The output string IS NOT null-terminated.
alternate version, without modulo
oldval = value;
value /= 10;
s[i] = "0123456789" [oldval - 10*value];
i++
References gcc_assert, INSN_SHUID, and JUMP_LABEL.
void update_alignments | ( | ) |
Update the already computed alignment information. LABEL_PAIRS is a vector made up of pairs of labels for which the alignment information of the first element will be copied from that of the second element.
References get_insns(), get_max_uid(), grow_label_align(), INSN_P, INSN_SHUID, LABEL_P, log(), MAX_CODE_ALIGN, max_label_num(), and NEXT_INSN.
|
static |
Do alter_subreg on all the SUBREGs contained in X.
|
static |
Nonzero if have enabled APP processing of our assembler output.
Referenced by default_function_switched_text_sections().
|
static |
Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen.
rtx current_insn_predicate |
Nonnull if the insn currently being emitted was a COND_EXEC pattern.
rtx current_output_insn |
Last insn processed by final_scan_insn.
|
static |
Last insn processed by final_scan_insn.
|
static |
Linked list of such structures.
|
static |
Discriminator of current block.
bool final_insns_dump_p |
True if printing into -fdump-final-insns= dump.
rtx final_sequence |
If we are outputting an insn sequence, this contains the sequence rtx. Zero otherwise.
Whether to force emission of a line note before the next insn.
|
static |
Highest line number in current block.
|
static |
Likewise for function.
vec<int> insn_addresses_ |
Macros to support INSN_ADDRESSES Copyright (C) 2000-2013 Free Software Foundation, Inc.
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/.
|
static |
Assign a unique number to each insn that is output. This can be used to generate unique local labels.
int insn_current_address |
Address of insn being processed. Used by `insn_current_length'.
int insn_current_align |
known invariant alignment of insn being processed.
int insn_last_address |
Address of insn being processed in previous iteration.
|
static |
Return the number of slots filled in the current delayed branch sequence (we don't count the insn needing the delay slot). Zero if not in a delayed branch sequence. The next two pages contain routines used to compute the length of an insn and to shorten branches. Arrays for insn lengths, and addresses. The latter is referenced by `insn_current_length'.
|
static |
Max uid for which the above arrays are valid.
|
static |
Number of operands of this insn, for an `asm' with operands.
Referenced by output_asm_operand_names().
|
static |
|
static |
Last discriminator written to assembly.
|
static |
Filename of last NOTE.
|
static |
Compare optimization flag.
|
static |
Line number of last NOTE.
const int length_unit_log |
|
static |
|
static |
|
static |
True if profile_function should be called, but hasn't been called yet.
Referenced by get_insn_template(), and reemit_insn_block_notes().
|
static |
Override filename and line number.
|
static |
rtx this_is_asm_operands |
Nonzero while outputting an `asm' with operands. This means that inconsistencies are the user's fault, so don't die. The precise value is the insn being output, to pass to error_for_asm.
|
static |
|
static |