8d9254fc8a
From-SVN: r279813
2782 lines
102 KiB
Plaintext
2782 lines
102 KiB
Plaintext
@c Copyright (C) 2008-2020 Free Software Foundation, Inc.
|
|
@c Free Software Foundation, Inc.
|
|
@c This is part of the GCC manual.
|
|
@c For copying conditions, see the file gcc.texi.
|
|
|
|
@node GIMPLE
|
|
@chapter GIMPLE
|
|
@cindex GIMPLE
|
|
|
|
GIMPLE is a three-address representation derived from GENERIC by
|
|
breaking down GENERIC expressions into tuples of no more than 3
|
|
operands (with some exceptions like function calls). GIMPLE was
|
|
heavily influenced by the SIMPLE IL used by the McCAT compiler
|
|
project at McGill University, though we have made some different
|
|
choices. For one thing, SIMPLE doesn't support @code{goto}.
|
|
|
|
Temporaries are introduced to hold intermediate values needed to
|
|
compute complex expressions. Additionally, all the control
|
|
structures used in GENERIC are lowered into conditional jumps,
|
|
lexical scopes are removed and exception regions are converted
|
|
into an on the side exception region tree.
|
|
|
|
The compiler pass which converts GENERIC into GIMPLE is referred to as
|
|
the @samp{gimplifier}. The gimplifier works recursively, generating
|
|
GIMPLE tuples out of the original GENERIC expressions.
|
|
|
|
One of the early implementation strategies used for the GIMPLE
|
|
representation was to use the same internal data structures used
|
|
by front ends to represent parse trees. This simplified
|
|
implementation because we could leverage existing functionality
|
|
and interfaces. However, GIMPLE is a much more restrictive
|
|
representation than abstract syntax trees (AST), therefore it
|
|
does not require the full structural complexity provided by the
|
|
main tree data structure.
|
|
|
|
The GENERIC representation of a function is stored in the
|
|
@code{DECL_SAVED_TREE} field of the associated @code{FUNCTION_DECL}
|
|
tree node. It is converted to GIMPLE by a call to
|
|
@code{gimplify_function_tree}.
|
|
|
|
If a front end wants to include language-specific tree codes in the tree
|
|
representation which it provides to the back end, it must provide a
|
|
definition of @code{LANG_HOOKS_GIMPLIFY_EXPR} which knows how to
|
|
convert the front end trees to GIMPLE@. Usually such a hook will involve
|
|
much of the same code for expanding front end trees to RTL@. This function
|
|
can return fully lowered GIMPLE, or it can return GENERIC trees and let the
|
|
main gimplifier lower them the rest of the way; this is often simpler.
|
|
GIMPLE that is not fully lowered is known as ``High GIMPLE'' and
|
|
consists of the IL before the pass @code{pass_lower_cf}. High GIMPLE
|
|
contains some container statements like lexical scopes
|
|
(represented by @code{GIMPLE_BIND}) and nested expressions (e.g.,
|
|
@code{GIMPLE_TRY}), while ``Low GIMPLE'' exposes all of the
|
|
implicit jumps for control and exception expressions directly in
|
|
the IL and EH region trees.
|
|
|
|
The C and C++ front ends currently convert directly from front end
|
|
trees to GIMPLE, and hand that off to the back end rather than first
|
|
converting to GENERIC@. Their gimplifier hooks know about all the
|
|
@code{_STMT} nodes and how to convert them to GENERIC forms. There
|
|
was some work done on a genericization pass which would run first, but
|
|
the existence of @code{STMT_EXPR} meant that in order to convert all
|
|
of the C statements into GENERIC equivalents would involve walking the
|
|
entire tree anyway, so it was simpler to lower all the way. This
|
|
might change in the future if someone writes an optimization pass
|
|
which would work better with higher-level trees, but currently the
|
|
optimizers all expect GIMPLE@.
|
|
|
|
You can request to dump a C-like representation of the GIMPLE form
|
|
with the flag @option{-fdump-tree-gimple}.
|
|
|
|
@menu
|
|
* Tuple representation::
|
|
* Class hierarchy of GIMPLE statements::
|
|
* GIMPLE instruction set::
|
|
* GIMPLE Exception Handling::
|
|
* Temporaries::
|
|
* Operands::
|
|
* Manipulating GIMPLE statements::
|
|
* Tuple specific accessors::
|
|
* GIMPLE sequences::
|
|
* Sequence iterators::
|
|
* Adding a new GIMPLE statement code::
|
|
* Statement and operand traversals::
|
|
@end menu
|
|
|
|
@node Tuple representation
|
|
@section Tuple representation
|
|
@cindex tuples
|
|
|
|
GIMPLE instructions are tuples of variable size divided in two
|
|
groups: a header describing the instruction and its locations,
|
|
and a variable length body with all the operands. Tuples are
|
|
organized into a hierarchy with 3 main classes of tuples.
|
|
|
|
@subsection @code{gimple} (gsbase)
|
|
@cindex gimple
|
|
|
|
This is the root of the hierarchy, it holds basic information
|
|
needed by most GIMPLE statements. There are some fields that
|
|
may not be relevant to every GIMPLE statement, but those were
|
|
moved into the base structure to take advantage of holes left by
|
|
other fields (thus making the structure more compact). The
|
|
structure takes 4 words (32 bytes) on 64 bit hosts:
|
|
|
|
@multitable {@code{references_memory_p}} {Size (bits)}
|
|
@item Field @tab Size (bits)
|
|
@item @code{code} @tab 8
|
|
@item @code{subcode} @tab 16
|
|
@item @code{no_warning} @tab 1
|
|
@item @code{visited} @tab 1
|
|
@item @code{nontemporal_move} @tab 1
|
|
@item @code{plf} @tab 2
|
|
@item @code{modified} @tab 1
|
|
@item @code{has_volatile_ops} @tab 1
|
|
@item @code{references_memory_p} @tab 1
|
|
@item @code{uid} @tab 32
|
|
@item @code{location} @tab 32
|
|
@item @code{num_ops} @tab 32
|
|
@item @code{bb} @tab 64
|
|
@item @code{block} @tab 63
|
|
@item Total size @tab 32 bytes
|
|
@end multitable
|
|
|
|
@itemize @bullet
|
|
@item @code{code}
|
|
Main identifier for a GIMPLE instruction.
|
|
|
|
@item @code{subcode}
|
|
Used to distinguish different variants of the same basic
|
|
instruction or provide flags applicable to a given code. The
|
|
@code{subcode} flags field has different uses depending on the code of
|
|
the instruction, but mostly it distinguishes instructions of the
|
|
same family. The most prominent use of this field is in
|
|
assignments, where subcode indicates the operation done on the
|
|
RHS of the assignment. For example, a = b + c is encoded as
|
|
@code{GIMPLE_ASSIGN <PLUS_EXPR, a, b, c>}.
|
|
|
|
@item @code{no_warning}
|
|
Bitflag to indicate whether a warning has already been issued on
|
|
this statement.
|
|
|
|
@item @code{visited}
|
|
General purpose ``visited'' marker. Set and cleared by each pass
|
|
when needed.
|
|
|
|
@item @code{nontemporal_move}
|
|
Bitflag used in assignments that represent non-temporal moves.
|
|
Although this bitflag is only used in assignments, it was moved
|
|
into the base to take advantage of the bit holes left by the
|
|
previous fields.
|
|
|
|
@item @code{plf}
|
|
Pass Local Flags. This 2-bit mask can be used as general purpose
|
|
markers by any pass. Passes are responsible for clearing and
|
|
setting these two flags accordingly.
|
|
|
|
@item @code{modified}
|
|
Bitflag to indicate whether the statement has been modified.
|
|
Used mainly by the operand scanner to determine when to re-scan a
|
|
statement for operands.
|
|
|
|
@item @code{has_volatile_ops}
|
|
Bitflag to indicate whether this statement contains operands that
|
|
have been marked volatile.
|
|
|
|
@item @code{references_memory_p}
|
|
Bitflag to indicate whether this statement contains memory
|
|
references (i.e., its operands are either global variables, or
|
|
pointer dereferences or anything that must reside in memory).
|
|
|
|
@item @code{uid}
|
|
This is an unsigned integer used by passes that want to assign
|
|
IDs to every statement. These IDs must be assigned and used by
|
|
each pass.
|
|
|
|
@item @code{location}
|
|
This is a @code{location_t} identifier to specify source code
|
|
location for this statement. It is inherited from the front
|
|
end.
|
|
|
|
@item @code{num_ops}
|
|
Number of operands that this statement has. This specifies the
|
|
size of the operand vector embedded in the tuple. Only used in
|
|
some tuples, but it is declared in the base tuple to take
|
|
advantage of the 32-bit hole left by the previous fields.
|
|
|
|
@item @code{bb}
|
|
Basic block holding the instruction.
|
|
|
|
@item @code{block}
|
|
Lexical block holding this statement. Also used for debug
|
|
information generation.
|
|
@end itemize
|
|
|
|
@subsection @code{gimple_statement_with_ops}
|
|
@cindex gimple_statement_with_ops
|
|
|
|
This tuple is actually split in two:
|
|
@code{gimple_statement_with_ops_base} and
|
|
@code{gimple_statement_with_ops}. This is needed to accommodate the
|
|
way the operand vector is allocated. The operand vector is
|
|
defined to be an array of 1 element. So, to allocate a dynamic
|
|
number of operands, the memory allocator (@code{gimple_alloc}) simply
|
|
allocates enough memory to hold the structure itself plus @code{N
|
|
- 1} operands which run ``off the end'' of the structure. For
|
|
example, to allocate space for a tuple with 3 operands,
|
|
@code{gimple_alloc} reserves @code{sizeof (struct
|
|
gimple_statement_with_ops) + 2 * sizeof (tree)} bytes.
|
|
|
|
On the other hand, several fields in this tuple need to be shared
|
|
with the @code{gimple_statement_with_memory_ops} tuple. So, these
|
|
common fields are placed in @code{gimple_statement_with_ops_base} which
|
|
is then inherited from the other two tuples.
|
|
|
|
|
|
@multitable {@code{def_ops}} {48 + 8 * @code{num_ops} bytes}
|
|
@item @code{gsbase} @tab 256
|
|
@item @code{def_ops} @tab 64
|
|
@item @code{use_ops} @tab 64
|
|
@item @code{op} @tab @code{num_ops} * 64
|
|
@item Total size @tab 48 + 8 * @code{num_ops} bytes
|
|
@end multitable
|
|
|
|
@itemize @bullet
|
|
@item @code{gsbase}
|
|
Inherited from @code{struct gimple}.
|
|
|
|
@item @code{def_ops}
|
|
Array of pointers into the operand array indicating all the slots that
|
|
contain a variable written-to by the statement. This array is
|
|
also used for immediate use chaining. Note that it would be
|
|
possible to not rely on this array, but the changes required to
|
|
implement this are pretty invasive.
|
|
|
|
@item @code{use_ops}
|
|
Similar to @code{def_ops} but for variables read by the statement.
|
|
|
|
@item @code{op}
|
|
Array of trees with @code{num_ops} slots.
|
|
@end itemize
|
|
|
|
@subsection @code{gimple_statement_with_memory_ops}
|
|
|
|
This tuple is essentially identical to @code{gimple_statement_with_ops},
|
|
except that it contains 4 additional fields to hold vectors
|
|
related memory stores and loads. Similar to the previous case,
|
|
the structure is split in two to accommodate for the operand
|
|
vector (@code{gimple_statement_with_memory_ops_base} and
|
|
@code{gimple_statement_with_memory_ops}).
|
|
|
|
|
|
@multitable {@code{vdef_ops}} {80 + 8 * @code{num_ops} bytes}
|
|
@item Field @tab Size (bits)
|
|
@item @code{gsbase} @tab 256
|
|
@item @code{def_ops} @tab 64
|
|
@item @code{use_ops} @tab 64
|
|
@item @code{vdef_ops} @tab 64
|
|
@item @code{vuse_ops} @tab 64
|
|
@item @code{stores} @tab 64
|
|
@item @code{loads} @tab 64
|
|
@item @code{op} @tab @code{num_ops} * 64
|
|
@item Total size @tab 80 + 8 * @code{num_ops} bytes
|
|
@end multitable
|
|
|
|
@itemize @bullet
|
|
@item @code{vdef_ops}
|
|
Similar to @code{def_ops} but for @code{VDEF} operators. There is
|
|
one entry per memory symbol written by this statement. This is
|
|
used to maintain the memory SSA use-def and def-def chains.
|
|
|
|
@item @code{vuse_ops}
|
|
Similar to @code{use_ops} but for @code{VUSE} operators. There is
|
|
one entry per memory symbol loaded by this statement. This is
|
|
used to maintain the memory SSA use-def chains.
|
|
|
|
@item @code{stores}
|
|
Bitset with all the UIDs for the symbols written-to by the
|
|
statement. This is different than @code{vdef_ops} in that all the
|
|
affected symbols are mentioned in this set. If memory
|
|
partitioning is enabled, the @code{vdef_ops} vector will refer to memory
|
|
partitions. Furthermore, no SSA information is stored in this
|
|
set.
|
|
|
|
@item @code{loads}
|
|
Similar to @code{stores}, but for memory loads. (Note that there
|
|
is some amount of redundancy here, it should be possible to
|
|
reduce memory utilization further by removing these sets).
|
|
@end itemize
|
|
|
|
All the other tuples are defined in terms of these three basic
|
|
ones. Each tuple will add some fields.
|
|
|
|
|
|
@node Class hierarchy of GIMPLE statements
|
|
@section Class hierarchy of GIMPLE statements
|
|
@cindex GIMPLE class hierarchy
|
|
|
|
The following diagram shows the C++ inheritance hierarchy of statement
|
|
kinds, along with their relationships to @code{GSS_} values (layouts) and
|
|
@code{GIMPLE_} values (codes):
|
|
|
|
@smallexample
|
|
gimple
|
|
| layout: GSS_BASE
|
|
| used for 4 codes: GIMPLE_ERROR_MARK
|
|
| GIMPLE_NOP
|
|
| GIMPLE_OMP_SECTIONS_SWITCH
|
|
| GIMPLE_PREDICT
|
|
|
|
|
+ gimple_statement_with_ops_base
|
|
| | (no GSS layout)
|
|
| |
|
|
| + gimple_statement_with_ops
|
|
| | | layout: GSS_WITH_OPS
|
|
| | |
|
|
| | + gcond
|
|
| | | code: GIMPLE_COND
|
|
| | |
|
|
| | + gdebug
|
|
| | | code: GIMPLE_DEBUG
|
|
| | |
|
|
| | + ggoto
|
|
| | | code: GIMPLE_GOTO
|
|
| | |
|
|
| | + glabel
|
|
| | | code: GIMPLE_LABEL
|
|
| | |
|
|
| | + gswitch
|
|
| | code: GIMPLE_SWITCH
|
|
| |
|
|
| + gimple_statement_with_memory_ops_base
|
|
| | layout: GSS_WITH_MEM_OPS_BASE
|
|
| |
|
|
| + gimple_statement_with_memory_ops
|
|
| | | layout: GSS_WITH_MEM_OPS
|
|
| | |
|
|
| | + gassign
|
|
| | | code GIMPLE_ASSIGN
|
|
| | |
|
|
| | + greturn
|
|
| | code GIMPLE_RETURN
|
|
| |
|
|
| + gcall
|
|
| | layout: GSS_CALL, code: GIMPLE_CALL
|
|
| |
|
|
| + gasm
|
|
| | layout: GSS_ASM, code: GIMPLE_ASM
|
|
| |
|
|
| + gtransaction
|
|
| layout: GSS_TRANSACTION, code: GIMPLE_TRANSACTION
|
|
|
|
|
+ gimple_statement_omp
|
|
| | layout: GSS_OMP. Used for code GIMPLE_OMP_SECTION
|
|
| |
|
|
| + gomp_critical
|
|
| | layout: GSS_OMP_CRITICAL, code: GIMPLE_OMP_CRITICAL
|
|
| |
|
|
| + gomp_for
|
|
| | layout: GSS_OMP_FOR, code: GIMPLE_OMP_FOR
|
|
| |
|
|
| + gomp_parallel_layout
|
|
| | | layout: GSS_OMP_PARALLEL_LAYOUT
|
|
| | |
|
|
| | + gimple_statement_omp_taskreg
|
|
| | | |
|
|
| | | + gomp_parallel
|
|
| | | | code: GIMPLE_OMP_PARALLEL
|
|
| | | |
|
|
| | | + gomp_task
|
|
| | | code: GIMPLE_OMP_TASK
|
|
| | |
|
|
| | + gimple_statement_omp_target
|
|
| | code: GIMPLE_OMP_TARGET
|
|
| |
|
|
| + gomp_sections
|
|
| | layout: GSS_OMP_SECTIONS, code: GIMPLE_OMP_SECTIONS
|
|
| |
|
|
| + gimple_statement_omp_single_layout
|
|
| | layout: GSS_OMP_SINGLE_LAYOUT
|
|
| |
|
|
| + gomp_single
|
|
| | code: GIMPLE_OMP_SINGLE
|
|
| |
|
|
| + gomp_teams
|
|
| code: GIMPLE_OMP_TEAMS
|
|
|
|
|
+ gbind
|
|
| layout: GSS_BIND, code: GIMPLE_BIND
|
|
|
|
|
+ gcatch
|
|
| layout: GSS_CATCH, code: GIMPLE_CATCH
|
|
|
|
|
+ geh_filter
|
|
| layout: GSS_EH_FILTER, code: GIMPLE_EH_FILTER
|
|
|
|
|
+ geh_else
|
|
| layout: GSS_EH_ELSE, code: GIMPLE_EH_ELSE
|
|
|
|
|
+ geh_mnt
|
|
| layout: GSS_EH_MNT, code: GIMPLE_EH_MUST_NOT_THROW
|
|
|
|
|
+ gphi
|
|
| layout: GSS_PHI, code: GIMPLE_PHI
|
|
|
|
|
+ gimple_statement_eh_ctrl
|
|
| | layout: GSS_EH_CTRL
|
|
| |
|
|
| + gresx
|
|
| | code: GIMPLE_RESX
|
|
| |
|
|
| + geh_dispatch
|
|
| code: GIMPLE_EH_DISPATCH
|
|
|
|
|
+ gtry
|
|
| layout: GSS_TRY, code: GIMPLE_TRY
|
|
|
|
|
+ gimple_statement_wce
|
|
| layout: GSS_WCE, code: GIMPLE_WITH_CLEANUP_EXPR
|
|
|
|
|
+ gomp_continue
|
|
| layout: GSS_OMP_CONTINUE, code: GIMPLE_OMP_CONTINUE
|
|
|
|
|
+ gomp_atomic_load
|
|
| layout: GSS_OMP_ATOMIC_LOAD, code: GIMPLE_OMP_ATOMIC_LOAD
|
|
|
|
|
+ gimple_statement_omp_atomic_store_layout
|
|
| layout: GSS_OMP_ATOMIC_STORE_LAYOUT,
|
|
| code: GIMPLE_OMP_ATOMIC_STORE
|
|
|
|
|
+ gomp_atomic_store
|
|
| code: GIMPLE_OMP_ATOMIC_STORE
|
|
|
|
|
+ gomp_return
|
|
code: GIMPLE_OMP_RETURN
|
|
@end smallexample
|
|
|
|
|
|
@node GIMPLE instruction set
|
|
@section GIMPLE instruction set
|
|
@cindex GIMPLE instruction set
|
|
|
|
The following table briefly describes the GIMPLE instruction set.
|
|
|
|
@multitable {@code{GIMPLE_OMP_SECTIONS_SWITCH}} {High GIMPLE} {Low GIMPLE}
|
|
@item Instruction @tab High GIMPLE @tab Low GIMPLE
|
|
@item @code{GIMPLE_ASM} @tab x @tab x
|
|
@item @code{GIMPLE_ASSIGN} @tab x @tab x
|
|
@item @code{GIMPLE_BIND} @tab x @tab
|
|
@item @code{GIMPLE_CALL} @tab x @tab x
|
|
@item @code{GIMPLE_CATCH} @tab x @tab
|
|
@item @code{GIMPLE_COND} @tab x @tab x
|
|
@item @code{GIMPLE_DEBUG} @tab x @tab x
|
|
@item @code{GIMPLE_EH_FILTER} @tab x @tab
|
|
@item @code{GIMPLE_GOTO} @tab x @tab x
|
|
@item @code{GIMPLE_LABEL} @tab x @tab x
|
|
@item @code{GIMPLE_NOP} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_ATOMIC_LOAD} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_ATOMIC_STORE} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_CONTINUE} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_CRITICAL} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_FOR} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_MASTER} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_ORDERED} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_PARALLEL} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_RETURN} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_SECTION} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_SECTIONS} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_SECTIONS_SWITCH} @tab x @tab x
|
|
@item @code{GIMPLE_OMP_SINGLE} @tab x @tab x
|
|
@item @code{GIMPLE_PHI} @tab @tab x
|
|
@item @code{GIMPLE_RESX} @tab @tab x
|
|
@item @code{GIMPLE_RETURN} @tab x @tab x
|
|
@item @code{GIMPLE_SWITCH} @tab x @tab x
|
|
@item @code{GIMPLE_TRY} @tab x @tab
|
|
@end multitable
|
|
|
|
@node GIMPLE Exception Handling
|
|
@section Exception Handling
|
|
@cindex GIMPLE Exception Handling
|
|
|
|
Other exception handling constructs are represented using
|
|
@code{GIMPLE_TRY_CATCH}. @code{GIMPLE_TRY_CATCH} has two operands. The
|
|
first operand is a sequence of statements to execute. If executing
|
|
these statements does not throw an exception, then the second operand
|
|
is ignored. Otherwise, if an exception is thrown, then the second
|
|
operand of the @code{GIMPLE_TRY_CATCH} is checked. The second
|
|
operand may have the following forms:
|
|
|
|
@enumerate
|
|
|
|
@item A sequence of statements to execute. When an exception occurs,
|
|
these statements are executed, and then the exception is rethrown.
|
|
|
|
@item A sequence of @code{GIMPLE_CATCH} statements. Each
|
|
@code{GIMPLE_CATCH} has a list of applicable exception types and
|
|
handler code. If the thrown exception matches one of the caught
|
|
types, the associated handler code is executed. If the handler
|
|
code falls off the bottom, execution continues after the original
|
|
@code{GIMPLE_TRY_CATCH}.
|
|
|
|
@item A @code{GIMPLE_EH_FILTER} statement. This has a list of
|
|
permitted exception types, and code to handle a match failure. If the
|
|
thrown exception does not match one of the allowed types, the
|
|
associated match failure code is executed. If the thrown exception
|
|
does match, it continues unwinding the stack looking for the next
|
|
handler.
|
|
|
|
@end enumerate
|
|
|
|
Currently throwing an exception is not directly represented in
|
|
GIMPLE, since it is implemented by calling a function. At some
|
|
point in the future we will want to add some way to express that
|
|
the call will throw an exception of a known type.
|
|
|
|
Just before running the optimizers, the compiler lowers the
|
|
high-level EH constructs above into a set of @samp{goto}s, magic
|
|
labels, and EH regions. Continuing to unwind at the end of a
|
|
cleanup is represented with a @code{GIMPLE_RESX}.
|
|
|
|
|
|
@node Temporaries
|
|
@section Temporaries
|
|
@cindex Temporaries
|
|
|
|
When gimplification encounters a subexpression that is too
|
|
complex, it creates a new temporary variable to hold the value of
|
|
the subexpression, and adds a new statement to initialize it
|
|
before the current statement. These special temporaries are known
|
|
as @samp{expression temporaries}, and are allocated using
|
|
@code{get_formal_tmp_var}. The compiler tries to always evaluate
|
|
identical expressions into the same temporary, to simplify
|
|
elimination of redundant calculations.
|
|
|
|
We can only use expression temporaries when we know that it will
|
|
not be reevaluated before its value is used, and that it will not
|
|
be otherwise modified@footnote{These restrictions are derived
|
|
from those in Morgan 4.8.}. Other temporaries can be allocated
|
|
using @code{get_initialized_tmp_var} or @code{create_tmp_var}.
|
|
|
|
Currently, an expression like @code{a = b + 5} is not reduced any
|
|
further. We tried converting it to something like
|
|
@smallexample
|
|
T1 = b + 5;
|
|
a = T1;
|
|
@end smallexample
|
|
but this bloated the representation for minimal benefit. However, a
|
|
variable which must live in memory cannot appear in an expression; its
|
|
value is explicitly loaded into a temporary first. Similarly, storing
|
|
the value of an expression to a memory variable goes through a
|
|
temporary.
|
|
|
|
@node Operands
|
|
@section Operands
|
|
@cindex Operands
|
|
|
|
In general, expressions in GIMPLE consist of an operation and the
|
|
appropriate number of simple operands; these operands must either be a
|
|
GIMPLE rvalue (@code{is_gimple_val}), i.e.@: a constant or a register
|
|
variable. More complex operands are factored out into temporaries, so
|
|
that
|
|
@smallexample
|
|
a = b + c + d
|
|
@end smallexample
|
|
becomes
|
|
@smallexample
|
|
T1 = b + c;
|
|
a = T1 + d;
|
|
@end smallexample
|
|
|
|
The same rule holds for arguments to a @code{GIMPLE_CALL}.
|
|
|
|
The target of an assignment is usually a variable, but can also be a
|
|
@code{MEM_REF} or a compound lvalue as described below.
|
|
|
|
@menu
|
|
* Compound Expressions::
|
|
* Compound Lvalues::
|
|
* Conditional Expressions::
|
|
* Logical Operators::
|
|
@end menu
|
|
|
|
@node Compound Expressions
|
|
@subsection Compound Expressions
|
|
@cindex Compound Expressions
|
|
|
|
The left-hand side of a C comma expression is simply moved into a separate
|
|
statement.
|
|
|
|
@node Compound Lvalues
|
|
@subsection Compound Lvalues
|
|
@cindex Compound Lvalues
|
|
|
|
Currently compound lvalues involving array and structure field references
|
|
are not broken down; an expression like @code{a.b[2] = 42} is not reduced
|
|
any further (though complex array subscripts are). This restriction is a
|
|
workaround for limitations in later optimizers; if we were to convert this
|
|
to
|
|
|
|
@smallexample
|
|
T1 = &a.b;
|
|
T1[2] = 42;
|
|
@end smallexample
|
|
|
|
alias analysis would not remember that the reference to @code{T1[2]} came
|
|
by way of @code{a.b}, so it would think that the assignment could alias
|
|
another member of @code{a}; this broke @code{struct-alias-1.c}. Future
|
|
optimizer improvements may make this limitation unnecessary.
|
|
|
|
@node Conditional Expressions
|
|
@subsection Conditional Expressions
|
|
@cindex Conditional Expressions
|
|
|
|
A C @code{?:} expression is converted into an @code{if} statement with
|
|
each branch assigning to the same temporary. So,
|
|
|
|
@smallexample
|
|
a = b ? c : d;
|
|
@end smallexample
|
|
becomes
|
|
@smallexample
|
|
if (b == 1)
|
|
T1 = c;
|
|
else
|
|
T1 = d;
|
|
a = T1;
|
|
@end smallexample
|
|
|
|
The GIMPLE level if-conversion pass re-introduces @code{?:}
|
|
expression, if appropriate. It is used to vectorize loops with
|
|
conditions using vector conditional operations.
|
|
|
|
Note that in GIMPLE, @code{if} statements are represented using
|
|
@code{GIMPLE_COND}, as described below.
|
|
|
|
@node Logical Operators
|
|
@subsection Logical Operators
|
|
@cindex Logical Operators
|
|
|
|
Except when they appear in the condition operand of a
|
|
@code{GIMPLE_COND}, logical `and' and `or' operators are simplified
|
|
as follows: @code{a = b && c} becomes
|
|
|
|
@smallexample
|
|
T1 = (bool)b;
|
|
if (T1 == true)
|
|
T1 = (bool)c;
|
|
a = T1;
|
|
@end smallexample
|
|
|
|
Note that @code{T1} in this example cannot be an expression temporary,
|
|
because it has two different assignments.
|
|
|
|
@subsection Manipulating operands
|
|
|
|
All gimple operands are of type @code{tree}. But only certain
|
|
types of trees are allowed to be used as operand tuples. Basic
|
|
validation is controlled by the function
|
|
@code{get_gimple_rhs_class}, which given a tree code, returns an
|
|
@code{enum} with the following values of type @code{enum
|
|
gimple_rhs_class}
|
|
|
|
@itemize @bullet
|
|
@item @code{GIMPLE_INVALID_RHS}
|
|
The tree cannot be used as a GIMPLE operand.
|
|
|
|
@item @code{GIMPLE_TERNARY_RHS}
|
|
The tree is a valid GIMPLE ternary operation.
|
|
|
|
@item @code{GIMPLE_BINARY_RHS}
|
|
The tree is a valid GIMPLE binary operation.
|
|
|
|
@item @code{GIMPLE_UNARY_RHS}
|
|
The tree is a valid GIMPLE unary operation.
|
|
|
|
@item @code{GIMPLE_SINGLE_RHS}
|
|
The tree is a single object, that cannot be split into simpler
|
|
operands (for instance, @code{SSA_NAME}, @code{VAR_DECL}, @code{COMPONENT_REF}, etc).
|
|
|
|
This operand class also acts as an escape hatch for tree nodes
|
|
that may be flattened out into the operand vector, but would need
|
|
more than two slots on the RHS. For instance, a @code{COND_EXPR}
|
|
expression of the form @code{(a op b) ? x : y} could be flattened
|
|
out on the operand vector using 4 slots, but it would also
|
|
require additional processing to distinguish @code{c = a op b}
|
|
from @code{c = a op b ? x : y}. Something similar occurs with
|
|
@code{ASSERT_EXPR}. In time, these special case tree
|
|
expressions should be flattened into the operand vector.
|
|
@end itemize
|
|
|
|
For tree nodes in the categories @code{GIMPLE_TERNARY_RHS},
|
|
@code{GIMPLE_BINARY_RHS} and @code{GIMPLE_UNARY_RHS}, they cannot be
|
|
stored inside tuples directly. They first need to be flattened and
|
|
separated into individual components. For instance, given the GENERIC
|
|
expression
|
|
|
|
@smallexample
|
|
a = b + c
|
|
@end smallexample
|
|
|
|
its tree representation is:
|
|
|
|
@smallexample
|
|
MODIFY_EXPR <VAR_DECL <a>, PLUS_EXPR <VAR_DECL <b>, VAR_DECL <c>>>
|
|
@end smallexample
|
|
|
|
In this case, the GIMPLE form for this statement is logically
|
|
identical to its GENERIC form but in GIMPLE, the @code{PLUS_EXPR}
|
|
on the RHS of the assignment is not represented as a tree,
|
|
instead the two operands are taken out of the @code{PLUS_EXPR} sub-tree
|
|
and flattened into the GIMPLE tuple as follows:
|
|
|
|
@smallexample
|
|
GIMPLE_ASSIGN <PLUS_EXPR, VAR_DECL <a>, VAR_DECL <b>, VAR_DECL <c>>
|
|
@end smallexample
|
|
|
|
@subsection Operand vector allocation
|
|
|
|
The operand vector is stored at the bottom of the three tuple
|
|
structures that accept operands. This means, that depending on
|
|
the code of a given statement, its operand vector will be at
|
|
different offsets from the base of the structure. To access
|
|
tuple operands use the following accessors
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_num_ops (gimple g)
|
|
Returns the number of operands in statement G.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_op (gimple g, unsigned i)
|
|
Returns operand @code{I} from statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_ops (gimple g)
|
|
Returns a pointer into the operand vector for statement @code{G}. This
|
|
is computed using an internal table called @code{gimple_ops_offset_}[].
|
|
This table is indexed by the gimple code of @code{G}.
|
|
|
|
When the compiler is built, this table is filled-in using the
|
|
sizes of the structures used by each statement code defined in
|
|
gimple.def. Since the operand vector is at the bottom of the
|
|
structure, for a gimple code @code{C} the offset is computed as sizeof
|
|
(struct-of @code{C}) - sizeof (tree).
|
|
|
|
This mechanism adds one memory indirection to every access when
|
|
using @code{gimple_op}(), if this becomes a bottleneck, a pass can
|
|
choose to memoize the result from @code{gimple_ops}() and use that to
|
|
access the operands.
|
|
@end deftypefn
|
|
|
|
@subsection Operand validation
|
|
|
|
When adding a new operand to a gimple statement, the operand will
|
|
be validated according to what each tuple accepts in its operand
|
|
vector. These predicates are called by the
|
|
@code{gimple_@var{name}_set_...()}. Each tuple will use one of the
|
|
following predicates (Note, this list is not exhaustive):
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_val (tree t)
|
|
Returns true if t is a "GIMPLE value", which are all the
|
|
non-addressable stack variables (variables for which
|
|
@code{is_gimple_reg} returns true) and constants (expressions for which
|
|
@code{is_gimple_min_invariant} returns true).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_addressable (tree t)
|
|
Returns true if t is a symbol or memory reference whose address
|
|
can be taken.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_asm_val (tree t)
|
|
Similar to @code{is_gimple_val} but it also accepts hard registers.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_call_addr (tree t)
|
|
Return true if t is a valid expression to use as the function
|
|
called by a @code{GIMPLE_CALL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_mem_ref_addr (tree t)
|
|
Return true if t is a valid expression to use as first operand
|
|
of a @code{MEM_REF} expression.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_constant (tree t)
|
|
Return true if t is a valid gimple constant.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_min_invariant (tree t)
|
|
Return true if t is a valid minimal invariant. This is different
|
|
from constants, in that the specific value of t may not be known
|
|
at compile time, but it is known that it doesn't change (e.g.,
|
|
the address of a function local variable).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_ip_invariant (tree t)
|
|
Return true if t is an interprocedural invariant. This means that t
|
|
is a valid invariant in all functions (e.g.@: it can be an address of a
|
|
global variable but not of a local one).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_ip_invariant_address (tree t)
|
|
Return true if t is an @code{ADDR_EXPR} that does not change once the
|
|
program is running (and which is valid in all functions).
|
|
@end deftypefn
|
|
|
|
|
|
@subsection Statement validation
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_assign (gimple g)
|
|
Return true if the code of g is @code{GIMPLE_ASSIGN}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_call (gimple g)
|
|
Return true if the code of g is @code{GIMPLE_CALL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_debug (gimple g)
|
|
Return true if the code of g is @code{GIMPLE_DEBUG}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_assign_cast_p (const_gimple g)
|
|
Return true if g is a @code{GIMPLE_ASSIGN} that performs a type cast
|
|
operation.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_debug_bind_p (gimple g)
|
|
Return true if g is a @code{GIMPLE_DEBUG} that binds the value of an
|
|
expression to a variable.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool is_gimple_omp (gimple g)
|
|
Return true if g is any of the OpenMP codes.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_debug_begin_stmt_p (gimple g)
|
|
Return true if g is a @code{GIMPLE_DEBUG} that marks the beginning of
|
|
a source statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_debug_inline_entry_p (gimple g)
|
|
Return true if g is a @code{GIMPLE_DEBUG} that marks the entry
|
|
point of an inlined function.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_debug_nonbind_marker_p (gimple g)
|
|
Return true if g is a @code{GIMPLE_DEBUG} that marks a program location,
|
|
without any variable binding.
|
|
@end deftypefn
|
|
|
|
@node Manipulating GIMPLE statements
|
|
@section Manipulating GIMPLE statements
|
|
@cindex Manipulating GIMPLE statements
|
|
|
|
This section documents all the functions available to handle each
|
|
of the GIMPLE instructions.
|
|
|
|
@subsection Common accessors
|
|
The following are common accessors for gimple statements.
|
|
|
|
@deftypefn {GIMPLE function} {enum gimple_code} gimple_code (gimple g)
|
|
Return the code for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} basic_block gimple_bb (gimple g)
|
|
Return the basic block to which statement @code{G} belongs to.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_block (gimple g)
|
|
Return the lexical scope block holding statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_expr_type (gimple stmt)
|
|
Return the type of the main expression computed by @code{STMT}. Return
|
|
@code{void_type_node} if @code{STMT} computes nothing. This will only return
|
|
something meaningful for @code{GIMPLE_ASSIGN}, @code{GIMPLE_COND} and
|
|
@code{GIMPLE_CALL}. For all other tuple codes, it will return
|
|
@code{void_type_node}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {enum tree_code} gimple_expr_code (gimple stmt)
|
|
Return the tree code for the expression computed by @code{STMT}. This
|
|
is only meaningful for @code{GIMPLE_CALL}, @code{GIMPLE_ASSIGN} and
|
|
@code{GIMPLE_COND}. If @code{STMT} is @code{GIMPLE_CALL}, it will return @code{CALL_EXPR}.
|
|
For @code{GIMPLE_COND}, it returns the code of the comparison predicate.
|
|
For @code{GIMPLE_ASSIGN} it returns the code of the operation performed
|
|
by the @code{RHS} of the assignment.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_block (gimple g, tree block)
|
|
Set the lexical scope block of @code{G} to @code{BLOCK}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} location_t gimple_locus (gimple g)
|
|
Return locus information for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_locus (gimple g, location_t locus)
|
|
Set locus information for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_locus_empty_p (gimple g)
|
|
Return true if @code{G} does not have locus information.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_no_warning_p (gimple stmt)
|
|
Return true if no warnings should be emitted for statement @code{STMT}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_visited (gimple stmt, bool visited_p)
|
|
Set the visited status on statement @code{STMT} to @code{VISITED_P}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_visited_p (gimple stmt)
|
|
Return the visited status on statement @code{STMT}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_plf (gimple stmt, enum plf_mask plf, bool val_p)
|
|
Set pass local flag @code{PLF} on statement @code{STMT} to @code{VAL_P}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {unsigned int} gimple_plf (gimple stmt, enum plf_mask plf)
|
|
Return the value of pass local flag @code{PLF} on statement @code{STMT}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_has_ops (gimple g)
|
|
Return true if statement @code{G} has register or memory operands.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_has_mem_ops (gimple g)
|
|
Return true if statement @code{G} has memory operands.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_num_ops (gimple g)
|
|
Return the number of operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_ops (gimple g)
|
|
Return the array of operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_op (gimple g, unsigned i)
|
|
Return operand @code{I} for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_op_ptr (gimple g, unsigned i)
|
|
Return a pointer to operand @code{I} for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_op (gimple g, unsigned i, tree op)
|
|
Set operand @code{I} of statement @code{G} to @code{OP}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bitmap gimple_addresses_taken (gimple stmt)
|
|
Return the set of symbols that have had their address taken by
|
|
@code{STMT}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {struct def_optype_d *} gimple_def_ops (gimple g)
|
|
Return the set of @code{DEF} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_def_ops (gimple g, struct def_optype_d *def)
|
|
Set @code{DEF} to be the set of @code{DEF} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {struct use_optype_d *} gimple_use_ops (gimple g)
|
|
Return the set of @code{USE} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_use_ops (gimple g, struct use_optype_d *use)
|
|
Set @code{USE} to be the set of @code{USE} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {struct voptype_d *} gimple_vuse_ops (gimple g)
|
|
Return the set of @code{VUSE} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_vuse_ops (gimple g, struct voptype_d *ops)
|
|
Set @code{OPS} to be the set of @code{VUSE} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {struct voptype_d *} gimple_vdef_ops (gimple g)
|
|
Return the set of @code{VDEF} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_vdef_ops (gimple g, struct voptype_d *ops)
|
|
Set @code{OPS} to be the set of @code{VDEF} operands for statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bitmap gimple_loaded_syms (gimple g)
|
|
Return the set of symbols loaded by statement @code{G}. Each element of
|
|
the set is the @code{DECL_UID} of the corresponding symbol.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bitmap gimple_stored_syms (gimple g)
|
|
Return the set of symbols stored by statement @code{G}. Each element of
|
|
the set is the @code{DECL_UID} of the corresponding symbol.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_modified_p (gimple g)
|
|
Return true if statement @code{G} has operands and the modified field
|
|
has been set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_has_volatile_ops (gimple stmt)
|
|
Return true if statement @code{STMT} contains volatile operands.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_set_has_volatile_ops (gimple stmt, bool volatilep)
|
|
Return true if statement @code{STMT} contains volatile operands.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void update_stmt (gimple s)
|
|
Mark statement @code{S} as modified, and update it.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void update_stmt_if_modified (gimple s)
|
|
Update statement @code{S} if it has been marked modified.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_copy (gimple stmt)
|
|
Return a deep copy of statement @code{STMT}.
|
|
@end deftypefn
|
|
|
|
@node Tuple specific accessors
|
|
@section Tuple specific accessors
|
|
@cindex Tuple specific accessors
|
|
|
|
@menu
|
|
* @code{GIMPLE_ASM}::
|
|
* @code{GIMPLE_ASSIGN}::
|
|
* @code{GIMPLE_BIND}::
|
|
* @code{GIMPLE_CALL}::
|
|
* @code{GIMPLE_CATCH}::
|
|
* @code{GIMPLE_COND}::
|
|
* @code{GIMPLE_DEBUG}::
|
|
* @code{GIMPLE_EH_FILTER}::
|
|
* @code{GIMPLE_LABEL}::
|
|
* @code{GIMPLE_GOTO}::
|
|
* @code{GIMPLE_NOP}::
|
|
* @code{GIMPLE_OMP_ATOMIC_LOAD}::
|
|
* @code{GIMPLE_OMP_ATOMIC_STORE}::
|
|
* @code{GIMPLE_OMP_CONTINUE}::
|
|
* @code{GIMPLE_OMP_CRITICAL}::
|
|
* @code{GIMPLE_OMP_FOR}::
|
|
* @code{GIMPLE_OMP_MASTER}::
|
|
* @code{GIMPLE_OMP_ORDERED}::
|
|
* @code{GIMPLE_OMP_PARALLEL}::
|
|
* @code{GIMPLE_OMP_RETURN}::
|
|
* @code{GIMPLE_OMP_SECTION}::
|
|
* @code{GIMPLE_OMP_SECTIONS}::
|
|
* @code{GIMPLE_OMP_SINGLE}::
|
|
* @code{GIMPLE_PHI}::
|
|
* @code{GIMPLE_RESX}::
|
|
* @code{GIMPLE_RETURN}::
|
|
* @code{GIMPLE_SWITCH}::
|
|
* @code{GIMPLE_TRY}::
|
|
* @code{GIMPLE_WITH_CLEANUP_EXPR}::
|
|
@end menu
|
|
|
|
|
|
@node @code{GIMPLE_ASM}
|
|
@subsection @code{GIMPLE_ASM}
|
|
@cindex @code{GIMPLE_ASM}
|
|
|
|
@deftypefn {GIMPLE function} gasm *gimple_build_asm_vec ( @
|
|
const char *string, vec<tree, va_gc> *inputs, @
|
|
vec<tree, va_gc> *outputs, vec<tree, va_gc> *clobbers, @
|
|
vec<tree, va_gc> *labels)
|
|
Build a @code{GIMPLE_ASM} statement. This statement is used for
|
|
building in-line assembly constructs. @code{STRING} is the assembly
|
|
code. @code{INPUTS}, @code{OUTPUTS}, @code{CLOBBERS} and @code{LABELS}
|
|
are the inputs, outputs, clobbered registers and labels.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_asm_ninputs (const gasm *g)
|
|
Return the number of input operands for @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_asm_noutputs (const gasm *g)
|
|
Return the number of output operands for @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_asm_nclobbers (const gasm *g)
|
|
Return the number of clobber operands for @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_asm_input_op (const gasm *g, @
|
|
unsigned index)
|
|
Return input operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_asm_set_input_op (gasm *g, @
|
|
unsigned index, tree in_op)
|
|
Set @code{IN_OP} to be input operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_asm_output_op (const gasm *g, @
|
|
unsigned index)
|
|
Return output operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_asm_set_output_op (gasm *g, @
|
|
unsigned index, tree out_op)
|
|
Set @code{OUT_OP} to be output operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_asm_clobber_op (const gasm *g, @
|
|
unsigned index)
|
|
Return clobber operand @code{INDEX} of @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_asm_set_clobber_op (gasm *g, @
|
|
unsigned index, tree clobber_op)
|
|
Set @code{CLOBBER_OP} to be clobber operand @code{INDEX} in @code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {const char *} gimple_asm_string (const gasm *g)
|
|
Return the string representing the assembly instruction in
|
|
@code{GIMPLE_ASM} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_asm_volatile_p (const gasm *g)
|
|
Return true if @code{G} is an asm statement marked volatile.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_asm_set_volatile (gasm *g, @
|
|
bool volatile_p)
|
|
Mark asm statement @code{G} as volatile or non-volatile based on
|
|
@code{VOLATILE_P}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_ASSIGN}
|
|
@subsection @code{GIMPLE_ASSIGN}
|
|
@cindex @code{GIMPLE_ASSIGN}
|
|
|
|
@deftypefn {GIMPLE function} gassign *gimple_build_assign (tree lhs, tree rhs)
|
|
Build a @code{GIMPLE_ASSIGN} statement. The left-hand side is an lvalue
|
|
passed in lhs. The right-hand side can be either a unary or
|
|
binary tree expression. The expression tree rhs will be
|
|
flattened and its operands assigned to the corresponding operand
|
|
slots in the new statement. This function is useful when you
|
|
already have a tree expression that you want to convert into a
|
|
tuple. However, try to avoid building expression trees for the
|
|
sole purpose of calling this function. If you already have the
|
|
operands in separate trees, it is better to use
|
|
@code{gimple_build_assign} with @code{enum tree_code} argument and separate
|
|
arguments for each operand.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gassign *gimple_build_assign @
|
|
(tree lhs, enum tree_code subcode, tree op1, tree op2, tree op3)
|
|
This function is similar to two operand @code{gimple_build_assign},
|
|
but is used to build a @code{GIMPLE_ASSIGN} statement when the operands of the
|
|
right-hand side of the assignment are already split into
|
|
different operands.
|
|
|
|
The left-hand side is an lvalue passed in lhs. Subcode is the
|
|
@code{tree_code} for the right-hand side of the assignment. Op1, op2 and op3
|
|
are the operands.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gassign *gimple_build_assign @
|
|
(tree lhs, enum tree_code subcode, tree op1, tree op2)
|
|
Like the above 5 operand @code{gimple_build_assign}, but with the last
|
|
argument @code{NULL} - this overload should not be used for
|
|
@code{GIMPLE_TERNARY_RHS} assignments.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gassign *gimple_build_assign @
|
|
(tree lhs, enum tree_code subcode, tree op1)
|
|
Like the above 4 operand @code{gimple_build_assign}, but with the last
|
|
argument @code{NULL} - this overload should be used only for
|
|
@code{GIMPLE_UNARY_RHS} and @code{GIMPLE_SINGLE_RHS} assignments.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
|
|
Build a new @code{GIMPLE_ASSIGN} tuple and append it to the end of
|
|
@code{*SEQ_P}.
|
|
@end deftypefn
|
|
|
|
@code{DST}/@code{SRC} are the destination and source respectively. You can
|
|
pass ungimplified trees in @code{DST} or @code{SRC}, in which
|
|
case they will be converted to a gimple operand if necessary.
|
|
|
|
This function returns the newly created @code{GIMPLE_ASSIGN} tuple.
|
|
|
|
@deftypefn {GIMPLE function} {enum tree_code} gimple_assign_rhs_code (gimple g)
|
|
Return the code of the expression computed on the @code{RHS} of
|
|
assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} {enum gimple_rhs_class} gimple_assign_rhs_class (gimple g)
|
|
Return the gimple rhs class of the code for the expression
|
|
computed on the rhs of assignment statement @code{G}. This will never
|
|
return @code{GIMPLE_INVALID_RHS}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_assign_lhs (gimple g)
|
|
Return the @code{LHS} of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_assign_lhs_ptr (gimple g)
|
|
Return a pointer to the @code{LHS} of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_assign_rhs1 (gimple g)
|
|
Return the first operand on the @code{RHS} of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_assign_rhs1_ptr (gimple g)
|
|
Return the address of the first operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_assign_rhs2 (gimple g)
|
|
Return the second operand on the @code{RHS} of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_assign_rhs2_ptr (gimple g)
|
|
Return the address of the second operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_assign_rhs3 (gimple g)
|
|
Return the third operand on the @code{RHS} of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_assign_rhs3_ptr (gimple g)
|
|
Return the address of the third operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_assign_set_lhs (gimple g, tree lhs)
|
|
Set @code{LHS} to be the @code{LHS} operand of assignment statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_assign_set_rhs1 (gimple g, tree rhs)
|
|
Set @code{RHS} to be the first operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_assign_set_rhs2 (gimple g, tree rhs)
|
|
Set @code{RHS} to be the second operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_assign_set_rhs3 (gimple g, tree rhs)
|
|
Set @code{RHS} to be the third operand on the @code{RHS} of assignment
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_assign_cast_p (const_gimple s)
|
|
Return true if @code{S} is a type-cast assignment.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_BIND}
|
|
@subsection @code{GIMPLE_BIND}
|
|
@cindex @code{GIMPLE_BIND}
|
|
|
|
@deftypefn {GIMPLE function} gbind *gimple_build_bind (tree vars, @
|
|
gimple_seq body)
|
|
Build a @code{GIMPLE_BIND} statement with a list of variables in @code{VARS}
|
|
and a body of statements in sequence @code{BODY}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_bind_vars (const gbind *g)
|
|
Return the variables declared in the @code{GIMPLE_BIND} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_set_vars (gbind *g, tree vars)
|
|
Set @code{VARS} to be the set of variables declared in the @code{GIMPLE_BIND}
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_append_vars (gbind *g, tree vars)
|
|
Append @code{VARS} to the set of variables declared in the @code{GIMPLE_BIND}
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_bind_body (gbind *g)
|
|
Return the GIMPLE sequence contained in the @code{GIMPLE_BIND} statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_set_body (gbind *g, @
|
|
gimple_seq seq)
|
|
Set @code{SEQ} to be sequence contained in the @code{GIMPLE_BIND} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_add_stmt (gbind *gs, gimple stmt)
|
|
Append a statement to the end of a @code{GIMPLE_BIND}'s body.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_add_seq (gbind *gs, @
|
|
gimple_seq seq)
|
|
Append a sequence of statements to the end of a @code{GIMPLE_BIND}'s
|
|
body.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_bind_block (const gbind *g)
|
|
Return the @code{TREE_BLOCK} node associated with @code{GIMPLE_BIND} statement
|
|
@code{G}. This is analogous to the @code{BIND_EXPR_BLOCK} field in trees.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_bind_set_block (gbind *g, tree block)
|
|
Set @code{BLOCK} to be the @code{TREE_BLOCK} node associated with @code{GIMPLE_BIND}
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_CALL}
|
|
@subsection @code{GIMPLE_CALL}
|
|
@cindex @code{GIMPLE_CALL}
|
|
|
|
@deftypefn {GIMPLE function} gcall *gimple_build_call (tree fn, @
|
|
unsigned nargs, ...)
|
|
Build a @code{GIMPLE_CALL} statement to function @code{FN}. The argument @code{FN}
|
|
must be either a @code{FUNCTION_DECL} or a gimple call address as
|
|
determined by @code{is_gimple_call_addr}. @code{NARGS} are the number of
|
|
arguments. The rest of the arguments follow the argument @code{NARGS},
|
|
and must be trees that are valid as rvalues in gimple (i.e., each
|
|
operand is validated with @code{is_gimple_operand}).
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} gcall *gimple_build_call_from_tree (tree call_expr, @
|
|
tree fnptrtype)
|
|
Build a @code{GIMPLE_CALL} from a @code{CALL_EXPR} node. The arguments
|
|
and the function are taken from the expression directly. The type of the
|
|
@code{GIMPLE_CALL} is set from the second parameter passed by a caller.
|
|
This routine assumes that @code{call_expr} is already in GIMPLE form.
|
|
That is, its operands are GIMPLE values and the function call needs no further
|
|
simplification. All the call flags in @code{call_expr} are copied over
|
|
to the new @code{GIMPLE_CALL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gcall *gimple_build_call_vec (tree fn, @
|
|
@code{vec<tree>} args)
|
|
Identical to @code{gimple_build_call} but the arguments are stored in a
|
|
@code{vec<tree>}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_lhs (gimple g)
|
|
Return the @code{LHS} of call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_call_lhs_ptr (gimple g)
|
|
Return a pointer to the @code{LHS} of call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_call_set_lhs (gimple g, tree lhs)
|
|
Set @code{LHS} to be the @code{LHS} operand of call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_fn (gimple g)
|
|
Return the tree node representing the function called by call
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_call_set_fn (gcall *g, tree fn)
|
|
Set @code{FN} to be the function called by call statement @code{G}. This has
|
|
to be a gimple value specifying the address of the called
|
|
function.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_fndecl (gimple g)
|
|
If a given @code{GIMPLE_CALL}'s callee is a @code{FUNCTION_DECL}, return it.
|
|
Otherwise return @code{NULL}. This function is analogous to
|
|
@code{get_callee_fndecl} in @code{GENERIC}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_set_fndecl (gimple g, tree fndecl)
|
|
Set the called function to @code{FNDECL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_return_type (const gcall *g)
|
|
Return the type returned by call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_chain (gimple g)
|
|
Return the static chain for call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_call_set_chain (gcall *g, tree chain)
|
|
Set @code{CHAIN} to be the static chain for call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_call_num_args (gimple g)
|
|
Return the number of arguments used by call statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_call_arg (gimple g, unsigned index)
|
|
Return the argument at position @code{INDEX} for call statement @code{G}. The
|
|
first argument is 0.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_call_arg_ptr (gimple g, unsigned index)
|
|
Return a pointer to the argument at position @code{INDEX} for call
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_call_set_arg (gimple g, unsigned index, tree arg)
|
|
Set @code{ARG} to be the argument at position @code{INDEX} for call statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_call_set_tail (gcall *s)
|
|
Mark call statement @code{S} as being a tail call (i.e., a call just
|
|
before the exit of a function). These calls are candidate for
|
|
tail call optimization.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_call_tail_p (gcall *s)
|
|
Return true if @code{GIMPLE_CALL} @code{S} is marked as a tail call.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_call_noreturn_p (gimple s)
|
|
Return true if @code{S} is a noreturn call.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_call_copy_skip_args (gcall *stmt, @
|
|
bitmap args_to_skip)
|
|
Build a @code{GIMPLE_CALL} identical to @code{STMT} but skipping the arguments
|
|
in the positions marked by the set @code{ARGS_TO_SKIP}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_CATCH}
|
|
@subsection @code{GIMPLE_CATCH}
|
|
@cindex @code{GIMPLE_CATCH}
|
|
|
|
@deftypefn {GIMPLE function} gcatch *gimple_build_catch (tree types, @
|
|
gimple_seq handler)
|
|
Build a @code{GIMPLE_CATCH} statement. @code{TYPES} are the tree types this
|
|
catch handles. @code{HANDLER} is a sequence of statements with the code
|
|
for the handler.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_catch_types (const gcatch *g)
|
|
Return the types handled by @code{GIMPLE_CATCH} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_catch_types_ptr (gcatch *g)
|
|
Return a pointer to the types handled by @code{GIMPLE_CATCH} statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_catch_handler (gcatch *g)
|
|
Return the GIMPLE sequence representing the body of the handler
|
|
of @code{GIMPLE_CATCH} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_catch_set_types (gcatch *g, tree t)
|
|
Set @code{T} to be the set of types handled by @code{GIMPLE_CATCH} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_catch_set_handler (gcatch *g, @
|
|
gimple_seq handler)
|
|
Set @code{HANDLER} to be the body of @code{GIMPLE_CATCH} @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_COND}
|
|
@subsection @code{GIMPLE_COND}
|
|
@cindex @code{GIMPLE_COND}
|
|
|
|
@deftypefn {GIMPLE function} gcond *gimple_build_cond ( @
|
|
enum tree_code pred_code, tree lhs, tree rhs, tree t_label, tree f_label)
|
|
Build a @code{GIMPLE_COND} statement. @code{A} @code{GIMPLE_COND} statement compares
|
|
@code{LHS} and @code{RHS} and if the condition in @code{PRED_CODE} is true, jump to
|
|
the label in @code{t_label}, otherwise jump to the label in @code{f_label}.
|
|
@code{PRED_CODE} are relational operator tree codes like @code{EQ_EXPR},
|
|
@code{LT_EXPR}, @code{LE_EXPR}, @code{NE_EXPR}, etc.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} gcond *gimple_build_cond_from_tree (tree cond, @
|
|
tree t_label, tree f_label)
|
|
Build a @code{GIMPLE_COND} statement from the conditional expression
|
|
tree @code{COND}. @code{T_LABEL} and @code{F_LABEL} are as in @code{gimple_build_cond}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {enum tree_code} gimple_cond_code (gimple g)
|
|
Return the code of the predicate computed by conditional
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_set_code (gcond *g, @
|
|
enum tree_code code)
|
|
Set @code{CODE} to be the predicate code for the conditional statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_cond_lhs (gimple g)
|
|
Return the @code{LHS} of the predicate computed by conditional statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_set_lhs (gcond *g, tree lhs)
|
|
Set @code{LHS} to be the @code{LHS} operand of the predicate computed by
|
|
conditional statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_cond_rhs (gimple g)
|
|
Return the @code{RHS} operand of the predicate computed by conditional
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_set_rhs (gcond *g, tree rhs)
|
|
Set @code{RHS} to be the @code{RHS} operand of the predicate computed by
|
|
conditional statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_cond_true_label (const gcond *g)
|
|
Return the label used by conditional statement @code{G} when its
|
|
predicate evaluates to true.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_set_true_label (gcond *g, tree label)
|
|
Set @code{LABEL} to be the label used by conditional statement @code{G} when
|
|
its predicate evaluates to true.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_set_false_label (gcond *g, tree label)
|
|
Set @code{LABEL} to be the label used by conditional statement @code{G} when
|
|
its predicate evaluates to false.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_cond_false_label (const gcond *g)
|
|
Return the label used by conditional statement @code{G} when its
|
|
predicate evaluates to false.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_make_false (gcond *g)
|
|
Set the conditional @code{COND_STMT} to be of the form 'if (1 == 0)'.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_cond_make_true (gcond *g)
|
|
Set the conditional @code{COND_STMT} to be of the form 'if (1 == 1)'.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_DEBUG}
|
|
@subsection @code{GIMPLE_DEBUG}
|
|
@cindex @code{GIMPLE_DEBUG}
|
|
@cindex @code{GIMPLE_DEBUG_BIND}
|
|
@cindex @code{GIMPLE_DEBUG_BEGIN_STMT}
|
|
@cindex @code{GIMPLE_DEBUG_INLINE_ENTRY}
|
|
|
|
@deftypefn {GIMPLE function} gdebug *gimple_build_debug_bind (tree var, @
|
|
tree value, gimple stmt)
|
|
Build a @code{GIMPLE_DEBUG} statement with @code{GIMPLE_DEBUG_BIND}
|
|
@code{subcode}. The effect of this statement is to tell debug
|
|
information generation machinery that the value of user variable
|
|
@code{var} is given by @code{value} at that point, and to remain with
|
|
that value until @code{var} runs out of scope, a
|
|
dynamically-subsequent debug bind statement overrides the binding, or
|
|
conflicting values reach a control flow merge point. Even if
|
|
components of the @code{value} expression change afterwards, the
|
|
variable is supposed to retain the same value, though not necessarily
|
|
the same location.
|
|
|
|
It is expected that @code{var} be most often a tree for automatic user
|
|
variables (@code{VAR_DECL} or @code{PARM_DECL}) that satisfy the
|
|
requirements for gimple registers, but it may also be a tree for a
|
|
scalarized component of a user variable (@code{ARRAY_REF},
|
|
@code{COMPONENT_REF}), or a debug temporary (@code{DEBUG_EXPR_DECL}).
|
|
|
|
As for @code{value}, it can be an arbitrary tree expression, but it is
|
|
recommended that it be in a suitable form for a gimple assignment
|
|
@code{RHS}. It is not expected that user variables that could appear
|
|
as @code{var} ever appear in @code{value}, because in the latter we'd
|
|
have their @code{SSA_NAME}s instead, but even if they were not in SSA
|
|
form, user variables appearing in @code{value} are to be regarded as
|
|
part of the executable code space, whereas those in @code{var} are to
|
|
be regarded as part of the source code space. There is no way to
|
|
refer to the value bound to a user variable within a @code{value}
|
|
expression.
|
|
|
|
If @code{value} is @code{GIMPLE_DEBUG_BIND_NOVALUE}, debug information
|
|
generation machinery is informed that the variable @code{var} is
|
|
unbound, i.e., that its value is indeterminate, which sometimes means
|
|
it is really unavailable, and other times that the compiler could not
|
|
keep track of it.
|
|
|
|
Block and location information for the newly-created stmt are
|
|
taken from @code{stmt}, if given.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_debug_bind_get_var (gimple stmt)
|
|
Return the user variable @var{var} that is bound at @code{stmt}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_debug_bind_get_value (gimple stmt)
|
|
Return the value expression that is bound to a user variable at
|
|
@code{stmt}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_debug_bind_get_value_ptr (gimple stmt)
|
|
Return a pointer to the value expression that is bound to a user
|
|
variable at @code{stmt}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_debug_bind_set_var (gimple stmt, tree var)
|
|
Modify the user variable bound at @code{stmt} to @var{var}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_debug_bind_set_value (gimple stmt, tree var)
|
|
Modify the value bound to the user variable bound at @code{stmt} to
|
|
@var{value}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_debug_bind_reset_value (gimple stmt)
|
|
Modify the value bound to the user variable bound at @code{stmt} so
|
|
that the variable becomes unbound.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_debug_bind_has_value_p (gimple stmt)
|
|
Return @code{TRUE} if @code{stmt} binds a user variable to a value,
|
|
and @code{FALSE} if it unbinds the variable.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_debug_begin_stmt (tree block, location_t location)
|
|
Build a @code{GIMPLE_DEBUG} statement with
|
|
@code{GIMPLE_DEBUG_BEGIN_STMT} @code{subcode}. The effect of this
|
|
statement is to tell debug information generation machinery that the
|
|
user statement at the given @code{location} and @code{block} starts at
|
|
the point at which the statement is inserted. The intent is that side
|
|
effects (e.g.@: variable bindings) of all prior user statements are
|
|
observable, and that none of the side effects of subsequent user
|
|
statements are.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_debug_inline_entry (tree block, location_t location)
|
|
Build a @code{GIMPLE_DEBUG} statement with
|
|
@code{GIMPLE_DEBUG_INLINE_ENTRY} @code{subcode}. The effect of this
|
|
statement is to tell debug information generation machinery that a
|
|
function call at @code{location} underwent inline substitution, that
|
|
@code{block} is the enclosing lexical block created for the
|
|
substitution, and that at the point of the program in which the stmt is
|
|
inserted, all parameters for the inlined function are bound to the
|
|
respective arguments, and none of the side effects of its stmts are
|
|
observable.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_EH_FILTER}
|
|
@subsection @code{GIMPLE_EH_FILTER}
|
|
@cindex @code{GIMPLE_EH_FILTER}
|
|
|
|
@deftypefn {GIMPLE function} geh_filter *gimple_build_eh_filter (tree types, @
|
|
gimple_seq failure)
|
|
Build a @code{GIMPLE_EH_FILTER} statement. @code{TYPES} are the filter's
|
|
types. @code{FAILURE} is a sequence with the filter's failure action.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_eh_filter_types (gimple g)
|
|
Return the types handled by @code{GIMPLE_EH_FILTER} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_eh_filter_types_ptr (gimple g)
|
|
Return a pointer to the types handled by @code{GIMPLE_EH_FILTER}
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_eh_filter_failure (gimple g)
|
|
Return the sequence of statement to execute when @code{GIMPLE_EH_FILTER}
|
|
statement fails.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_eh_filter_set_types (geh_filter *g, @
|
|
tree types)
|
|
Set @code{TYPES} to be the set of types handled by @code{GIMPLE_EH_FILTER} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_eh_filter_set_failure (geh_filter *g, @
|
|
gimple_seq failure)
|
|
Set @code{FAILURE} to be the sequence of statements to execute on
|
|
failure for @code{GIMPLE_EH_FILTER} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_eh_must_not_throw_fndecl ( @
|
|
geh_mnt *eh_mnt_stmt)
|
|
Get the function decl to be called by the MUST_NOT_THROW region.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_eh_must_not_throw_set_fndecl ( @
|
|
geh_mnt *eh_mnt_stmt, tree decl)
|
|
Set the function decl to be called by GS to DECL.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_LABEL}
|
|
@subsection @code{GIMPLE_LABEL}
|
|
@cindex @code{GIMPLE_LABEL}
|
|
|
|
@deftypefn {GIMPLE function} glabel *gimple_build_label (tree label)
|
|
Build a @code{GIMPLE_LABEL} statement with corresponding to the tree
|
|
label, @code{LABEL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_label_label (const glabel *g)
|
|
Return the @code{LABEL_DECL} node used by @code{GIMPLE_LABEL} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_label_set_label (glabel *g, tree label)
|
|
Set @code{LABEL} to be the @code{LABEL_DECL} node used by @code{GIMPLE_LABEL}
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_GOTO}
|
|
@subsection @code{GIMPLE_GOTO}
|
|
@cindex @code{GIMPLE_GOTO}
|
|
|
|
@deftypefn {GIMPLE function} ggoto *gimple_build_goto (tree dest)
|
|
Build a @code{GIMPLE_GOTO} statement to label @code{DEST}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_goto_dest (gimple g)
|
|
Return the destination of the unconditional jump @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_goto_set_dest (ggoto *g, tree dest)
|
|
Set @code{DEST} to be the destination of the unconditional jump @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_NOP}
|
|
@subsection @code{GIMPLE_NOP}
|
|
@cindex @code{GIMPLE_NOP}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_nop (void)
|
|
Build a @code{GIMPLE_NOP} statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_nop_p (gimple g)
|
|
Returns @code{TRUE} if statement @code{G} is a @code{GIMPLE_NOP}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_OMP_ATOMIC_LOAD}
|
|
@subsection @code{GIMPLE_OMP_ATOMIC_LOAD}
|
|
@cindex @code{GIMPLE_OMP_ATOMIC_LOAD}
|
|
|
|
@deftypefn {GIMPLE function} gomp_atomic_load *gimple_build_omp_atomic_load ( @
|
|
tree lhs, tree rhs)
|
|
Build a @code{GIMPLE_OMP_ATOMIC_LOAD} statement. @code{LHS} is the left-hand
|
|
side of the assignment. @code{RHS} is the right-hand side of the
|
|
assignment.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_atomic_load_set_lhs ( @
|
|
gomp_atomic_load *g, tree lhs)
|
|
Set the @code{LHS} of an atomic load.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_atomic_load_lhs ( @
|
|
const gomp_atomic_load *g)
|
|
Get the @code{LHS} of an atomic load.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_atomic_load_set_rhs ( @
|
|
gomp_atomic_load *g, tree rhs)
|
|
Set the @code{RHS} of an atomic set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_atomic_load_rhs ( @
|
|
const gomp_atomic_load *g)
|
|
Get the @code{RHS} of an atomic set.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_ATOMIC_STORE}
|
|
@subsection @code{GIMPLE_OMP_ATOMIC_STORE}
|
|
@cindex @code{GIMPLE_OMP_ATOMIC_STORE}
|
|
|
|
@deftypefn {GIMPLE function} gomp_atomic_store *gimple_build_omp_atomic_store ( @
|
|
tree val)
|
|
Build a @code{GIMPLE_OMP_ATOMIC_STORE} statement. @code{VAL} is the value to be
|
|
stored.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_atomic_store_set_val ( @
|
|
gomp_atomic_store *g, tree val)
|
|
Set the value being stored in an atomic store.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_atomic_store_val ( @
|
|
const gomp_atomic_store *g)
|
|
Return the value being stored in an atomic store.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_OMP_CONTINUE}
|
|
@subsection @code{GIMPLE_OMP_CONTINUE}
|
|
@cindex @code{GIMPLE_OMP_CONTINUE}
|
|
|
|
@deftypefn {GIMPLE function} gomp_continue *gimple_build_omp_continue ( @
|
|
tree control_def, tree control_use)
|
|
Build a @code{GIMPLE_OMP_CONTINUE} statement. @code{CONTROL_DEF} is the
|
|
definition of the control variable. @code{CONTROL_USE} is the use of
|
|
the control variable.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_control_def ( @
|
|
const gomp_continue *s)
|
|
Return the definition of the control variable on a
|
|
@code{GIMPLE_OMP_CONTINUE} in @code{S}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_control_def_ptr ( @
|
|
gomp_continue *s)
|
|
Same as above, but return the pointer.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_set_control_def ( @
|
|
gomp_continue *s)
|
|
Set the control variable definition for a @code{GIMPLE_OMP_CONTINUE}
|
|
statement in @code{S}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_control_use ( @
|
|
const gomp_continue *s)
|
|
Return the use of the control variable on a @code{GIMPLE_OMP_CONTINUE}
|
|
in @code{S}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_control_use_ptr ( @
|
|
gomp_continue *s)
|
|
Same as above, but return the pointer.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_continue_set_control_use ( @
|
|
gomp_continue *s)
|
|
Set the control variable use for a @code{GIMPLE_OMP_CONTINUE} statement
|
|
in @code{S}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_CRITICAL}
|
|
@subsection @code{GIMPLE_OMP_CRITICAL}
|
|
@cindex @code{GIMPLE_OMP_CRITICAL}
|
|
|
|
@deftypefn {GIMPLE function} gomp_critical *gimple_build_omp_critical ( @
|
|
gimple_seq body, tree name)
|
|
Build a @code{GIMPLE_OMP_CRITICAL} statement. @code{BODY} is the sequence of
|
|
statements for which only one thread can execute. @code{NAME} is an
|
|
optional identifier for this critical block.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_critical_name ( @
|
|
const gomp_critical *g)
|
|
Return the name associated with @code{OMP_CRITICAL} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_critical_name_ptr ( @
|
|
gomp_critical *g)
|
|
Return a pointer to the name associated with @code{OMP} critical
|
|
statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_critical_set_name ( @
|
|
gomp_critical *g, tree name)
|
|
Set @code{NAME} to be the name associated with @code{OMP} critical statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_OMP_FOR}
|
|
@subsection @code{GIMPLE_OMP_FOR}
|
|
@cindex @code{GIMPLE_OMP_FOR}
|
|
|
|
@deftypefn {GIMPLE function} gomp_for *gimple_build_omp_for (gimple_seq body, @
|
|
tree clauses, tree index, tree initial, tree final, tree incr, @
|
|
gimple_seq pre_body, enum tree_code omp_for_cond)
|
|
Build a @code{GIMPLE_OMP_FOR} statement. @code{BODY} is sequence of statements
|
|
inside the for loop. @code{CLAUSES}, are any of the loop
|
|
construct's clauses. @code{PRE_BODY} is the
|
|
sequence of statements that are loop invariant. @code{INDEX} is the
|
|
index variable. @code{INITIAL} is the initial value of @code{INDEX}. @code{FINAL} is
|
|
final value of @code{INDEX}. OMP_FOR_COND is the predicate used to
|
|
compare @code{INDEX} and @code{FINAL}. @code{INCR} is the increment expression.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_for_clauses (gimple g)
|
|
Return the clauses associated with @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_for_clauses_ptr (gimple g)
|
|
Return a pointer to the @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_clauses (gimple g, tree clauses)
|
|
Set @code{CLAUSES} to be the list of clauses associated with @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_for_index (gimple g)
|
|
Return the index variable for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_for_index_ptr (gimple g)
|
|
Return a pointer to the index variable for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_index (gimple g, tree index)
|
|
Set @code{INDEX} to be the index variable for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_for_initial (gimple g)
|
|
Return the initial value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_for_initial_ptr (gimple g)
|
|
Return a pointer to the initial value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_initial (gimple g, tree initial)
|
|
Set @code{INITIAL} to be the initial value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_for_final (gimple g)
|
|
Return the final value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_for_final_ptr (gimple g)
|
|
turn a pointer to the final value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_final (gimple g, tree final)
|
|
Set @code{FINAL} to be the final value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_for_incr (gimple g)
|
|
Return the increment value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_for_incr_ptr (gimple g)
|
|
Return a pointer to the increment value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_incr (gimple g, tree incr)
|
|
Set @code{INCR} to be the increment value for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_omp_for_pre_body (gimple g)
|
|
Return the sequence of statements to execute before the @code{OMP_FOR}
|
|
statement @code{G} starts.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_pre_body (gimple g, gimple_seq pre_body)
|
|
Set @code{PRE_BODY} to be the sequence of statements to execute before
|
|
the @code{OMP_FOR} statement @code{G} starts.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_for_set_cond (gimple g, enum tree_code cond)
|
|
Set @code{COND} to be the condition code for @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {enum tree_code} gimple_omp_for_cond (gimple g)
|
|
Return the condition code associated with @code{OMP_FOR} @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_MASTER}
|
|
@subsection @code{GIMPLE_OMP_MASTER}
|
|
@cindex @code{GIMPLE_OMP_MASTER}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_omp_master (gimple_seq body)
|
|
Build a @code{GIMPLE_OMP_MASTER} statement. @code{BODY} is the sequence of
|
|
statements to be executed by just the master.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_ORDERED}
|
|
@subsection @code{GIMPLE_OMP_ORDERED}
|
|
@cindex @code{GIMPLE_OMP_ORDERED}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_omp_ordered (gimple_seq body)
|
|
Build a @code{GIMPLE_OMP_ORDERED} statement.
|
|
@end deftypefn
|
|
|
|
@code{BODY} is the sequence of statements inside a loop that will
|
|
executed in sequence.
|
|
|
|
|
|
@node @code{GIMPLE_OMP_PARALLEL}
|
|
@subsection @code{GIMPLE_OMP_PARALLEL}
|
|
@cindex @code{GIMPLE_OMP_PARALLEL}
|
|
|
|
@deftypefn {GIMPLE function} gomp_parallel *gimple_build_omp_parallel (@
|
|
gimple_seq body, tree clauses, tree child_fn, tree data_arg)
|
|
Build a @code{GIMPLE_OMP_PARALLEL} statement.
|
|
@end deftypefn
|
|
|
|
@code{BODY} is sequence of statements which are executed in parallel.
|
|
@code{CLAUSES}, are the @code{OMP} parallel construct's clauses. @code{CHILD_FN} is
|
|
the function created for the parallel threads to execute.
|
|
@code{DATA_ARG} are the shared data argument(s).
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_omp_parallel_combined_p (gimple g)
|
|
Return true if @code{OMP} parallel statement @code{G} has the
|
|
@code{GF_OMP_PARALLEL_COMBINED} flag set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_parallel_set_combined_p (gimple g)
|
|
Set the @code{GF_OMP_PARALLEL_COMBINED} field in @code{OMP} parallel statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_omp_body (gimple g)
|
|
Return the body for the @code{OMP} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_set_body (gimple g, gimple_seq body)
|
|
Set @code{BODY} to be the body for the @code{OMP} statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_parallel_clauses (gimple g)
|
|
Return the clauses associated with @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_parallel_clauses_ptr ( @
|
|
gomp_parallel *g)
|
|
Return a pointer to the clauses associated with @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_parallel_set_clauses ( @
|
|
gomp_parallel *g, tree clauses)
|
|
Set @code{CLAUSES} to be the list of clauses associated with
|
|
@code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_parallel_child_fn ( @
|
|
const gomp_parallel *g)
|
|
Return the child function used to hold the body of @code{OMP_PARALLEL}
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_parallel_child_fn_ptr ( @
|
|
gomp_parallel *g)
|
|
Return a pointer to the child function used to hold the body of
|
|
@code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_parallel_set_child_fn ( @
|
|
gomp_parallel *g, tree child_fn)
|
|
Set @code{CHILD_FN} to be the child function for @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_parallel_data_arg ( @
|
|
const gomp_parallel *g)
|
|
Return the artificial argument used to send variables and values
|
|
from the parent to the children threads in @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_parallel_data_arg_ptr ( @
|
|
gomp_parallel *g)
|
|
Return a pointer to the data argument for @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_parallel_set_data_arg ( @
|
|
gomp_parallel *g, tree data_arg)
|
|
Set @code{DATA_ARG} to be the data argument for @code{OMP_PARALLEL} @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_RETURN}
|
|
@subsection @code{GIMPLE_OMP_RETURN}
|
|
@cindex @code{GIMPLE_OMP_RETURN}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_omp_return (bool wait_p)
|
|
Build a @code{GIMPLE_OMP_RETURN} statement. @code{WAIT_P} is true if this is a
|
|
non-waiting return.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_return_set_nowait (gimple s)
|
|
Set the nowait flag on @code{GIMPLE_OMP_RETURN} statement @code{S}.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_omp_return_nowait_p (gimple g)
|
|
Return true if @code{OMP} return statement @code{G} has the
|
|
@code{GF_OMP_RETURN_NOWAIT} flag set.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_OMP_SECTION}
|
|
@subsection @code{GIMPLE_OMP_SECTION}
|
|
@cindex @code{GIMPLE_OMP_SECTION}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_omp_section (gimple_seq body)
|
|
Build a @code{GIMPLE_OMP_SECTION} statement for a sections statement.
|
|
@end deftypefn
|
|
|
|
@code{BODY} is the sequence of statements in the section.
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_omp_section_last_p (gimple g)
|
|
Return true if @code{OMP} section statement @code{G} has the
|
|
@code{GF_OMP_SECTION_LAST} flag set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_section_set_last (gimple g)
|
|
Set the @code{GF_OMP_SECTION_LAST} flag on @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_OMP_SECTIONS}
|
|
@subsection @code{GIMPLE_OMP_SECTIONS}
|
|
@cindex @code{GIMPLE_OMP_SECTIONS}
|
|
|
|
@deftypefn {GIMPLE function} gomp_sections *gimple_build_omp_sections ( @
|
|
gimple_seq body, tree clauses)
|
|
Build a @code{GIMPLE_OMP_SECTIONS} statement. @code{BODY} is a sequence of
|
|
section statements. @code{CLAUSES} are any of the @code{OMP} sections
|
|
construct's clauses: private, firstprivate, lastprivate,
|
|
reduction, and nowait.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_omp_sections_switch (void)
|
|
Build a @code{GIMPLE_OMP_SECTIONS_SWITCH} statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_sections_control (gimple g)
|
|
Return the control variable associated with the
|
|
@code{GIMPLE_OMP_SECTIONS} in @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_sections_control_ptr (gimple g)
|
|
Return a pointer to the clauses associated with the
|
|
@code{GIMPLE_OMP_SECTIONS} in @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_sections_set_control (gimple g, tree control)
|
|
Set @code{CONTROL} to be the set of clauses associated with the
|
|
@code{GIMPLE_OMP_SECTIONS} in @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_sections_clauses (gimple g)
|
|
Return the clauses associated with @code{OMP_SECTIONS} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_sections_clauses_ptr (gimple g)
|
|
Return a pointer to the clauses associated with @code{OMP_SECTIONS} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_sections_set_clauses (gimple g, tree clauses)
|
|
Set @code{CLAUSES} to be the set of clauses associated with @code{OMP_SECTIONS}
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_OMP_SINGLE}
|
|
@subsection @code{GIMPLE_OMP_SINGLE}
|
|
@cindex @code{GIMPLE_OMP_SINGLE}
|
|
|
|
@deftypefn {GIMPLE function} gomp_single *gimple_build_omp_single ( @
|
|
gimple_seq body, tree clauses)
|
|
Build a @code{GIMPLE_OMP_SINGLE} statement. @code{BODY} is the sequence of
|
|
statements that will be executed once. @code{CLAUSES} are any of the
|
|
@code{OMP} single construct's clauses: private, firstprivate,
|
|
copyprivate, nowait.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_omp_single_clauses (gimple g)
|
|
Return the clauses associated with @code{OMP_SINGLE} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_omp_single_clauses_ptr (gimple g)
|
|
Return a pointer to the clauses associated with @code{OMP_SINGLE} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_omp_single_set_clauses ( @
|
|
gomp_single *g, tree clauses)
|
|
Set @code{CLAUSES} to be the clauses associated with @code{OMP_SINGLE} @code{G}.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_PHI}
|
|
@subsection @code{GIMPLE_PHI}
|
|
@cindex @code{GIMPLE_PHI}
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_phi_capacity (gimple g)
|
|
Return the maximum number of arguments supported by @code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_phi_num_args (gimple g)
|
|
Return the number of arguments in @code{GIMPLE_PHI} @code{G}. This must always
|
|
be exactly the number of incoming edges for the basic block
|
|
holding @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_phi_result (gimple g)
|
|
Return the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {tree *} gimple_phi_result_ptr (gimple g)
|
|
Return a pointer to the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_phi_set_result (gphi *g, tree result)
|
|
Set @code{RESULT} to be the @code{SSA} name created by @code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {struct phi_arg_d *} gimple_phi_arg (gimple g, index)
|
|
Return the @code{PHI} argument corresponding to incoming edge @code{INDEX} for
|
|
@code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_phi_set_arg (gphi *g, index, @
|
|
struct phi_arg_d * phiarg)
|
|
Set @code{PHIARG} to be the argument corresponding to incoming edge
|
|
@code{INDEX} for @code{GIMPLE_PHI} @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_RESX}
|
|
@subsection @code{GIMPLE_RESX}
|
|
@cindex @code{GIMPLE_RESX}
|
|
|
|
@deftypefn {GIMPLE function} gresx *gimple_build_resx (int region)
|
|
Build a @code{GIMPLE_RESX} statement which is a statement. This
|
|
statement is a placeholder for _Unwind_Resume before we know if a
|
|
function call or a branch is needed. @code{REGION} is the exception
|
|
region from which control is flowing.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} int gimple_resx_region (const gresx *g)
|
|
Return the region number for @code{GIMPLE_RESX} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_resx_set_region (gresx *g, int region)
|
|
Set @code{REGION} to be the region number for @code{GIMPLE_RESX} @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_RETURN}
|
|
@subsection @code{GIMPLE_RETURN}
|
|
@cindex @code{GIMPLE_RETURN}
|
|
|
|
@deftypefn {GIMPLE function} greturn *gimple_build_return (tree retval)
|
|
Build a @code{GIMPLE_RETURN} statement whose return value is retval.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_return_retval (const greturn *g)
|
|
Return the return value for @code{GIMPLE_RETURN} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_return_set_retval (greturn *g, @
|
|
tree retval)
|
|
Set @code{RETVAL} to be the return value for @code{GIMPLE_RETURN} @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_SWITCH}
|
|
@subsection @code{GIMPLE_SWITCH}
|
|
@cindex @code{GIMPLE_SWITCH}
|
|
|
|
@deftypefn {GIMPLE function} gswitch *gimple_build_switch (tree index, @
|
|
tree default_label, @code{vec}<tree> *args)
|
|
Build a @code{GIMPLE_SWITCH} statement. @code{INDEX} is the index variable
|
|
to switch on, and @code{DEFAULT_LABEL} represents the default label.
|
|
@code{ARGS} is a vector of @code{CASE_LABEL_EXPR} trees that contain the
|
|
non-default case labels. Each label is a tree of code @code{CASE_LABEL_EXPR}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} unsigned gimple_switch_num_labels ( @
|
|
const gswitch *g)
|
|
Return the number of labels associated with the switch statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_switch_set_num_labels (gswitch *g, @
|
|
unsigned nlabels)
|
|
Set @code{NLABELS} to be the number of labels for the switch statement
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_switch_index (const gswitch *g)
|
|
Return the index variable used by the switch statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_switch_set_index (gswitch *g, @
|
|
tree index)
|
|
Set @code{INDEX} to be the index variable for switch statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_switch_label (const gswitch *g, @
|
|
unsigned index)
|
|
Return the label numbered @code{INDEX}. The default label is 0, followed
|
|
by any labels in a switch statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_switch_set_label (gswitch *g, @
|
|
unsigned index, tree label)
|
|
Set the label number @code{INDEX} to @code{LABEL}. 0 is always the default
|
|
label.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} tree gimple_switch_default_label ( @
|
|
const gswitch *g)
|
|
Return the default label for a switch statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_switch_set_default_label (gswitch *g, @
|
|
tree label)
|
|
Set the default label for a switch statement.
|
|
@end deftypefn
|
|
|
|
|
|
@node @code{GIMPLE_TRY}
|
|
@subsection @code{GIMPLE_TRY}
|
|
@cindex @code{GIMPLE_TRY}
|
|
|
|
@deftypefn {GIMPLE function} gtry *gimple_build_try (gimple_seq eval, @
|
|
gimple_seq cleanup, unsigned int kind)
|
|
Build a @code{GIMPLE_TRY} statement. @code{EVAL} is a sequence with the
|
|
expression to evaluate. @code{CLEANUP} is a sequence of statements to
|
|
run at clean-up time. @code{KIND} is the enumeration value
|
|
@code{GIMPLE_TRY_CATCH} if this statement denotes a try/catch construct
|
|
or @code{GIMPLE_TRY_FINALLY} if this statement denotes a try/finally
|
|
construct.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {enum gimple_try_flags} gimple_try_kind (gimple g)
|
|
Return the kind of try block represented by @code{GIMPLE_TRY} @code{G}. This is
|
|
either @code{GIMPLE_TRY_CATCH} or @code{GIMPLE_TRY_FINALLY}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_try_catch_is_cleanup (gimple g)
|
|
Return the @code{GIMPLE_TRY_CATCH_IS_CLEANUP} flag.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_try_eval (gimple g)
|
|
Return the sequence of statements used as the body for @code{GIMPLE_TRY}
|
|
@code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_try_cleanup (gimple g)
|
|
Return the sequence of statements used as the cleanup body for
|
|
@code{GIMPLE_TRY} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_try_set_catch_is_cleanup (gimple g, @
|
|
bool catch_is_cleanup)
|
|
Set the @code{GIMPLE_TRY_CATCH_IS_CLEANUP} flag.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_try_set_eval (gtry *g, gimple_seq eval)
|
|
Set @code{EVAL} to be the sequence of statements to use as the body for
|
|
@code{GIMPLE_TRY} @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_try_set_cleanup (gtry *g, @
|
|
gimple_seq cleanup)
|
|
Set @code{CLEANUP} to be the sequence of statements to use as the
|
|
cleanup body for @code{GIMPLE_TRY} @code{G}.
|
|
@end deftypefn
|
|
|
|
@node @code{GIMPLE_WITH_CLEANUP_EXPR}
|
|
@subsection @code{GIMPLE_WITH_CLEANUP_EXPR}
|
|
@cindex @code{GIMPLE_WITH_CLEANUP_EXPR}
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_build_wce (gimple_seq cleanup)
|
|
Build a @code{GIMPLE_WITH_CLEANUP_EXPR} statement. @code{CLEANUP} is the
|
|
clean-up expression.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_wce_cleanup (gimple g)
|
|
Return the cleanup sequence for cleanup statement @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_wce_set_cleanup (gimple g, gimple_seq cleanup)
|
|
Set @code{CLEANUP} to be the cleanup sequence for @code{G}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_wce_cleanup_eh_only (gimple g)
|
|
Return the @code{CLEANUP_EH_ONLY} flag for a @code{WCE} tuple.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_wce_set_cleanup_eh_only (gimple g, bool eh_only_p)
|
|
Set the @code{CLEANUP_EH_ONLY} flag for a @code{WCE} tuple.
|
|
@end deftypefn
|
|
|
|
|
|
@node GIMPLE sequences
|
|
@section GIMPLE sequences
|
|
@cindex GIMPLE sequences
|
|
|
|
GIMPLE sequences are the tuple equivalent of @code{STATEMENT_LIST}'s
|
|
used in @code{GENERIC}. They are used to chain statements together, and
|
|
when used in conjunction with sequence iterators, provide a
|
|
framework for iterating through statements.
|
|
|
|
GIMPLE sequences are of type struct @code{gimple_sequence}, but are more
|
|
commonly passed by reference to functions dealing with sequences.
|
|
The type for a sequence pointer is @code{gimple_seq} which is the same
|
|
as struct @code{gimple_sequence} *. When declaring a local sequence,
|
|
you can define a local variable of type struct @code{gimple_sequence}.
|
|
When declaring a sequence allocated on the garbage collected
|
|
heap, use the function @code{gimple_seq_alloc} documented below.
|
|
|
|
There are convenience functions for iterating through sequences
|
|
in the section entitled Sequence Iterators.
|
|
|
|
Below is a list of functions to manipulate and query sequences.
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_add_stmt (gimple_seq *seq, gimple g)
|
|
Link a gimple statement to the end of the sequence *@code{SEQ} if @code{G} is
|
|
not @code{NULL}. If *@code{SEQ} is @code{NULL}, allocate a sequence before linking.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_add_seq (gimple_seq *dest, gimple_seq src)
|
|
Append sequence @code{SRC} to the end of sequence *@code{DEST} if @code{SRC} is not
|
|
@code{NULL}. If *@code{DEST} is @code{NULL}, allocate a new sequence before
|
|
appending.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_seq_deep_copy (gimple_seq src)
|
|
Perform a deep copy of sequence @code{SRC} and return the result.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_seq_reverse (gimple_seq seq)
|
|
Reverse the order of the statements in the sequence @code{SEQ}. Return
|
|
@code{SEQ}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_seq_first (gimple_seq s)
|
|
Return the first statement in sequence @code{S}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gimple_seq_last (gimple_seq s)
|
|
Return the last statement in sequence @code{S}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_set_last (gimple_seq s, gimple last)
|
|
Set the last statement in sequence @code{S} to the statement in @code{LAST}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_set_first (gimple_seq s, gimple first)
|
|
Set the first statement in sequence @code{S} to the statement in @code{FIRST}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_init (gimple_seq s)
|
|
Initialize sequence @code{S} to an empty sequence.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gimple_seq_alloc (void)
|
|
Allocate a new sequence in the garbage collected store and return
|
|
it.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gimple_seq_copy (gimple_seq dest, gimple_seq src)
|
|
Copy the sequence @code{SRC} into the sequence @code{DEST}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_seq_empty_p (gimple_seq s)
|
|
Return true if the sequence @code{S} is empty.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq bb_seq (basic_block bb)
|
|
Returns the sequence of statements in @code{BB}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void set_bb_seq (basic_block bb, gimple_seq seq)
|
|
Sets the sequence of statements in @code{BB} to @code{SEQ}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gimple_seq_singleton_p (gimple_seq seq)
|
|
Determine whether @code{SEQ} contains exactly one statement.
|
|
@end deftypefn
|
|
|
|
@node Sequence iterators
|
|
@section Sequence iterators
|
|
@cindex Sequence iterators
|
|
|
|
Sequence iterators are convenience constructs for iterating
|
|
through statements in a sequence. Given a sequence @code{SEQ}, here is
|
|
a typical use of gimple sequence iterators:
|
|
|
|
@smallexample
|
|
gimple_stmt_iterator gsi;
|
|
|
|
for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
|
|
@{
|
|
gimple g = gsi_stmt (gsi);
|
|
/* Do something with gimple statement @code{G}. */
|
|
@}
|
|
@end smallexample
|
|
|
|
Backward iterations are possible:
|
|
|
|
@smallexample
|
|
for (gsi = gsi_last (seq); !gsi_end_p (gsi); gsi_prev (&gsi))
|
|
@end smallexample
|
|
|
|
Forward and backward iterations on basic blocks are possible with
|
|
@code{gsi_start_bb} and @code{gsi_last_bb}.
|
|
|
|
In the documentation below we sometimes refer to enum
|
|
@code{gsi_iterator_update}. The valid options for this enumeration are:
|
|
|
|
@itemize @bullet
|
|
@item @code{GSI_NEW_STMT}
|
|
Only valid when a single statement is added. Move the iterator to it.
|
|
|
|
@item @code{GSI_SAME_STMT}
|
|
Leave the iterator at the same statement.
|
|
|
|
@item @code{GSI_CONTINUE_LINKING}
|
|
Move iterator to whatever position is suitable for linking other
|
|
statements in the same direction.
|
|
@end itemize
|
|
|
|
Below is a list of the functions used to manipulate and use
|
|
statement iterators.
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_start (gimple_seq seq)
|
|
Return a new iterator pointing to the sequence @code{SEQ}'s first
|
|
statement. If @code{SEQ} is empty, the iterator's basic block is @code{NULL}.
|
|
Use @code{gsi_start_bb} instead when the iterator needs to always have
|
|
the correct basic block set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_start_bb (basic_block bb)
|
|
Return a new iterator pointing to the first statement in basic
|
|
block @code{BB}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_last (gimple_seq seq)
|
|
Return a new iterator initially pointing to the last statement of
|
|
sequence @code{SEQ}. If @code{SEQ} is empty, the iterator's basic block is
|
|
@code{NULL}. Use @code{gsi_last_bb} instead when the iterator needs to always
|
|
have the correct basic block set.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_last_bb (basic_block bb)
|
|
Return a new iterator pointing to the last statement in basic
|
|
block @code{BB}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gsi_end_p (gimple_stmt_iterator i)
|
|
Return @code{TRUE} if at the end of @code{I}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} bool gsi_one_before_end_p (gimple_stmt_iterator i)
|
|
Return @code{TRUE} if we're one statement before the end of @code{I}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_next (gimple_stmt_iterator *i)
|
|
Advance the iterator to the next gimple statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_prev (gimple_stmt_iterator *i)
|
|
Advance the iterator to the previous gimple statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple gsi_stmt (gimple_stmt_iterator i)
|
|
Return the current stmt.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_after_labels (basic_block bb)
|
|
Return a block statement iterator that points to the first
|
|
non-label statement in block @code{BB}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} {gimple *} gsi_stmt_ptr (gimple_stmt_iterator *i)
|
|
Return a pointer to the current stmt.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} basic_block gsi_bb (gimple_stmt_iterator i)
|
|
Return the basic block associated with this iterator.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gsi_seq (gimple_stmt_iterator i)
|
|
Return the sequence associated with this iterator.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_remove (gimple_stmt_iterator *i, bool remove_eh_info)
|
|
Remove the current stmt from the sequence. The iterator is
|
|
updated to point to the next statement. When @code{REMOVE_EH_INFO} is
|
|
true we remove the statement pointed to by iterator @code{I} from the @code{EH}
|
|
tables. Otherwise we do not modify the @code{EH} tables. Generally,
|
|
@code{REMOVE_EH_INFO} should be true when the statement is going to be
|
|
removed from the @code{IL} and not reinserted elsewhere.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_link_seq_before (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)
|
|
Links the sequence of statements @code{SEQ} before the statement pointed
|
|
by iterator @code{I}. @code{MODE} indicates what to do with the iterator
|
|
after insertion (see @code{enum gsi_iterator_update} above).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_link_before (gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode)
|
|
Links statement @code{G} before the statement pointed-to by iterator @code{I}.
|
|
Updates iterator @code{I} according to @code{MODE}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_link_seq_after (gimple_stmt_iterator *i, @
|
|
gimple_seq seq, enum gsi_iterator_update mode)
|
|
Links sequence @code{SEQ} after the statement pointed-to by iterator @code{I}.
|
|
@code{MODE} is as in @code{gsi_insert_after}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_link_after (gimple_stmt_iterator *i, @
|
|
gimple g, enum gsi_iterator_update mode)
|
|
Links statement @code{G} after the statement pointed-to by iterator @code{I}.
|
|
@code{MODE} is as in @code{gsi_insert_after}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gsi_split_seq_after (gimple_stmt_iterator i)
|
|
Move all statements in the sequence after @code{I} to a new sequence.
|
|
Return this new sequence.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_seq gsi_split_seq_before (gimple_stmt_iterator *i)
|
|
Move all statements in the sequence before @code{I} to a new sequence.
|
|
Return this new sequence.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_replace (gimple_stmt_iterator *i, @
|
|
gimple stmt, bool update_eh_info)
|
|
Replace the statement pointed-to by @code{I} to @code{STMT}. If @code{UPDATE_EH_INFO}
|
|
is true, the exception handling information of the original
|
|
statement is moved to the new statement.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_before (gimple_stmt_iterator *i, @
|
|
gimple stmt, enum gsi_iterator_update mode)
|
|
Insert statement @code{STMT} before the statement pointed-to by iterator
|
|
@code{I}, update @code{STMT}'s basic block and scan it for new operands. @code{MODE}
|
|
specifies how to update iterator @code{I} after insertion (see enum
|
|
@code{gsi_iterator_update}).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_seq_before (gimple_stmt_iterator *i, @
|
|
gimple_seq seq, enum gsi_iterator_update mode)
|
|
Like @code{gsi_insert_before}, but for all the statements in @code{SEQ}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_after (gimple_stmt_iterator *i, @
|
|
gimple stmt, enum gsi_iterator_update mode)
|
|
Insert statement @code{STMT} after the statement pointed-to by iterator
|
|
@code{I}, update @code{STMT}'s basic block and scan it for new operands. @code{MODE}
|
|
specifies how to update iterator @code{I} after insertion (see enum
|
|
@code{gsi_iterator_update}).
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_seq_after (gimple_stmt_iterator *i, @
|
|
gimple_seq seq, enum gsi_iterator_update mode)
|
|
Like @code{gsi_insert_after}, but for all the statements in @code{SEQ}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} gimple_stmt_iterator gsi_for_stmt (gimple stmt)
|
|
Finds iterator for @code{STMT}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_move_after (gimple_stmt_iterator *from, @
|
|
gimple_stmt_iterator *to)
|
|
Move the statement at @code{FROM} so it comes right after the statement
|
|
at @code{TO}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_move_before (gimple_stmt_iterator *from, @
|
|
gimple_stmt_iterator *to)
|
|
Move the statement at @code{FROM} so it comes right before the statement
|
|
at @code{TO}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_move_to_bb_end (gimple_stmt_iterator *from, @
|
|
basic_block bb)
|
|
Move the statement at @code{FROM} to the end of basic block @code{BB}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_on_edge (edge e, gimple stmt)
|
|
Add @code{STMT} to the pending list of edge @code{E}. No actual insertion is
|
|
made until a call to @code{gsi_commit_edge_inserts}() is made.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_insert_seq_on_edge (edge e, gimple_seq seq)
|
|
Add the sequence of statements in @code{SEQ} to the pending list of edge
|
|
@code{E}. No actual insertion is made until a call to
|
|
@code{gsi_commit_edge_inserts}() is made.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} basic_block gsi_insert_on_edge_immediate (edge e, gimple stmt)
|
|
Similar to @code{gsi_insert_on_edge}+@code{gsi_commit_edge_inserts}. If a new
|
|
block has to be created, it is returned.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
|
|
Commit insertions pending at edge @code{E}. If a new block is created,
|
|
set @code{NEW_BB} to this block, otherwise set it to @code{NULL}.
|
|
@end deftypefn
|
|
|
|
@deftypefn {GIMPLE function} void gsi_commit_edge_inserts (void)
|
|
This routine will commit all pending edge insertions, creating
|
|
any new basic blocks which are necessary.
|
|
@end deftypefn
|
|
|
|
|
|
@node Adding a new GIMPLE statement code
|
|
@section Adding a new GIMPLE statement code
|
|
@cindex Adding a new GIMPLE statement code
|
|
|
|
The first step in adding a new GIMPLE statement code, is
|
|
modifying the file @code{gimple.def}, which contains all the GIMPLE
|
|
codes. Then you must add a corresponding gimple subclass
|
|
located in @code{gimple.h}. This in turn, will require you to add a
|
|
corresponding @code{GTY} tag in @code{gsstruct.def}, and code to handle
|
|
this tag in @code{gss_for_code} which is located in @code{gimple.c}.
|
|
|
|
In order for the garbage collector to know the size of the
|
|
structure you created in @code{gimple.h}, you need to add a case to
|
|
handle your new GIMPLE statement in @code{gimple_size} which is located
|
|
in @code{gimple.c}.
|
|
|
|
You will probably want to create a function to build the new
|
|
gimple statement in @code{gimple.c}. The function should be called
|
|
@code{gimple_build_@var{new-tuple-name}}, and should return the new tuple
|
|
as a pointer to the appropriate gimple subclass.
|
|
|
|
If your new statement requires accessors for any members or
|
|
operands it may have, put simple inline accessors in
|
|
@code{gimple.h} and any non-trivial accessors in @code{gimple.c} with a
|
|
corresponding prototype in @code{gimple.h}.
|
|
|
|
You should add the new statement subclass to the class hierarchy diagram
|
|
in @code{gimple.texi}.
|
|
|
|
|
|
@node Statement and operand traversals
|
|
@section Statement and operand traversals
|
|
@cindex Statement and operand traversals
|
|
|
|
There are two functions available for walking statements and
|
|
sequences: @code{walk_gimple_stmt} and @code{walk_gimple_seq},
|
|
accordingly, and a third function for walking the operands in a
|
|
statement: @code{walk_gimple_op}.
|
|
|
|
@deftypefn {GIMPLE function} tree walk_gimple_stmt (gimple_stmt_iterator *gsi, @
|
|
walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi)
|
|
This function is used to walk the current statement in @code{GSI},
|
|
optionally using traversal state stored in @code{WI}. If @code{WI} is @code{NULL}, no
|
|
state is kept during the traversal.
|
|
|
|
The callback @code{CALLBACK_STMT} is called. If @code{CALLBACK_STMT} returns
|
|
true, it means that the callback function has handled all the
|
|
operands of the statement and it is not necessary to walk its
|
|
operands.
|
|
|
|
If @code{CALLBACK_STMT} is @code{NULL} or it returns false, @code{CALLBACK_OP} is
|
|
called on each operand of the statement via @code{walk_gimple_op}. If
|
|
@code{walk_gimple_op} returns non-@code{NULL} for any operand, the remaining
|
|
operands are not scanned.
|
|
|
|
The return value is that returned by the last call to
|
|
@code{walk_gimple_op}, or @code{NULL_TREE} if no @code{CALLBACK_OP} is specified.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} tree walk_gimple_op (gimple stmt, @
|
|
walk_tree_fn callback_op, struct walk_stmt_info *wi)
|
|
Use this function to walk the operands of statement @code{STMT}. Every
|
|
operand is walked via @code{walk_tree} with optional state information
|
|
in @code{WI}.
|
|
|
|
@code{CALLBACK_OP} is called on each operand of @code{STMT} via @code{walk_tree}.
|
|
Additional parameters to @code{walk_tree} must be stored in @code{WI}. For
|
|
each operand @code{OP}, @code{walk_tree} is called as:
|
|
|
|
@smallexample
|
|
walk_tree (&@code{OP}, @code{CALLBACK_OP}, @code{WI}, @code{PSET})
|
|
@end smallexample
|
|
|
|
If @code{CALLBACK_OP} returns non-@code{NULL} for an operand, the remaining
|
|
operands are not scanned. The return value is that returned by
|
|
the last call to @code{walk_tree}, or @code{NULL_TREE} if no @code{CALLBACK_OP} is
|
|
specified.
|
|
@end deftypefn
|
|
|
|
|
|
@deftypefn {GIMPLE function} tree walk_gimple_seq (gimple_seq seq, @
|
|
walk_stmt_fn callback_stmt, walk_tree_fn callback_op, struct walk_stmt_info *wi)
|
|
This function walks all the statements in the sequence @code{SEQ}
|
|
calling @code{walk_gimple_stmt} on each one. @code{WI} is as in
|
|
@code{walk_gimple_stmt}. If @code{walk_gimple_stmt} returns non-@code{NULL}, the walk
|
|
is stopped and the value returned. Otherwise, all the statements
|
|
are walked and @code{NULL_TREE} returned.
|
|
@end deftypefn
|