This is gccint.info, produced by makeinfo version 7.1 from gccint.texi. Copyright © 1988-2024 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being "Funding Free Software", the Front-Cover Texts being (a) (see below), and with the Back-Cover Texts being (b) (see below). A copy of the license is included in the section entitled "GNU Free Documentation License". (a) The FSF's Front-Cover Text is: A GNU Manual (b) The FSF's Back-Cover Text is: You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development. INFO-DIR-SECTION Software development START-INFO-DIR-ENTRY * gccint: (gccint). Internals of the GNU Compiler Collection. END-INFO-DIR-ENTRY This file documents the internals of the GNU compilers. Copyright © 1988-2024 Free Software Foundation, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being "Funding Free Software", the Front-Cover Texts being (a) (see below), and with the Back-Cover Texts being (b) (see below). A copy of the license is included in the section entitled "GNU Free Documentation License". (a) The FSF's Front-Cover Text is: A GNU Manual (b) The FSF's Back-Cover Text is: You have freedom to copy and modify this GNU Manual, like GNU software. Copies published by the Free Software Foundation raise funds for GNU development.  File: gccint.info, Node: Ada Tests, Next: C Tests, Prev: Test Directives, Up: Testsuites 7.3 Ada Language Testsuites =========================== The Ada testsuite includes executable tests from the ACATS testsuite, publicly available at . These tests are integrated in the GCC testsuite in the ‘ada/acats’ directory, and enabled automatically when running ‘make check’, assuming the Ada language has been enabled when configuring GCC. You can also run the Ada testsuite independently, using ‘make check-ada’, or run a subset of the tests by specifying which chapter to run, e.g.: $ make check-ada CHAPTERS="c3 c9" The tests are organized by directory, each directory corresponding to a chapter of the Ada Reference Manual. So for example, ‘c9’ corresponds to chapter 9, which deals with tasking features of the language. The tests are run using two ‘sh’ scripts: ‘run_acats’ and ‘run_all.sh’. To run the tests using a simulator or a cross target, see the small customization section at the top of ‘run_all.sh’. These tests are run using the build tree: they can be run without doing a ‘make install’.  File: gccint.info, Node: C Tests, Next: LTO Testing, Prev: Ada Tests, Up: Testsuites 7.4 C Language Testsuites ========================= GCC contains the following C language testsuites, in the ‘gcc/testsuite’ directory: ‘gcc.dg’ This contains tests of particular features of the C compiler, using the more modern ‘dg’ harness. Correctness tests for various compiler features should go here if possible. Magic comments determine whether the file is preprocessed, compiled, linked or run. In these tests, error and warning message texts are compared against expected texts or regular expressions given in comments. These tests are run with the options ‘-ansi -pedantic’ unless other options are given in the test. Except as noted below they are not run with multiple optimization options. ‘gcc.dg/compat’ This subdirectory contains tests for binary compatibility using ‘lib/compat.exp’, which in turn uses the language-independent support (*note Support for testing binary compatibility: compat Testing.). ‘gcc.dg/cpp’ This subdirectory contains tests of the preprocessor. ‘gcc.dg/debug’ This subdirectory contains tests for debug formats. Tests in this subdirectory are run for each debug format that the compiler supports. ‘gcc.dg/format’ This subdirectory contains tests of the ‘-Wformat’ format checking. Tests in this directory are run with and without ‘-DWIDE’. ‘gcc.dg/noncompile’ This subdirectory contains tests of code that should not compile and does not need any special compilation options. They are run with multiple optimization options, since sometimes invalid code crashes the compiler with optimization. ‘gcc.dg/special’ FIXME: describe this. ‘gcc.c-torture’ This contains particular code fragments which have historically broken easily. These tests are run with multiple optimization options, so tests for features which only break at some optimization levels belong here. This also contains tests to check that certain optimizations occur. It might be worthwhile to separate the correctness tests cleanly from the code quality tests, but it hasn't been done yet. ‘gcc.c-torture/compat’ FIXME: describe this. This directory should probably not be used for new tests. ‘gcc.c-torture/compile’ This testsuite contains test cases that should compile, but do not need to link or run. These test cases are compiled with several different combinations of optimization options. All warnings are disabled for these test cases, so this directory is not suitable if you wish to test for the presence or absence of compiler warnings. While special options can be set, and tests disabled on specific platforms, by the use of ‘.x’ files, mostly these test cases should not contain platform dependencies. FIXME: discuss how defines such as ‘STACK_SIZE’ are used. ‘gcc.c-torture/execute’ This testsuite contains test cases that should compile, link and run; otherwise the same comments as for ‘gcc.c-torture/compile’ apply. ‘gcc.c-torture/execute/ieee’ This contains tests which are specific to IEEE floating point. ‘gcc.c-torture/unsorted’ FIXME: describe this. This directory should probably not be used for new tests. ‘gcc.misc-tests’ This directory contains C tests that require special handling. Some of these tests have individual expect files, and others share special-purpose expect files: ‘bprob*.c’ Test ‘-fbranch-probabilities’ using ‘gcc.misc-tests/bprob.exp’, which in turn uses the generic, language-independent framework (*note Support for testing profile-directed optimizations: profopt Testing.). ‘gcov*.c’ Test ‘gcov’ output using ‘gcov.exp’, which in turn uses the language-independent support (*note Support for testing gcov: gcov Testing.). ‘i386-pf-*.c’ Test i386-specific support for data prefetch using ‘i386-prefetch.exp’. ‘gcc.test-framework’ ‘dg-*.c’ Test the testsuite itself using ‘gcc.test-framework/test-framework.exp’. FIXME: merge in ‘testsuite/README.gcc’ and discuss the format of test cases and magic comments more.  File: gccint.info, Node: LTO Testing, Next: gcov Testing, Prev: C Tests, Up: Testsuites 7.5 Support for testing link-time optimizations =============================================== Tests for link-time optimizations usually require multiple source files that are compiled separately, perhaps with different sets of options. There are several special-purpose test directives used for these tests. ‘{ dg-lto-do DO-WHAT-KEYWORD }’ DO-WHAT-KEYWORD specifies how the test is compiled and whether it is executed. It is one of: ‘assemble’ Compile with ‘-c’ to produce a relocatable object file. ‘link’ Compile, assemble, and link to produce an executable file. ‘run’ Produce and run an executable file, which is expected to return an exit code of 0. The default is ‘assemble’. That can be overridden for a set of tests by redefining ‘dg-do-what-default’ within the ‘.exp’ file for those tests. Unlike ‘dg-do’, ‘dg-lto-do’ does not support an optional ‘target’ or ‘xfail’ list. Use ‘dg-skip-if’, ‘dg-xfail-if’, or ‘dg-xfail-run-if’. ‘{ dg-lto-options { { OPTIONS } [{ OPTIONS }] } [{ target SELECTOR }]}’ This directive provides a list of one or more sets of compiler options to override LTO_OPTIONS. Each test will be compiled and run with each of these sets of options. ‘{ dg-extra-ld-options OPTIONS [{ target SELECTOR }]}’ This directive adds OPTIONS to the linker options used. ‘{ dg-suppress-ld-options OPTIONS [{ target SELECTOR }]}’ This directive removes OPTIONS from the set of linker options used.  File: gccint.info, Node: gcov Testing, Next: profopt Testing, Prev: LTO Testing, Up: Testsuites 7.6 Support for testing ‘gcov’ ============================== Language-independent support for testing ‘gcov’, and for checking that branch profiling produces expected values, is provided by the expect file ‘lib/gcov.exp’. ‘gcov’ tests also rely on procedures in ‘lib/gcc-dg.exp’ to compile and run the test program. A typical ‘gcov’ test contains the following DejaGnu commands within comments: { dg-options "--coverage" } { dg-do run { target native } } { dg-final { run-gcov sourcefile } } Checks of ‘gcov’ output can include line counts, branch percentages, and call return percentages. All of these checks are requested via commands that appear in comments in the test's source file. Commands to check line counts are processed by default. Commands to check branch percentages and call return percentages are processed if the ‘run-gcov’ command has arguments ‘branches’ or ‘calls’, respectively. For example, the following specifies checking both, as well as passing ‘-b’ to ‘gcov’: { dg-final { run-gcov branches calls { -b sourcefile } } } A line count command appears within a comment on the source line that is expected to get the specified count and has the form ‘count(CNT)’. A test should only check line counts for lines that will get the same count for any architecture. Commands to check branch percentages (‘branch’) and call return percentages (‘returns’) are very similar to each other. A beginning command appears on or before the first of a range of lines that will report the percentage, and the ending command follows that range of lines. The beginning command can include a list of percentages, all of which are expected to be found within the range. A range is terminated by the next command of the same kind. A command ‘branch(end)’ or ‘returns(end)’ marks the end of a range without starting a new one. For example: if (i > 10 && j > i && j < 20) /* branch(27 50 75) */ /* branch(end) */ foo (i, j); For a call return percentage, the value specified is the percentage of calls reported to return. For a branch percentage, the value is either the expected percentage or 100 minus that value, since the direction of a branch can differ depending on the target or the optimization level. Not all branches and calls need to be checked. A test should not check for branches that might be optimized away or replaced with predicated instructions. Don't check for calls inserted by the compiler or ones that might be inlined or optimized away. A single test can check for combinations of line counts, branch percentages, and call return percentages. The command to check a line count must appear on the line that will report that count, but commands to check branch percentages and call return percentages can bracket the lines that report them.  File: gccint.info, Node: profopt Testing, Next: compat Testing, Prev: gcov Testing, Up: Testsuites 7.7 Support for testing profile-directed optimizations ====================================================== The file ‘profopt.exp’ provides language-independent support for checking correct execution of a test built with profile-directed optimization. This testing requires that a test program be built and executed twice. The first time it is compiled to generate profile data, and the second time it is compiled to use the data that was generated during the first execution. The second execution is to verify that the test produces the expected results. To check that the optimization actually generated better code, a test can be built and run a third time with normal optimizations to verify that the performance is better with the profile-directed optimizations. ‘profopt.exp’ has the beginnings of this kind of support. ‘profopt.exp’ provides generic support for profile-directed optimizations. Each set of tests that uses it provides information about a specific optimization: ‘tool’ tool being tested, e.g., ‘gcc’ ‘profile_option’ options used to generate profile data ‘feedback_option’ options used to optimize using that profile data ‘prof_ext’ suffix of profile data files ‘PROFOPT_OPTIONS’ list of options with which to run each test, similar to the lists for torture tests ‘{ dg-final-generate { LOCAL-DIRECTIVE } }’ This directive is similar to ‘dg-final’, but the LOCAL-DIRECTIVE is run after the generation of profile data. ‘{ dg-final-use { LOCAL-DIRECTIVE } }’ The LOCAL-DIRECTIVE is run after the profile data have been used.  File: gccint.info, Node: compat Testing, Next: Torture Tests, Prev: profopt Testing, Up: Testsuites 7.8 Support for testing binary compatibility ============================================ The file ‘compat.exp’ provides language-independent support for binary compatibility testing. It supports testing interoperability of two compilers that follow the same ABI, or of multiple sets of compiler options that should not affect binary compatibility. It is intended to be used for testsuites that complement ABI testsuites. A test supported by this framework has three parts, each in a separate source file: a main program and two pieces that interact with each other to split up the functionality being tested. ‘TESTNAME_main.SUFFIX’ Contains the main program, which calls a function in file ‘TESTNAME_x.SUFFIX’. ‘TESTNAME_x.SUFFIX’ Contains at least one call to a function in ‘TESTNAME_y.SUFFIX’. ‘TESTNAME_y.SUFFIX’ Shares data with, or gets arguments from, ‘TESTNAME_x.SUFFIX’. Within each test, the main program and one functional piece are compiled by the GCC under test. The other piece can be compiled by an alternate compiler. If no alternate compiler is specified, then all three source files are all compiled by the GCC under test. You can specify pairs of sets of compiler options. The first element of such a pair specifies options used with the GCC under test, and the second element of the pair specifies options used with the alternate compiler. Each test is compiled with each pair of options. ‘compat.exp’ defines default pairs of compiler options. These can be overridden by defining the environment variable ‘COMPAT_OPTIONS’ as: COMPAT_OPTIONS="[list [list {TST1} {ALT1}] ...[list {TSTN} {ALTN}]]" where TSTI and ALTI are lists of options, with TSTI used by the compiler under test and ALTI used by the alternate compiler. For example, with ‘[list [list {-g -O0} {-O3}] [list {-fpic} {-fPIC -O2}]]’, the test is first built with ‘-g -O0’ by the compiler under test and with ‘-O3’ by the alternate compiler. The test is built a second time using ‘-fpic’ by the compiler under test and ‘-fPIC -O2’ by the alternate compiler. An alternate compiler is specified by defining an environment variable to be the full pathname of an installed compiler; for C define ‘ALT_CC_UNDER_TEST’, and for C++ define ‘ALT_CXX_UNDER_TEST’. These will be written to the ‘site.exp’ file used by DejaGnu. The default is to build each test with the compiler under test using the first of each pair of compiler options from ‘COMPAT_OPTIONS’. When ‘ALT_CC_UNDER_TEST’ or ‘ALT_CXX_UNDER_TEST’ is ‘same’, each test is built using the compiler under test but with combinations of the options from ‘COMPAT_OPTIONS’. To run only the C++ compatibility suite using the compiler under test and another version of GCC using specific compiler options, do the following from ‘OBJDIR/gcc’: rm site.exp make -k \ ALT_CXX_UNDER_TEST=${alt_prefix}/bin/g++ \ COMPAT_OPTIONS="LISTS AS SHOWN ABOVE" \ check-c++ \ RUNTESTFLAGS="compat.exp" A test that fails when the source files are compiled with different compilers, but passes when the files are compiled with the same compiler, demonstrates incompatibility of the generated code or runtime support. A test that fails for the alternate compiler but passes for the compiler under test probably tests for a bug that was fixed in the compiler under test but is present in the alternate compiler. The binary compatibility tests support a small number of test framework commands that appear within comments in a test file. ‘dg-require-*’ These commands can be used in ‘TESTNAME_main.SUFFIX’ to skip the test if specific support is not available on the target. ‘dg-options’ The specified options are used for compiling this particular source file, appended to the options from ‘COMPAT_OPTIONS’. When this command appears in ‘TESTNAME_main.SUFFIX’ the options are also used to link the test program. ‘dg-xfail-if’ This command can be used in a secondary source file to specify that compilation is expected to fail for particular options on particular targets.  File: gccint.info, Node: Torture Tests, Next: GIMPLE Tests, Prev: compat Testing, Up: Testsuites 7.9 Support for torture testing using multiple options ====================================================== Throughout the compiler testsuite there are several directories whose tests are run multiple times, each with a different set of options. These are known as torture tests. ‘lib/torture-options.exp’ defines procedures to set up these lists: ‘torture-init’ Initialize use of torture lists. ‘set-torture-options’ Set lists of torture options to use for tests with and without loops. Optionally combine a set of torture options with a set of other options, as is done with Objective-C runtime options. ‘torture-finish’ Finalize use of torture lists. The ‘.exp’ file for a set of tests that use torture options must include calls to these three procedures if: • It calls ‘gcc-dg-runtest’ and overrides DG_TORTURE_OPTIONS. • It calls ${TOOL}‘-torture’ or ${TOOL}‘-torture-execute’, where TOOL is ‘c’, ‘fortran’, or ‘objc’. • It calls ‘dg-pch’. It is not necessary for a ‘.exp’ file that calls ‘gcc-dg-runtest’ to call the torture procedures if the tests should use the list in DG_TORTURE_OPTIONS defined in ‘gcc-dg.exp’. Most uses of torture options can override the default lists by defining TORTURE_OPTIONS or add to the default list by defining ADDITIONAL_TORTURE_OPTIONS. Define these in a ‘.dejagnurc’ file or add them to the ‘site.exp’ file; for example set ADDITIONAL_TORTURE_OPTIONS [list \ { -O2 -ftree-loop-linear } \ { -O2 -fpeel-loops } ]  File: gccint.info, Node: GIMPLE Tests, Next: RTL Tests, Prev: Torture Tests, Up: Testsuites 7.10 Support for testing GIMPLE passes ====================================== As of gcc 7, C functions can be tagged with ‘__GIMPLE’ to indicate that the function body will be GIMPLE, rather than C. The compiler requires the option ‘-fgimple’ to enable this functionality. For example: /* { dg-do compile } */ /* { dg-options "-O -fgimple" } */ void __GIMPLE (startwith ("dse2")) foo () { int a; bb_2: if (a > 4) goto bb_3; else goto bb_4; bb_3: a_2 = 10; goto bb_5; bb_4: a_3 = 20; bb_5: a_1 = __PHI (bb_3: a_2, bb_4: a_3); a_4 = a_1 + 4; return; } The ‘startwith’ argument indicates at which pass to begin. Use the dump modifier ‘-gimple’ (e.g. ‘-fdump-tree-all-gimple’) to make tree dumps more closely follow the format accepted by the GIMPLE parser. Example DejaGnu tests of GIMPLE can be seen in the source tree at ‘gcc/testsuite/gcc.dg/gimplefe-*.c’. The ‘__GIMPLE’ parser is integrated with the C tokenizer and preprocessor, so it should be possible to use macros to build out test coverage.  File: gccint.info, Node: RTL Tests, Prev: GIMPLE Tests, Up: Testsuites 7.11 Support for testing RTL passes =================================== As of gcc 7, C functions can be tagged with ‘__RTL’ to indicate that the function body will be RTL, rather than C. For example: double __RTL (startwith ("ira")) test (struct foo *f, const struct bar *b) { (function "test" [...snip; various directives go in here...] ) ;; function "test" } The ‘startwith’ argument indicates at which pass to begin. The parser expects the RTL body to be in the format emitted by this dumping function: DEBUG_FUNCTION void print_rtx_function (FILE *outfile, function *fn, bool compact); when "compact" is true. So you can capture RTL in the correct format from the debugger using: (gdb) print_rtx_function (stderr, cfun, true); and copy and paste the output into the body of the C function. Example DejaGnu tests of RTL can be seen in the source tree under ‘gcc/testsuite/gcc.dg/rtl’. The ‘__RTL’ parser is not integrated with the C tokenizer or preprocessor, and works simply by reading the relevant lines within the braces. In particular, the RTL body must be on separate lines from the enclosing braces, and the preprocessor is not usable within it.  File: gccint.info, Node: Options, Next: Passes, Prev: Testsuites, Up: Top 8 Option specification files **************************** Most GCC command-line options are described by special option definition files, the names of which conventionally end in ‘.opt’. This chapter describes the format of these files. * Menu: * Option file format:: The general layout of the files * Option properties:: Supported option properties  File: gccint.info, Node: Option file format, Next: Option properties, Up: Options 8.1 Option file format ====================== Option files are a simple list of records in which each field occupies its own line and in which the records themselves are separated by blank lines. Comments may appear on their own line anywhere within the file and are preceded by semicolons. Whitespace is allowed before the semicolon. The files can contain the following types of record: • A language definition record. These records have two fields: the string ‘Language’ and the name of the language. Once a language has been declared in this way, it can be used as an option property. *Note Option properties::. • A target specific save record to save additional information. These records have two fields: the string ‘TargetSave’, and a declaration type to go in the ‘cl_target_option’ structure. • A variable record to define a variable used to store option information. These records have two fields: the string ‘Variable’, and a declaration of the type and name of the variable, optionally with an initializer (but without any trailing ‘;’). These records may be used for variables used for many options where declaring the initializer in a single option definition record, or duplicating it in many records, would be inappropriate, or for variables set in option handlers rather than referenced by ‘Var’ properties. • A variable record to define a variable used to store option information. These records have two fields: the string ‘TargetVariable’, and a declaration of the type and name of the variable, optionally with an initializer (but without any trailing ‘;’). ‘TargetVariable’ is a combination of ‘Variable’ and ‘TargetSave’ records in that the variable is defined in the ‘gcc_options’ structure, but these variables are also stored in the ‘cl_target_option’ structure. The variables are saved in the target save code and restored in the target restore code. • A variable record to record any additional files that the ‘options.h’ file should include. This is useful to provide enumeration or structure definitions needed for target variables. These records have two fields: the string ‘HeaderInclude’ and the name of the include file. • A variable record to record any additional files that the ‘options.cc’ or ‘options-save.cc’ file should include. This is useful to provide inline functions needed for target variables and/or ‘#ifdef’ sequences to properly set up the initialization. These records have two fields: the string ‘SourceInclude’ and the name of the include file. • An enumeration record to define a set of strings that may be used as arguments to an option or options. These records have three fields: the string ‘Enum’, a space-separated list of properties and help text used to describe the set of strings in ‘--help’ output. Properties use the same format as option properties; the following are valid: ‘Name(NAME)’ This property is required; NAME must be a name (suitable for use in C identifiers) used to identify the set of strings in ‘Enum’ option properties. ‘Type(TYPE)’ This property is required; TYPE is the C type for variables set by options using this enumeration together with ‘Var’. ‘UnknownError(MESSAGE)’ The message MESSAGE will be used as an error message if the argument is invalid; for enumerations without ‘UnknownError’, a generic error message is used. MESSAGE should contain a single ‘%qs’ format, which will be used to format the invalid argument. • An enumeration value record to define one of the strings in a set given in an ‘Enum’ record. These records have two fields: the string ‘EnumValue’ and a space-separated list of properties. Properties use the same format as option properties; the following are valid: ‘Enum(NAME)’ This property is required; NAME says which ‘Enum’ record this ‘EnumValue’ record corresponds to. ‘String(STRING)’ This property is required; STRING is the string option argument being described by this record. ‘Value(VALUE)’ This property is required; it says what value (representable as ‘int’) should be used for the given string. ‘Canonical’ This property is optional. If present, it says the present string is the canonical one among all those with the given value. Other strings yielding that value will be mapped to this one so specs do not need to handle them. ‘DriverOnly’ This property is optional. If present, the present string will only be accepted by the driver. This is used for cases such as ‘-march=native’ that are processed by the driver so that ‘gcc -v’ shows how the options chosen depended on the system on which the compiler was run. ‘Set(NUMBER)’ This property is optional, required for enumerations used in ‘EnumSet’ options. NUMBER should be decimal number between 1 and 64 inclusive and divides the enumeration into a set of sets of mutually exclusive arguments. Arguments with the same NUMBER can't be specified together in the same option, but arguments with different NUMBER can. VALUE needs to be chosen such that a mask of all VALUE values from the same set NUMBER bitwise ored doesn't overlap with masks for other sets. When ‘-foption=arg_from_set1,arg_from_set4’ and ‘-fno-option=arg_from_set3’ are used, the effect is that previous value of the ‘Var’ will get bits from set 1 and 4 masks cleared, ored ‘Value’ of ‘arg_from_set1’ and ‘arg_from_set4’ and then will get bits from set 3 mask cleared. • An option definition record. These records have the following fields: 1. the name of the option, with the leading "-" removed 2. a space-separated list of option properties (*note Option properties::) 3. the help text to use for ‘--help’ (omitted if the second field contains the ‘Undocumented’ property). By default, all options beginning with "f", "g", "W" or "m" are implicitly assumed to take a "no-" form. This form should not be listed separately. If an option beginning with one of these letters does not have a "no-" form, you can use the ‘RejectNegative’ property to reject it. The help text is automatically line-wrapped before being displayed. Normally the name of the option is printed on the left-hand side of the output and the help text is printed on the right. However, if the help text contains a tab character, the text to the left of the tab is used instead of the option's name and the text to the right of the tab forms the help text. This allows you to elaborate on what type of argument the option takes. There is no support for different help texts for different languages. If an option is supported for multiple languages, use a generic description that is correct for all of them. If an option has multiple option definition records (in different front ends' ‘*.opt’ files, and/or ‘gcc/common.opt’, for example), convention is to not duplicate the help text for each of them, but instead put a comment like ‘; documented in common.opt’ in place of the help text for all but one of the multiple option definition records. • A target mask record. These records have one field of the form ‘Mask(X)’. The options-processing script will automatically allocate a bit in ‘target_flags’ (*note Run-time Target::) for each mask name X and set the macro ‘MASK_X’ to the appropriate bitmask. It will also declare a ‘TARGET_X’ macro that has the value 1 when bit ‘MASK_X’ is set and 0 otherwise. They are primarily intended to declare target masks that are not associated with user options, either because these masks represent internal switches or because the options are not available on all configurations and yet the masks always need to be defined.  File: gccint.info, Node: Option properties, Prev: Option file format, Up: Options 8.2 Option properties ===================== The second field of an option record can specify any of the following properties. When an option takes an argument, it is enclosed in parentheses following the option property name. The parser that handles option files is quite simplistic, and will be tricked by any nested parentheses within the argument text itself; in this case, the entire option argument can be wrapped in curly braces within the parentheses to demarcate it, e.g.: Condition({defined (USE_CYGWIN_LIBSTDCXX_WRAPPERS)}) ‘Common’ The option is available for all languages and targets. ‘Target’ The option is available for all languages but is target-specific. ‘Driver’ The option is handled by the compiler driver using code not shared with the compilers proper (‘cc1’ etc.). ‘LANGUAGE’ The option is available when compiling for the given language. It is possible to specify several different languages for the same option. Each LANGUAGE must have been declared by an earlier ‘Language’ record. *Note Option file format::. ‘RejectDriver’ The option is only handled by the compilers proper (‘cc1’ etc.) and should not be accepted by the driver. ‘RejectNegative’ The option does not have a "no-" form. All options beginning with "f", "g", "W" or "m" are assumed to have a "no-" form unless this property is used. ‘Negative(OTHERNAME)’ The option will turn off another option OTHERNAME, which is the option name with the leading "-" removed. This chain action will propagate through the ‘Negative’ property of the option to be turned off. The driver will prune options, removing those that are turned off by some later option. This pruning is not done for options with ‘Joined’ or ‘JoinedOrMissing’ properties, unless the options have both the ‘RejectNegative’ property and the ‘Negative’ property mentions itself. As a consequence, if you have a group of mutually-exclusive options, their ‘Negative’ properties should form a circular chain. For example, if options ‘-A’, ‘-B’ and ‘-C’ are mutually exclusive, their respective ‘Negative’ properties should be ‘Negative(B)’, ‘Negative(C)’ and ‘Negative(A)’. ‘Joined’ ‘Separate’ The option takes a mandatory argument. ‘Joined’ indicates that the option and argument can be included in the same ‘argv’ entry (as with ‘-mflush-func=NAME’, for example). ‘Separate’ indicates that the option and argument can be separate ‘argv’ entries (as with ‘-o’). An option is allowed to have both of these properties. ‘JoinedOrMissing’ The option takes an optional argument. If the argument is given, it will be part of the same ‘argv’ entry as the option itself. This property cannot be used alongside ‘Joined’ or ‘Separate’. ‘MissingArgError(MESSAGE)’ For an option marked ‘Joined’ or ‘Separate’, the message MESSAGE will be used as an error message if the mandatory argument is missing; for options without ‘MissingArgError’, a generic error message is used. MESSAGE should contain a single ‘%qs’ format, which will be used to format the name of the option passed. ‘Args(N)’ For an option marked ‘Separate’, indicate that it takes N arguments. The default is 1. ‘UInteger’ The option's argument is a non-negative integer consisting of either decimal or hexadecimal digits interpreted as ‘int’. Hexadecimal integers may optionally start with the ‘0x’ or ‘0X’ prefix. The option parser validates and converts the argument before passing it to the relevant option handler. ‘UInteger’ should also be used with options like ‘-falign-loops’ where both ‘-falign-loops’ and ‘-falign-loops’=N are supported to make sure the saved options are given a full integer. Positive values of the argument in excess of ‘INT_MAX’ wrap around zero. ‘Host_Wide_Int’ The option's argument is a non-negative integer consisting of either decimal or hexadecimal digits interpreted as the widest integer type on the host. As with an ‘UInteger’ argument, hexadecimal integers may optionally start with the ‘0x’ or ‘0X’ prefix. The option parser validates and converts the argument before passing it to the relevant option handler. ‘Host_Wide_Int’ should be used with options that need to accept very large values. Positive values of the argument in excess of ‘HOST_WIDE_INT_M1U’ are assigned ‘HOST_WIDE_INT_M1U’. ‘IntegerRange(N, M)’ The options's arguments are integers of type ‘int’. The option's parser validates that the value of an option integer argument is within the closed range [N, M]. ‘ByteSize’ A property applicable only to ‘UInteger’ or ‘Host_Wide_Int’ arguments. The option's integer argument is interpreted as if in infinite precision using saturation arithmetic in the corresponding type. The argument may be followed by a ‘byte-size’ suffix designating a multiple of bytes such as ‘kB’ and ‘KiB’ for kilobyte and kibibyte, respectively, ‘MB’ and ‘MiB’ for megabyte and mebibyte, ‘GB’ and ‘GiB’ for gigabyte and gigibyte, and so on. ‘ByteSize’ should be used for with options that take a very large argument representing a size in bytes, such as ‘-Wlarger-than=’. ‘ToLower’ The option's argument should be converted to lowercase as part of putting it in canonical form, and before comparing with the strings indicated by any ‘Enum’ property. ‘NoDriverArg’ For an option marked ‘Separate’, the option only takes an argument in the compiler proper, not in the driver. This is for compatibility with existing options that are used both directly and via ‘-Wp,’; new options should not have this property. ‘Var(VAR)’ The state of this option should be stored in variable VAR (actually a macro for ‘global_options.x_VAR’). The way that the state is stored depends on the type of option: • If the option uses the ‘Mask’ or ‘InverseMask’ properties, VAR is the integer variable that contains the mask. • If the option is a normal on/off switch, VAR is an integer variable that is nonzero when the option is enabled. The options parser will set the variable to 1 when the positive form of the option is used and 0 when the "no-" form is used. • If the option takes an argument and has the ‘UInteger’ property, VAR is an integer variable that stores the value of the argument. • If the option takes an argument and has the ‘Enum’ property, VAR is a variable (type given in the ‘Type’ property of the ‘Enum’ record whose ‘Name’ property has the same argument as the ‘Enum’ property of this option) that stores the value of the argument. • If the option has the ‘Defer’ property, VAR is a pointer to a ‘VEC(cl_deferred_option,heap)’ that stores the option for later processing. (VAR is declared with type ‘void *’ and needs to be cast to ‘VEC(cl_deferred_option,heap)’ before use.) • Otherwise, if the option takes an argument, VAR is a pointer to the argument string. The pointer will be null if the argument is optional and wasn't given. The option-processing script will usually zero-initialize VAR. You can modify this behavior using ‘Init’. ‘Var(VAR, SET)’ The option controls an integer variable VAR and is active when VAR equals SET. The option parser will set VAR to SET when the positive form of the option is used and ‘!SET’ when the "no-" form is used. VAR is declared in the same way as for the single-argument form described above. ‘Init(VALUE)’ The variable specified by the ‘Var’ property should be statically initialized to VALUE. If more than one option using the same variable specifies ‘Init’, all must specify the same initializer. ‘WarnRemoved’ The option is removed and every usage of such option will result in a warning. We use it option backward compatibility. ‘Mask(NAME)’ The option is associated with a bit in the ‘target_flags’ variable (*note Run-time Target::) and is active when that bit is set. You may also specify ‘Var’ to select a variable other than ‘target_flags’. The options-processing script will automatically allocate a unique bit for the option. If the option is attached to ‘target_flags’ or ‘Var’ which is defined by ‘TargetVariable’, the script will set the macro ‘MASK_NAME’ to the appropriate bitmask. It will also declare a ‘TARGET_NAME’, ‘TARGET_NAME_P’ and ‘TARGET_NAME_OPTS_P’: ‘TARGET_NAME’ macros that has the value 1 when the option is active and 0 otherwise, ‘TARGET_NAME_P’ is similar to ‘TARGET_NAME’ but take an argument as ‘target_flags’ or ‘TargetVariable’, and ‘TARGET_NAME_OPTS_P’ also similar to ‘TARGET_NAME’ but take an argument as ‘gcc_options’. If you use ‘Var’ to attach the option to a different variable which is not defined by ‘TargetVariable’, the bitmask macro with be called ‘OPTION_MASK_NAME’. ‘InverseMask(OTHERNAME)’ ‘InverseMask(OTHERNAME, THISNAME)’ The option is the inverse of another option that has the ‘Mask(OTHERNAME)’ property. If THISNAME is given, the options-processing script will declare ‘TARGET_THISNAME’, ‘TARGET_NAME_P’ and ‘TARGET_NAME_OPTS_P’ macros: ‘TARGET_THISNAME’ is 1 when the option is active and 0 otherwise, ‘TARGET_NAME_P’ is similar to ‘TARGET_NAME’ but take an argument as ‘target_flags’, and and ‘TARGET_NAME_OPTS_P’ also similar to ‘TARGET_NAME’ but take an argument as ‘gcc_options’. ‘Enum(NAME)’ The option's argument is a string from the set of strings associated with the corresponding ‘Enum’ record. The string is checked and converted to the integer specified in the corresponding ‘EnumValue’ record before being passed to option handlers. ‘EnumSet’ Must be used together with the ‘Enum(NAME)’ property. Corresponding ‘Enum’ record must use ‘Set’ properties. The option's argument is either a string from the set like for ‘Enum(NAME)’, but with a slightly different behavior that the whole ‘Var’ isn't overwritten, but only the bits in all the enumeration values with the same set bitwise ored together. Or option's argument can be a comma separated list of strings where each string is from a different ‘Set(NUMBER)’. ‘EnumBitSet’ Must be used together with the ‘Enum(NAME)’ property. Similar to ‘EnumSet’, but corresponding ‘Enum’ record must not use ‘Set’ properties, each ‘EnumValue’ should have ‘Value’ that is a power of 2, each value is treated as its own set and its value as the set's mask, so there are no mutually exclusive arguments. ‘Defer’ The option should be stored in a vector, specified with ‘Var’, for later processing. ‘Alias(OPT)’ ‘Alias(OPT, ARG)’ ‘Alias(OPT, POSARG, NEGARG)’ The option is an alias for ‘-OPT’ (or the negative form of that option, depending on ‘NegativeAlias’). In the first form, any argument passed to the alias is considered to be passed to ‘-OPT’, and ‘-OPT’ is considered to be negated if the alias is used in negated form. In the second form, the alias may not be negated or have an argument, and POSARG is considered to be passed as an argument to ‘-OPT’. In the third form, the alias may not have an argument, if the alias is used in the positive form then POSARG is considered to be passed to ‘-OPT’, and if the alias is used in the negative form then NEGARG is considered to be passed to ‘-OPT’. Aliases should not specify ‘Var’ or ‘Mask’ or ‘UInteger’. Aliases should normally specify the same languages as the target of the alias; the flags on the target will be used to determine any diagnostic for use of an option for the wrong language, while those on the alias will be used to identify what command-line text is the option and what text is any argument to that option. When an ‘Alias’ definition is used for an option, driver specs do not need to handle it and no ‘OPT_’ enumeration value is defined for it; only the canonical form of the option will be seen in those places. ‘NegativeAlias’ For an option marked with ‘Alias(OPT)’, the option is considered to be an alias for the positive form of ‘-OPT’ if negated and for the negative form of ‘-OPT’ if not negated. ‘NegativeAlias’ may not be used with the forms of ‘Alias’ taking more than one argument. ‘Ignore’ This option is ignored apart from printing any warning specified using ‘Warn’. The option will not be seen by specs and no ‘OPT_’ enumeration value is defined for it. ‘SeparateAlias’ For an option marked with ‘Joined’, ‘Separate’ and ‘Alias’, the option only acts as an alias when passed a separate argument; with a joined argument it acts as a normal option, with an ‘OPT_’ enumeration value. This is for compatibility with the Java ‘-d’ option and should not be used for new options. ‘Warn(MESSAGE)’ If this option is used, output the warning MESSAGE. MESSAGE is a format string, either taking a single operand with a ‘%qs’ format which is the option name, or not taking any operands, which is passed to the ‘warning’ function. If an alias is marked ‘Warn’, the target of the alias must not also be marked ‘Warn’. ‘Warning’ This is a warning option and should be shown as such in ‘--help’ output. This flag does not currently affect anything other than ‘--help’. ‘Optimization’ This is an optimization option. It should be shown as such in ‘--help’ output, and any associated variable named using ‘Var’ should be saved and restored when the optimization level is changed with ‘optimize’ attributes. ‘PerFunction’ This is an option that can be overridden on a per-function basis. ‘Optimization’ implies ‘PerFunction’, but options that do not affect executable code generation may use this flag instead, so that the option is not taken into account in ways that might affect executable code generation. ‘Param’ This is an option that is a parameter. ‘Undocumented’ The option is deliberately missing documentation and should not be included in the ‘--help’ output. ‘Condition(COND)’ The option should only be accepted if preprocessor condition COND is true. Note that any C declarations associated with the option will be present even if COND is false; COND simply controls whether the option is accepted and whether it is printed in the ‘--help’ output. ‘Save’ Build the ‘cl_target_option’ structure to hold a copy of the option, add the functions ‘cl_target_option_save’ and ‘cl_target_option_restore’ to save and restore the options. ‘SetByCombined’ The option may also be set by a combined option such as ‘-ffast-math’. This causes the ‘gcc_options’ struct to have a field ‘frontend_set_NAME’, where ‘NAME’ is the name of the field holding the value of this option (without the leading ‘x_’). This gives the front end a way to indicate that the value has been set explicitly and should not be changed by the combined option. For example, some front ends use this to prevent ‘-ffast-math’ and ‘-fno-fast-math’ from changing the value of ‘-fmath-errno’ for languages that do not use ‘errno’. ‘EnabledBy(OPT)’ ‘EnabledBy(OPT || OPT2)’ ‘EnabledBy(OPT && OPT2)’ If not explicitly set, the option is set to the value of ‘-OPT’; multiple options can be given, separated by ‘||’. The third form using ‘&&’ specifies that the option is only set if both OPT and OPT2 are set. The options OPT and OPT2 must have the ‘Common’ property; otherwise, use ‘LangEnabledBy’. ‘LangEnabledBy(LANGUAGE, OPT)’ ‘LangEnabledBy(LANGUAGE, OPT, POSARG, NEGARG)’ When compiling for the given language, the option is set to the value of ‘-OPT’, if not explicitly set. OPT can be also a list of ‘||’ separated options. In the second form, if OPT is used in the positive form then POSARG is considered to be passed to the option, and if OPT is used in the negative form then NEGARG is considered to be passed to the option. It is possible to specify several different languages. Each LANGUAGE must have been declared by an earlier ‘Language’ record. *Note Option file format::. ‘NoDWARFRecord’ The option is omitted from the producer string written by ‘-grecord-gcc-switches’. ‘PchIgnore’ Even if this is a target option, this option will not be recorded / compared to determine if a precompiled header file matches. ‘CPP(VAR)’ The state of this option should be kept in sync with the preprocessor option VAR. If this property is set, then properties ‘Var’ and ‘Init’ must be set as well. ‘CppReason(CPP_W_ENUM)’ This warning option corresponds to ‘cpplib.h’ warning reason code CPP_W_ENUM. This should only be used for warning options of the C-family front-ends. ‘UrlSuffix(URL_SUFFIX)’ Adjacent to each human-written ‘.opt’ file in the source tree is a corresponding file with a ‘.opt.urls’ extension. These files contain ‘UrlSuffix’ directives giving the ending part of the URL for the documentation of the option, such as: Wabi-tag UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wabi-tag) These URL suffixes are relative to ‘DOCUMENTATION_ROOT_URL’. There files are generated from the ‘.opt’ files and the generated HTML documentation by ‘regenerate-opt-urls.py’, and should be regenerated when adding new options, via manually invoking ‘make regenerate-opt-urls’. ‘LangUrlSuffix_LANG(URL_SUFFIX)’ In addition to ‘UrlSuffix’ directives, ‘regenerate-opt-urls.py’ can generate language-specific URLs, such as: LangUrlSuffix_D(gdc/Code-Generation.html#index-MMD)  File: gccint.info, Node: Passes, Next: poly_int, Prev: Options, Up: Top 9 Passes and Files of the Compiler ********************************** This chapter is dedicated to giving an overview of the optimization and code generation passes of the compiler. In the process, it describes some of the language front end interface, though this description is no where near complete. * Menu: * Parsing pass:: The language front end turns text into bits. * Gimplification pass:: The bits are turned into something we can optimize. * Pass manager:: Sequencing the optimization passes. * IPA passes:: Inter-procedural optimizations. * Tree SSA passes:: Optimizations on a high-level representation. * RTL passes:: Optimizations on a low-level representation. * Optimization info:: Dumping optimization information from passes.  File: gccint.info, Node: Parsing pass, Next: Gimplification pass, Up: Passes 9.1 Parsing pass ================ The language front end is invoked only once, via ‘lang_hooks.parse_file’, to parse the entire input. The language front end may use any intermediate language representation deemed appropriate. The C front end uses GENERIC trees (*note GENERIC::), plus a double handful of language specific tree codes defined in ‘c-common.def’. The Fortran front end uses a completely different private representation. At some point the front end must translate the representation used in the front end to a representation understood by the language-independent portions of the compiler. Current practice takes one of two forms. The C front end manually invokes the gimplifier (*note GIMPLE::) on each function, and uses the gimplifier callbacks to convert the language-specific tree nodes directly to GIMPLE before passing the function off to be compiled. The Fortran front end converts from a private representation to GENERIC, which is later lowered to GIMPLE when the function is compiled. Which route to choose probably depends on how well GENERIC (plus extensions) can be made to match up with the source language and necessary parsing data structures. BUG: Gimplification must occur before nested function lowering, and nested function lowering must be done by the front end before passing the data off to cgraph. TODO: Cgraph should control nested function lowering. It would only be invoked when it is certain that the outer-most function is used. TODO: Cgraph needs a gimplify_function callback. It should be invoked when (1) it is certain that the function is used, (2) warning flags specified by the user require some amount of compilation in order to honor, (3) the language indicates that semantic analysis is not complete until gimplification occurs. Hum... this sounds overly complicated. Perhaps we should just have the front end gimplify always; in most cases it's only one function call. The front end needs to pass all function definitions and top level declarations off to the middle-end so that they can be compiled and emitted to the object file. For a simple procedural language, it is usually most convenient to do this as each top level declaration or definition is seen. There is also a distinction to be made between generating functional code and generating complete debug information. The only thing that is absolutely required for functional code is that function and data _definitions_ be passed to the middle-end. For complete debug information, function, data and type declarations should all be passed as well. In any case, the front end needs each complete top-level function or data declaration, and each data definition should be passed to ‘rest_of_decl_compilation’. Each complete type definition should be passed to ‘rest_of_type_compilation’. Each function definition should be passed to ‘cgraph_finalize_function’. TODO: I know rest_of_compilation currently has all sorts of RTL generation semantics. I plan to move all code generation bits (both Tree and RTL) to compile_function. Should we hide cgraph from the front ends and move back to rest_of_compilation as the official interface? Possibly we should rename all three interfaces such that the names match in some meaningful way and that is more descriptive than "rest_of". The middle-end will, at its option, emit the function and data definitions immediately or queue them for later processing.  File: gccint.info, Node: Gimplification pass, Next: Pass manager, Prev: Parsing pass, Up: Passes 9.2 Gimplification pass ======================= “Gimplification” is a whimsical term for the process of converting the intermediate representation of a function into the GIMPLE language (*note GIMPLE::). The term stuck, and so words like "gimplification", "gimplify", "gimplifier" and the like are sprinkled throughout this section of code. While a front end may certainly choose to generate GIMPLE directly if it chooses, this can be a moderately complex process unless the intermediate language used by the front end is already fairly simple. Usually it is easier to generate GENERIC trees plus extensions and let the language-independent gimplifier do most of the work. The main entry point to this pass is ‘gimplify_function_tree’ located in ‘gimplify.cc’. From here we process the entire function gimplifying each statement in turn. The main workhorse for this pass is ‘gimplify_expr’. Approximately everything passes through here at least once, and it is from here that we invoke the ‘lang_hooks.gimplify_expr’ callback. The callback should examine the expression in question and return ‘GS_UNHANDLED’ if the expression is not a language specific construct that requires attention. Otherwise it should alter the expression in some way to such that forward progress is made toward producing valid GIMPLE. If the callback is certain that the transformation is complete and the expression is valid GIMPLE, it should return ‘GS_ALL_DONE’. Otherwise it should return ‘GS_OK’, which will cause the expression to be processed again. If the callback encounters an error during the transformation (because the front end is relying on the gimplification process to finish semantic checks), it should return ‘GS_ERROR’.  File: gccint.info, Node: Pass manager, Next: IPA passes, Prev: Gimplification pass, Up: Passes 9.3 Pass manager ================ The pass manager is located in ‘passes.cc’, ‘tree-optimize.c’ and ‘tree-pass.h’. It processes passes as described in ‘passes.def’. Its job is to run all of the individual passes in the correct order, and take care of standard bookkeeping that applies to every pass. The theory of operation is that each pass defines a structure that represents everything we need to know about that pass--when it should be run, how it should be run, what intermediate language form or on-the-side data structures it needs. We register the pass to be run in some particular order, and the pass manager arranges for everything to happen in the correct order. The actuality doesn't completely live up to the theory at present. Command-line switches and ‘timevar_id_t’ enumerations must still be defined elsewhere. The pass manager validates constraints but does not attempt to (re-)generate data structures or lower intermediate language form based on the requirements of the next pass. Nevertheless, what is present is useful, and a far sight better than nothing at all. Each pass should have a unique name. Each pass may have its own dump file (for GCC debugging purposes). Passes with a name starting with a star do not dump anything. Sometimes passes are supposed to share a dump file / option name. To still give these unique names, you can use a prefix that is delimited by a space from the part that is used for the dump file / option name. E.g. When the pass name is "ud dce", the name used for dump file/options is "dce". TODO: describe the global variables set up by the pass manager, and a brief description of how a new pass should use it. I need to look at what info RTL passes use first...  File: gccint.info, Node: IPA passes, Next: Tree SSA passes, Prev: Pass manager, Up: Passes 9.4 Inter-procedural optimization passes ======================================== The inter-procedural optimization (IPA) passes use call graph information to perform transformations across function boundaries. IPA is a critical part of link-time optimization (LTO) and whole-program (WHOPR) optimization, and these passes are structured with the needs of LTO and WHOPR in mind by dividing their operations into stages. For detailed discussion of the LTO/WHOPR IPA pass stages and interfaces, see *note IPA::. The following briefly describes the inter-procedural optimization (IPA) passes, which are split into small IPA passes, regular IPA passes, and late IPA passes, according to the LTO/WHOPR processing model. * Menu: * Small IPA passes:: * Regular IPA passes:: * Late IPA passes::  File: gccint.info, Node: Small IPA passes, Next: Regular IPA passes, Up: IPA passes 9.4.1 Small IPA passes ---------------------- A small IPA pass is a pass derived from ‘simple_ipa_opt_pass’. As described in *note IPA::, it does everything at once and defines only the _Execute_ stage. During this stage it accesses and modifies the function bodies. No ‘generate_summary’, ‘read_summary’, or ‘write_summary’ hooks are defined. • IPA free lang data This pass frees resources that are used by the front end but are not needed once it is done. It is located in ‘tree.cc’ and is described by ‘pass_ipa_free_lang_data’. • IPA function and variable visibility This is a local function pass handling visibilities of all symbols. This happens before LTO streaming, so ‘-fwhole-program’ should be ignored at this level. It is located in ‘ipa-visibility.cc’ and is described by ‘pass_ipa_function_and_variable_visibility’. • IPA remove symbols This pass performs reachability analysis and reclaims all unreachable nodes. It is located in ‘passes.cc’ and is described by ‘pass_ipa_remove_symbols’. • IPA OpenACC This is a pass group for OpenACC processing. It is located in ‘tree-ssa-loop.cc’ and is described by ‘pass_ipa_oacc’. • IPA points-to analysis This is a tree-based points-to analysis pass. The idea behind this analyzer is to generate set constraints from the program, then solve the resulting constraints in order to generate the points-to sets. It is located in ‘tree-ssa-structalias.cc’ and is described by ‘pass_ipa_pta’. • IPA OpenACC kernels This is a pass group for processing OpenACC kernels regions. It is a subpass of the IPA OpenACC pass group that runs on offloaded functions containing OpenACC kernels loops. It is located in ‘tree-ssa-loop.cc’ and is described by ‘pass_ipa_oacc_kernels’. • Target clone This is a pass for parsing functions with multiple target attributes. It is located in ‘multiple_target.cc’ and is described by ‘pass_target_clone’. • IPA auto profile This pass uses AutoFDO profiling data to annotate the control flow graph. It is located in ‘auto-profile.cc’ and is described by ‘pass_ipa_auto_profile’. • IPA tree profile This pass does profiling for all functions in the call graph. It calculates branch probabilities and basic block execution counts. It is located in ‘tree-profile.cc’ and is described by ‘pass_ipa_tree_profile’. • IPA free function summary This pass is a small IPA pass when argument ‘small_p’ is true. It releases inline function summaries and call summaries. It is located in ‘ipa-fnsummary.cc’ and is described by ‘pass_ipa_free_free_fn_summary’. • IPA increase alignment This pass increases the alignment of global arrays to improve vectorization. It is located in ‘tree-vectorizer.cc’ and is described by ‘pass_ipa_increase_alignment’. • IPA transactional memory This pass is for transactional memory support. It is located in ‘trans-mem.cc’ and is described by ‘pass_ipa_tm’. • IPA lower emulated TLS This pass lowers thread-local storage (TLS) operations to emulation functions provided by libgcc. It is located in ‘tree-emutls.cc’ and is described by ‘pass_ipa_lower_emutls’.  File: gccint.info, Node: Regular IPA passes, Next: Late IPA passes, Prev: Small IPA passes, Up: IPA passes 9.4.2 Regular IPA passes ------------------------ A regular IPA pass is a pass derived from ‘ipa_opt_pass_d’ that is executed in WHOPR compilation. Regular IPA passes may have summary hooks implemented in any of the LGEN, WPA or LTRANS stages (*note IPA::). • IPA whole program visibility This pass performs various optimizations involving symbol visibility with ‘-fwhole-program’, including symbol privatization, discovering local functions, and dismantling comdat groups. It is located in ‘ipa-visibility.cc’ and is described by ‘pass_ipa_whole_program_visibility’. • IPA profile The IPA profile pass propagates profiling frequencies across the call graph. It is located in ‘ipa-profile.cc’ and is described by ‘pass_ipa_profile’. • IPA identical code folding This is the inter-procedural identical code folding pass. The goal of this transformation is to discover functions and read-only variables that have exactly the same semantics. It is located in ‘ipa-icf.cc’ and is described by ‘pass_ipa_icf’. • IPA devirtualization This pass performs speculative devirtualization based on the type inheritance graph. When a polymorphic call has only one likely target in the unit, it is turned into a speculative call. It is located in ‘ipa-devirt.cc’ and is described by ‘pass_ipa_devirt’. • IPA constant propagation The goal of this pass is to discover functions that are always invoked with some arguments with the same known constant values and to modify the functions accordingly. It can also do partial specialization and type-based devirtualization. It is located in ‘ipa-cp.cc’ and is described by ‘pass_ipa_cp’. • IPA scalar replacement of aggregates This pass can replace an aggregate parameter with a set of other parameters representing part of the original, turning those passed by reference into new ones which pass the value directly. It also removes unused function return values and unused function parameters. This pass is located in ‘ipa-sra.cc’ and is described by ‘pass_ipa_sra’. • IPA constructor/destructor merge This pass merges multiple constructors and destructors for static objects into single functions. It's only run at LTO time unless the target doesn't support constructors and destructors natively. The pass is located in ‘ipa.cc’ and is described by ‘pass_ipa_cdtor_merge’. • IPA function summary This pass provides function analysis for inter-procedural passes. It collects estimates of function body size, execution time, and frame size for each function. It also estimates information about function calls: call statement size, time and how often the parameters change for each call. It is located in ‘ipa-fnsummary.cc’ and is described by ‘pass_ipa_fn_summary’. • IPA inline The IPA inline pass handles function inlining with whole-program knowledge. Small functions that are candidates for inlining are ordered in increasing badness, bounded by unit growth parameters. Unreachable functions are removed from the call graph. Functions called once and not exported from the unit are inlined. This pass is located in ‘ipa-inline.cc’ and is described by ‘pass_ipa_inline’. • IPA pure/const analysis This pass marks functions as being either const (‘TREE_READONLY’) or pure (‘DECL_PURE_P’). The per-function information is produced by ‘pure_const_generate_summary’, then the global information is computed by performing a transitive closure over the call graph. It is located in ‘ipa-pure-const.cc’ and is described by ‘pass_ipa_pure_const’. • IPA free function summary This pass is a regular IPA pass when argument ‘small_p’ is false. It releases inline function summaries and call summaries. It is located in ‘ipa-fnsummary.cc’ and is described by ‘pass_ipa_free_fn_summary’. • IPA reference This pass gathers information about how variables whose scope is confined to the compilation unit are used. It is located in ‘ipa-reference.cc’ and is described by ‘pass_ipa_reference’. • IPA single use This pass checks whether variables are used by a single function. It is located in ‘ipa.cc’ and is described by ‘pass_ipa_single_use’. • IPA comdats This pass looks for static symbols that are used exclusively within one comdat group, and moves them into that comdat group. It is located in ‘ipa-comdats.cc’ and is described by ‘pass_ipa_comdats’.  File: gccint.info, Node: Late IPA passes, Prev: Regular IPA passes, Up: IPA passes 9.4.3 Late IPA passes --------------------- Late IPA passes are simple IPA passes executed after the regular passes. In WHOPR mode the passes are executed after partitioning and thus see just parts of the compiled unit. • Materialize all clones Once all functions from compilation unit are in memory, produce all clones and update all calls. It is located in ‘ipa.cc’ and is described by ‘pass_materialize_all_clones’. • IPA points-to analysis Points-to analysis; this is the same as the points-to-analysis pass run with the small IPA passes (*note Small IPA passes::). • OpenMP simd clone This is the OpenMP constructs' SIMD clone pass. It creates the appropriate SIMD clones for functions tagged as elemental SIMD functions. It is located in ‘omp-simd-clone.cc’ and is described by ‘pass_omp_simd_clone’.  File: gccint.info, Node: Tree SSA passes, Next: RTL passes, Prev: IPA passes, Up: Passes 9.5 Tree SSA passes =================== The following briefly describes the Tree optimization passes that are run after gimplification and what source files they are located in. • Remove useless statements This pass is an extremely simple sweep across the gimple code in which we identify obviously dead code and remove it. Here we do things like simplify ‘if’ statements with constant conditions, remove exception handling constructs surrounding code that obviously cannot throw, remove lexical bindings that contain no variables, and other assorted simplistic cleanups. The idea is to get rid of the obvious stuff quickly rather than wait until later when it's more work to get rid of it. This pass is located in ‘tree-cfg.cc’ and described by ‘pass_remove_useless_stmts’. • OpenMP lowering If OpenMP generation (‘-fopenmp’) is enabled, this pass lowers OpenMP constructs into GIMPLE. Lowering of OpenMP constructs involves creating replacement expressions for local variables that have been mapped using data sharing clauses, exposing the control flow of most synchronization directives and adding region markers to facilitate the creation of the control flow graph. The pass is located in ‘omp-low.cc’ and is described by ‘pass_lower_omp’. • OpenMP expansion If OpenMP generation (‘-fopenmp’) is enabled, this pass expands parallel regions into their own functions to be invoked by the thread library. The pass is located in ‘omp-low.cc’ and is described by ‘pass_expand_omp’. • Lower control flow This pass flattens ‘if’ statements (‘COND_EXPR’) and moves lexical bindings (‘BIND_EXPR’) out of line. After this pass, all ‘if’ statements will have exactly two ‘goto’ statements in its ‘then’ and ‘else’ arms. Lexical binding information for each statement will be found in ‘TREE_BLOCK’ rather than being inferred from its position under a ‘BIND_EXPR’. This pass is found in ‘gimple-low.cc’ and is described by ‘pass_lower_cf’. • Lower exception handling control flow This pass decomposes high-level exception handling constructs (‘TRY_FINALLY_EXPR’ and ‘TRY_CATCH_EXPR’) into a form that explicitly represents the control flow involved. After this pass, ‘lookup_stmt_eh_region’ will return a non-negative number for any statement that may have EH control flow semantics; examine ‘tree_can_throw_internal’ or ‘tree_can_throw_external’ for exact semantics. Exact control flow may be extracted from ‘foreach_reachable_handler’. The EH region nesting tree is defined in ‘except.h’ and built in ‘except.cc’. The lowering pass itself is in ‘tree-eh.cc’ and is described by ‘pass_lower_eh’. • Build the control flow graph This pass decomposes a function into basic blocks and creates all of the edges that connect them. It is located in ‘tree-cfg.cc’ and is described by ‘pass_build_cfg’. • Find all referenced variables This pass walks the entire function and collects an array of all variables referenced in the function, ‘referenced_vars’. The index at which a variable is found in the array is used as a UID for the variable within this function. This data is needed by the SSA rewriting routines. The pass is located in ‘tree-dfa.cc’ and is described by ‘pass_referenced_vars’. • Enter static single assignment form This pass rewrites the function such that it is in SSA form. After this pass, all ‘is_gimple_reg’ variables will be referenced by ‘SSA_NAME’, and all occurrences of other variables will be annotated with ‘VDEFS’ and ‘VUSES’; PHI nodes will have been inserted as necessary for each basic block. This pass is located in ‘tree-ssa.cc’ and is described by ‘pass_build_ssa’. • Warn for uninitialized variables This pass scans the function for uses of ‘SSA_NAME’s that are fed by default definition. For non-parameter variables, such uses are uninitialized. The pass is run twice, before and after optimization (if turned on). In the first pass we only warn for uses that are positively uninitialized; in the second pass we warn for uses that are possibly uninitialized. The pass is located in ‘tree-ssa.cc’ and is defined by ‘pass_early_warn_uninitialized’ and ‘pass_late_warn_uninitialized’. • Dead code elimination This pass scans the function for statements without side effects whose result is unused. It does not do memory lifetime analysis, so any value that is stored in memory is considered used. The pass is run multiple times throughout the optimization process. It is located in ‘tree-ssa-dce.cc’ and is described by ‘pass_dce’. • Dominator optimizations This pass performs trivial dominator-based copy and constant propagation, expression simplification, and jump threading. It is run multiple times throughout the optimization process. It is located in ‘tree-ssa-dom.cc’ and is described by ‘pass_dominator’. • Forward propagation of single-use variables This pass attempts to remove redundant computation by substituting variables that are used once into the expression that uses them and seeing if the result can be simplified. It is located in ‘tree-ssa-forwprop.cc’ and is described by ‘pass_forwprop’. • Copy Renaming This pass attempts to change the name of compiler temporaries involved in copy operations such that SSA->normal can coalesce the copy away. When compiler temporaries are copies of user variables, it also renames the compiler temporary to the user variable resulting in better use of user symbols. It is located in ‘tree-ssa-copyrename.c’ and is described by ‘pass_copyrename’. • PHI node optimizations This pass recognizes forms of PHI inputs that can be represented as conditional expressions and rewrites them into straight line code. It is located in ‘tree-ssa-phiopt.cc’ and is described by ‘pass_phiopt’. • May-alias optimization This pass performs a flow sensitive SSA-based points-to analysis. The resulting may-alias, must-alias, and escape analysis information is used to promote variables from in-memory addressable objects to non-aliased variables that can be renamed into SSA form. We also update the ‘VDEF’/‘VUSE’ memory tags for non-renameable aggregates so that we get fewer false kills. The pass is located in ‘tree-ssa-alias.cc’ and is described by ‘pass_may_alias’. Interprocedural points-to information is located in ‘tree-ssa-structalias.cc’ and described by ‘pass_ipa_pta’. • Profiling This pass instruments the function in order to collect runtime block and value profiling data. Such data may be fed back into the compiler on a subsequent run so as to allow optimization based on expected execution frequencies. The pass is located in ‘tree-profile.cc’ and is described by ‘pass_ipa_tree_profile’. • Static profile estimation This pass implements series of heuristics to guess propababilities of branches. The resulting predictions are turned into edge profile by propagating branches across the control flow graphs. The pass is located in ‘tree-profile.cc’ and is described by ‘pass_profile’. • Lower complex arithmetic This pass rewrites complex arithmetic operations into their component scalar arithmetic operations. The pass is located in ‘tree-complex.cc’ and is described by ‘pass_lower_complex’. • Scalar replacement of aggregates This pass rewrites suitable non-aliased local aggregate variables into a set of scalar variables. The resulting scalar variables are rewritten into SSA form, which allows subsequent optimization passes to do a significantly better job with them. The pass is located in ‘tree-sra.cc’ and is described by ‘pass_sra’. • Dead store elimination This pass eliminates stores to memory that are subsequently overwritten by another store, without any intervening loads. The pass is located in ‘tree-ssa-dse.cc’ and is described by ‘pass_dse’. • Tail recursion elimination This pass transforms tail recursion into a loop. It is located in ‘tree-tailcall.cc’ and is described by ‘pass_tail_recursion’. • Forward store motion This pass sinks stores and assignments down the flowgraph closer to their use point. The pass is located in ‘tree-ssa-sink.cc’ and is described by ‘pass_sink_code’. • Partial redundancy elimination This pass eliminates partially redundant computations, as well as performing load motion. The pass is located in ‘tree-ssa-pre.cc’ and is described by ‘pass_pre’. Just before partial redundancy elimination, if ‘-funsafe-math-optimizations’ is on, GCC tries to convert divisions to multiplications by the reciprocal. The pass is located in ‘tree-ssa-math-opts.cc’ and is described by ‘pass_cse_reciprocal’. • Full redundancy elimination This is a simpler form of PRE that only eliminates redundancies that occur on all paths. It is located in ‘tree-ssa-pre.cc’ and described by ‘pass_fre’. • Loop optimization The main driver of the pass is placed in ‘tree-ssa-loop.cc’ and described by ‘pass_loop’. The optimizations performed by this pass are: Loop invariant motion. This pass moves only invariants that would be hard to handle on RTL level (function calls, operations that expand to nontrivial sequences of insns). With ‘-funswitch-loops’ it also moves operands of conditions that are invariant out of the loop, so that we can use just trivial invariantness analysis in loop unswitching. The pass also includes store motion. The pass is implemented in ‘tree-ssa-loop-im.cc’. Canonical induction variable creation. This pass creates a simple counter for number of iterations of the loop and replaces the exit condition of the loop using it, in case when a complicated analysis is necessary to determine the number of iterations. Later optimizations then may determine the number easily. The pass is implemented in ‘tree-ssa-loop-ivcanon.cc’. Induction variable optimizations. This pass performs standard induction variable optimizations, including strength reduction, induction variable merging and induction variable elimination. The pass is implemented in ‘tree-ssa-loop-ivopts.cc’. Loop unswitching. This pass moves the conditional jumps that are invariant out of the loops. To achieve this, a duplicate of the loop is created for each possible outcome of conditional jump(s). The pass is implemented in ‘tree-ssa-loop-unswitch.cc’. Loop splitting. If a loop contains a conditional statement that is always true for one part of the iteration space and false for the other this pass splits the loop into two, one dealing with one side the other only with the other, thereby removing one inner-loop conditional. The pass is implemented in ‘tree-ssa-loop-split.cc’. The optimizations also use various utility functions contained in ‘tree-ssa-loop-manip.cc’, ‘cfgloop.cc’, ‘cfgloopanal.cc’ and ‘cfgloopmanip.cc’. Vectorization. This pass transforms loops to operate on vector types instead of scalar types. Data parallelism across loop iterations is exploited to group data elements from consecutive iterations into a vector and operate on them in parallel. Depending on available target support the loop is conceptually unrolled by a factor ‘VF’ (vectorization factor), which is the number of elements operated upon in parallel in each iteration, and the ‘VF’ copies of each scalar operation are fused to form a vector operation. Additional loop transformations such as peeling and versioning may take place to align the number of iterations, and to align the memory accesses in the loop. The pass is implemented in ‘tree-vectorizer.cc’ (the main driver), ‘tree-vect-loop.cc’ and ‘tree-vect-loop-manip.cc’ (loop specific parts and general loop utilities), ‘tree-vect-slp’ (loop-aware SLP functionality), ‘tree-vect-stmts.cc’, ‘tree-vect-data-refs.cc’ and ‘tree-vect-slp-patterns.cc’ containing the SLP pattern matcher. Analysis of data references is in ‘tree-data-ref.cc’. SLP Vectorization. This pass performs vectorization of straight-line code. The pass is implemented in ‘tree-vectorizer.cc’ (the main driver), ‘tree-vect-slp.cc’, ‘tree-vect-stmts.cc’ and ‘tree-vect-data-refs.cc’. Autoparallelization. This pass splits the loop iteration space to run into several threads. The pass is implemented in ‘tree-parloops.cc’. Graphite is a loop transformation framework based on the polyhedral model. Graphite stands for Gimple Represented as Polyhedra. The internals of this infrastructure are documented in . The passes working on this representation are implemented in the various ‘graphite-*’ files. • Tree level if-conversion for vectorizer This pass applies if-conversion to simple loops to help vectorizer. We identify if convertible loops, if-convert statements and merge basic blocks in one big block. The idea is to present loop in such form so that vectorizer can have one to one mapping between statements and available vector operations. This pass is located in ‘tree-if-conv.cc’ and is described by ‘pass_if_conversion’. • Conditional constant propagation This pass relaxes a lattice of values in order to identify those that must be constant even in the presence of conditional branches. The pass is located in ‘tree-ssa-ccp.cc’ and is described by ‘pass_ccp’. A related pass that works on memory loads and stores, and not just register values, is located in ‘tree-ssa-ccp.cc’ and described by ‘pass_store_ccp’. • Conditional copy propagation This is similar to constant propagation but the lattice of values is the "copy-of" relation. It eliminates redundant copies from the code. The pass is located in ‘tree-ssa-copy.cc’ and described by ‘pass_copy_prop’. A related pass that works on memory copies, and not just register copies, is located in ‘tree-ssa-copy.cc’ and described by ‘pass_store_copy_prop’. • Value range propagation This transformation is similar to constant propagation but instead of propagating single constant values, it propagates known value ranges. The implementation is based on Patterson's range propagation algorithm (Accurate Static Branch Prediction by Value Range Propagation, J. R. C. Patterson, PLDI '95). In contrast to Patterson's algorithm, this implementation does not propagate branch probabilities nor it uses more than a single range per SSA name. This means that the current implementation cannot be used for branch prediction (though adapting it would not be difficult). The pass is located in ‘tree-vrp.cc’ and is described by ‘pass_vrp’. • Folding built-in functions This pass simplifies built-in functions, as applicable, with constant arguments or with inferable string lengths. It is located in ‘tree-ssa-ccp.cc’ and is described by ‘pass_fold_builtins’. • Split critical edges This pass identifies critical edges and inserts empty basic blocks such that the edge is no longer critical. The pass is located in ‘tree-cfg.cc’ and is described by ‘pass_split_crit_edges’. • Control dependence dead code elimination This pass is a stronger form of dead code elimination that can eliminate unnecessary control flow statements. It is located in ‘tree-ssa-dce.cc’ and is described by ‘pass_cd_dce’. • Tail call elimination This pass identifies function calls that may be rewritten into jumps. No code transformation is actually applied here, but the data and control flow problem is solved. The code transformation requires target support, and so is delayed until RTL. In the meantime ‘CALL_EXPR_TAILCALL’ is set indicating the possibility. The pass is located in ‘tree-tailcall.cc’ and is described by ‘pass_tail_calls’. The RTL transformation is handled by ‘fixup_tail_calls’ in ‘calls.cc’. • Warn for function return without value For non-void functions, this pass locates return statements that do not specify a value and issues a warning. Such a statement may have been injected by falling off the end of the function. This pass is run last so that we have as much time as possible to prove that the statement is not reachable. It is located in ‘tree-cfg.cc’ and is described by ‘pass_warn_function_return’. • Leave static single assignment form This pass rewrites the function such that it is in normal form. At the same time, we eliminate as many single-use temporaries as possible, so the intermediate language is no longer GIMPLE, but GENERIC. The pass is located in ‘tree-outof-ssa.cc’ and is described by ‘pass_del_ssa’. • Merge PHI nodes that feed into one another This is part of the CFG cleanup passes. It attempts to join PHI nodes from a forwarder CFG block into another block with PHI nodes. The pass is located in ‘tree-cfgcleanup.cc’ and is described by ‘pass_merge_phi’. • Return value optimization If a function always returns the same local variable, and that local variable is an aggregate type, then the variable is replaced with the return value for the function (i.e., the function's DECL_RESULT). This is equivalent to the C++ named return value optimization applied to GIMPLE. The pass is located in ‘tree-nrv.cc’ and is described by ‘pass_nrv’. • Return slot optimization If a function returns a memory object and is called as ‘var = foo()’, this pass tries to change the call so that the address of ‘var’ is sent to the caller to avoid an extra memory copy. This pass is located in ‘tree-nrv.cc’ and is described by ‘pass_return_slot’. • Optimize calls to ‘__builtin_object_size’ or ‘__builtin_dynamic_object_size’ This is a propagation pass similar to CCP that tries to remove calls to ‘__builtin_object_size’ when the upper or lower bound for the size of the object can be computed at compile-time. It also tries to replace calls to ‘__builtin_dynamic_object_size’ with an expression that evaluates the upper or lower bound for the size of the object. This pass is located in ‘tree-object-size.cc’ and is described by ‘pass_object_sizes’. • Loop invariant motion This pass removes expensive loop-invariant computations out of loops. The pass is located in ‘tree-ssa-loop.cc’ and described by ‘pass_lim’. • Loop nest optimizations This is a family of loop transformations that works on loop nests. It includes loop interchange, scaling, skewing and reversal and they are all geared to the optimization of data locality in array traversals and the removal of dependencies that hamper optimizations such as loop parallelization and vectorization. The pass is located in ‘tree-loop-linear.c’ and described by ‘pass_linear_transform’. • Removal of empty loops This pass removes loops with no code in them. The pass is located in ‘tree-ssa-loop-ivcanon.cc’ and described by ‘pass_empty_loop’. • Unrolling of small loops This pass completely unrolls loops with few iterations. The pass is located in ‘tree-ssa-loop-ivcanon.cc’ and described by ‘pass_complete_unroll’. • Predictive commoning This pass makes the code reuse the computations from the previous iterations of the loops, especially loads and stores to memory. It does so by storing the values of these computations to a bank of temporary variables that are rotated at the end of loop. To avoid the need for this rotation, the loop is then unrolled and the copies of the loop body are rewritten to use the appropriate version of the temporary variable. This pass is located in ‘tree-predcom.cc’ and described by ‘pass_predcom’. • Array prefetching This pass issues prefetch instructions for array references inside loops. The pass is located in ‘tree-ssa-loop-prefetch.cc’ and described by ‘pass_loop_prefetch’. • Reassociation This pass rewrites arithmetic expressions to enable optimizations that operate on them, like redundancy elimination and vectorization. The pass is located in ‘tree-ssa-reassoc.cc’ and described by ‘pass_reassoc’. • Optimization of ‘stdarg’ functions This pass tries to avoid the saving of register arguments into the stack on entry to ‘stdarg’ functions. If the function doesn't use any ‘va_start’ macros, no registers need to be saved. If ‘va_start’ macros are used, the ‘va_list’ variables don't escape the function, it is only necessary to save registers that will be used in ‘va_arg’ macros. For instance, if ‘va_arg’ is only used with integral types in the function, floating point registers don't need to be saved. This pass is located in ‘tree-stdarg.cc’ and described by ‘pass_stdarg’.  File: gccint.info, Node: RTL passes, Next: Optimization info, Prev: Tree SSA passes, Up: Passes 9.6 RTL passes ============== The following briefly describes the RTL generation and optimization passes that are run after the Tree optimization passes. • RTL generation The source files for RTL generation include ‘stmt.cc’, ‘calls.cc’, ‘expr.cc’, ‘explow.cc’, ‘expmed.cc’, ‘function.cc’, ‘optabs.cc’ and ‘emit-rtl.cc’. Also, the file ‘insn-emit.cc’, generated from the machine description by the program ‘genemit’, is used in this pass. The header file ‘expr.h’ is used for communication within this pass. The header files ‘insn-flags.h’ and ‘insn-codes.h’, generated from the machine description by the programs ‘genflags’ and ‘gencodes’, tell this pass which standard names are available for use and which patterns correspond to them. • Generation of exception landing pads This pass generates the glue that handles communication between the exception handling library routines and the exception handlers within the function. Entry points in the function that are invoked by the exception handling library are called “landing pads”. The code for this pass is located in ‘except.cc’. • Control flow graph cleanup This pass removes unreachable code, simplifies jumps to next, jumps to jump, jumps across jumps, etc. The pass is run multiple times. For historical reasons, it is occasionally referred to as the "jump optimization pass". The bulk of the code for this pass is in ‘cfgcleanup.cc’, and there are support routines in ‘cfgrtl.cc’ and ‘jump.cc’. • Forward propagation of single-def values This pass attempts to remove redundant computation by substituting variables that come from a single definition, and seeing if the result can be simplified. It performs copy propagation and addressing mode selection. The pass is run twice, with values being propagated into loops only on the second run. The code is located in ‘fwprop.cc’. • Common subexpression elimination This pass removes redundant computation within basic blocks, and optimizes addressing modes based on cost. The pass is run twice. The code for this pass is located in ‘cse.cc’. • Global common subexpression elimination This pass performs two different types of GCSE depending on whether you are optimizing for size or not (LCM based GCSE tends to increase code size for a gain in speed, while Morel-Renvoise based GCSE does not). When optimizing for size, GCSE is done using Morel-Renvoise Partial Redundancy Elimination, with the exception that it does not try to move invariants out of loops--that is left to the loop optimization pass. If MR PRE GCSE is done, code hoisting (aka unification) is also done, as well as load motion. If you are optimizing for speed, LCM (lazy code motion) based GCSE is done. LCM is based on the work of Knoop, Ruthing, and Steffen. LCM based GCSE also does loop invariant code motion. We also perform load and store motion when optimizing for speed. Regardless of which type of GCSE is used, the GCSE pass also performs global constant and copy propagation. The source file for this pass is ‘gcse.cc’, and the LCM routines are in ‘lcm.cc’. • Loop optimization This pass performs several loop related optimizations. The source files ‘cfgloopanal.cc’ and ‘cfgloopmanip.cc’ contain generic loop analysis and manipulation code. Initialization and finalization of loop structures is handled by ‘loop-init.cc’. A loop invariant motion pass is implemented in ‘loop-invariant.cc’. Basic block level optimizations--unrolling, and peeling loops-- are implemented in ‘loop-unroll.cc’. Replacing of the exit condition of loops by special machine-dependent instructions is handled by ‘loop-doloop.cc’. • Jump bypassing This pass is an aggressive form of GCSE that transforms the control flow graph of a function by propagating constants into conditional branch instructions. The source file for this pass is ‘gcse.cc’. • If conversion This pass attempts to replace conditional branches and surrounding assignments with arithmetic, boolean value producing comparison instructions, and conditional move instructions. In the very last invocation after reload/LRA, it will generate predicated instructions when supported by the target. The code is located in ‘ifcvt.cc’. • Web construction This pass splits independent uses of each pseudo-register. This can improve effect of the other transformation, such as CSE or register allocation. The code for this pass is located in ‘web.cc’. • Instruction combination This pass attempts to combine groups of two or three instructions that are related by data flow into single instructions. It combines the RTL expressions for the instructions by substitution, simplifies the result using algebra, and then attempts to match the result against the machine description. The code is located in ‘combine.cc’. • Mode switching optimization This pass looks for instructions that require the processor to be in a specific "mode" and minimizes the number of mode changes required to satisfy all users. What these modes are, and what they apply to are completely target-specific. The code for this pass is located in ‘mode-switching.cc’. • Modulo scheduling This pass looks at innermost loops and reorders their instructions by overlapping different iterations. Modulo scheduling is performed immediately before instruction scheduling. The code for this pass is located in ‘modulo-sched.cc’. • Instruction scheduling This pass looks for instructions whose output will not be available by the time that it is used in subsequent instructions. Memory loads and floating point instructions often have this behavior on RISC machines. It re-orders instructions within a basic block to try to separate the definition and use of items that otherwise would cause pipeline stalls. This pass is performed twice, before and after register allocation. The code for this pass is located in ‘haifa-sched.cc’, ‘sched-deps.cc’, ‘sched-ebb.cc’, ‘sched-rgn.cc’ and ‘sched-vis.c’. • Register allocation These passes make sure that all occurrences of pseudo registers are eliminated, either by allocating them to a hard register, replacing them by an equivalent expression (e.g. a constant) or by placing them on the stack. This is done in several subpasses: • The integrated register allocator (IRA). It is called integrated because coalescing, register live range splitting, and hard register preferencing are done on-the-fly during coloring. It also has better integration with the reload/LRA pass. Pseudo-registers spilled by the allocator or the reload/LRA have still a chance to get hard-registers if the reload/LRA evicts some pseudo-registers from hard-registers. The allocator helps to choose better pseudos for spilling based on their live ranges and to coalesce stack slots allocated for the spilled pseudo-registers. IRA is a regional register allocator which is transformed into Chaitin-Briggs allocator if there is one region. By default, IRA chooses regions using register pressure but the user can force it to use one region or regions corresponding to all loops. Source files of the allocator are ‘ira.cc’, ‘ira-build.cc’, ‘ira-costs.cc’, ‘ira-conflicts.cc’, ‘ira-color.cc’, ‘ira-emit.cc’, ‘ira-lives’, plus header files ‘ira.h’ and ‘ira-int.h’ used for the communication between the allocator and the rest of the compiler and between the IRA files. • Reloading. This pass renumbers pseudo registers with the hardware registers numbers they were allocated. Pseudo registers that did not get hard registers are replaced with stack slots. Then it finds instructions that are invalid because a value has failed to end up in a register, or has ended up in a register of the wrong kind. It fixes up these instructions by reloading the problematical values temporarily into registers. Additional instructions are generated to do the copying. The reload pass also optionally eliminates the frame pointer and inserts instructions to save and restore call-clobbered registers around calls. Source files are ‘reload.cc’ and ‘reload1.cc’, plus the header ‘reload.h’ used for communication between them. • This pass is a modern replacement of the reload pass. Source files are ‘lra.cc’, ‘lra-assign.c’, ‘lra-coalesce.cc’, ‘lra-constraints.cc’, ‘lra-eliminations.cc’, ‘lra-lives.cc’, ‘lra-remat.cc’, ‘lra-spills.cc’, the header ‘lra-int.h’ used for communication between them, and the header ‘lra.h’ used for communication between LRA and the rest of compiler. Unlike the reload pass, intermediate LRA decisions are reflected in RTL as much as possible. This reduces the number of target-dependent macros and hooks, leaving instruction constraints as the primary source of control. LRA is run on targets for which TARGET_LRA_P returns true. • Basic block reordering This pass implements profile guided code positioning. If profile information is not available, various types of static analysis are performed to make the predictions normally coming from the profile feedback (IE execution frequency, branch probability, etc). It is implemented in the file ‘bb-reorder.cc’, and the various prediction routines are in ‘predict.cc’. • Variable tracking This pass computes where the variables are stored at each position in code and generates notes describing the variable locations to RTL code. The location lists are then generated according to these notes to debug information if the debugging information format supports location lists. The code is located in ‘var-tracking.cc’. • Delayed branch scheduling This optional pass attempts to find instructions that can go into the delay slots of other instructions, usually jumps and calls. The code for this pass is located in ‘reorg.cc’. • Branch shortening On many RISC machines, branch instructions have a limited range. Thus, longer sequences of instructions must be used for long branches. In this pass, the compiler figures out what how far each instruction will be from each other instruction, and therefore whether the usual instructions, or the longer sequences, must be used for each branch. The code for this pass is located in ‘final.cc’. • Register-to-stack conversion Conversion from usage of some hard registers to usage of a register stack may be done at this point. Currently, this is supported only for the floating-point registers of the Intel 80387 coprocessor. The code for this pass is located in ‘reg-stack.cc’. • Final This pass outputs the assembler code for the function. The source files are ‘final.cc’ plus ‘insn-output.cc’; the latter is generated automatically from the machine description by the tool ‘genoutput’. The header file ‘conditions.h’ is used for communication between these files. • Debugging information output This is run after final because it must output the stack slot offsets for pseudo registers that did not get hard registers. Source files are ‘dwarfout.c’ for DWARF symbol table format, files ‘dwarf2out.cc’ and ‘dwarf2asm.cc’ for DWARF2 symbol table format, and ‘vmsdbgout.cc’ for VMS debug symbol table format.  File: gccint.info, Node: Optimization info, Prev: RTL passes, Up: Passes 9.7 Optimization info ===================== This section is describes dump infrastructure which is common to both pass dumps as well as optimization dumps. The goal for this infrastructure is to provide both gcc developers and users detailed information about various compiler transformations and optimizations. * Menu: * Dump setup:: Setup of optimization dumps. * Optimization groups:: Groups made up of optimization passes. * Dump files and streams:: Dump output file names and streams. * Dump output verbosity:: How much information to dump. * Dump types:: Various types of dump functions. * Dump examples:: Sample usage.  File: gccint.info, Node: Dump setup, Next: Optimization groups, Up: Optimization info 9.7.1 Dump setup ---------------- A dump_manager class is defined in ‘dumpfile.h’. Various passes register dumping pass-specific information via ‘dump_register’ in ‘passes.cc’. During the registration, an optimization pass can select its optimization group (*note Optimization groups::). After that optimization information corresponding to the entire group (presumably from multiple passes) can be output via command-line switches. Note that if a pass does not fit into any of the pre-defined groups, it can select ‘OPTGROUP_NONE’. Note that in general, a pass need not know its dump output file name, whether certain flags are enabled, etc. However, for legacy reasons, passes could also call ‘dump_begin’ which returns a stream in case the particular pass has optimization dumps enabled. A pass could call ‘dump_end’ when the dump has ended. These methods should go away once all the passes are converted to use the new dump infrastructure. The recommended way to setup the dump output is via ‘dump_start’ and ‘dump_end’.  File: gccint.info, Node: Optimization groups, Next: Dump files and streams, Prev: Dump setup, Up: Optimization info 9.7.2 Optimization groups ------------------------- The optimization passes are grouped into several categories. Currently defined categories in ‘dumpfile.h’ are ‘OPTGROUP_IPA’ IPA optimization passes. Enabled by ‘-ipa’ ‘OPTGROUP_LOOP’ Loop optimization passes. Enabled by ‘-loop’. ‘OPTGROUP_INLINE’ Inlining passes. Enabled by ‘-inline’. ‘OPTGROUP_OMP’ OMP (Offloading and Multi Processing) passes. Enabled by ‘-omp’. ‘OPTGROUP_VEC’ Vectorization passes. Enabled by ‘-vec’. ‘OPTGROUP_OTHER’ All other optimization passes which do not fall into one of the above. ‘OPTGROUP_ALL’ All optimization passes. Enabled by ‘-optall’. By using groups a user could selectively enable optimization information only for a group of passes. By default, the optimization information for all the passes is dumped.  File: gccint.info, Node: Dump files and streams, Next: Dump output verbosity, Prev: Optimization groups, Up: Optimization info 9.7.3 Dump files and streams ---------------------------- There are two separate output streams available for outputting optimization information from passes. Note that both these streams accept ‘stderr’ and ‘stdout’ as valid streams and thus it is possible to dump output to standard output or error. This is specially handy for outputting all available information in a single file by redirecting ‘stderr’. ‘pstream’ This stream is for pass-specific dump output. For example, ‘-fdump-tree-vect=foo.v’ dumps tree vectorization pass output into the given file name ‘foo.v’. If the file name is not provided, the default file name is based on the source file and pass number. Note that one could also use special file names ‘stdout’ and ‘stderr’ for dumping to standard output and standard error respectively. ‘alt_stream’ This stream is used for printing optimization specific output in response to the ‘-fopt-info’. Again a file name can be given. If the file name is not given, it defaults to ‘stderr’.  File: gccint.info, Node: Dump output verbosity, Next: Dump types, Prev: Dump files and streams, Up: Optimization info 9.7.4 Dump output verbosity --------------------------- The dump verbosity has the following options ‘optimized’ Print information when an optimization is successfully applied. It is up to a pass to decide which information is relevant. For example, the vectorizer passes print the source location of loops which got successfully vectorized. ‘missed’ Print information about missed optimizations. Individual passes control which information to include in the output. For example, gcc -O2 -ftree-vectorize -fopt-info-vec-missed will print information about missed optimization opportunities from vectorization passes on stderr. ‘note’ Print verbose information about optimizations, such as certain transformations, more detailed messages about decisions etc. ‘all’ Print detailed optimization information. This includes OPTIMIZED, MISSED, and NOTE.  File: gccint.info, Node: Dump types, Next: Dump examples, Prev: Dump output verbosity, Up: Optimization info 9.7.5 Dump types ---------------- ‘dump_printf’ This is a generic method for doing formatted output. It takes an additional argument ‘dump_kind’ which signifies the type of dump. This method outputs information only when the dumps are enabled for this particular ‘dump_kind’. Note that the caller doesn't need to know if the particular dump is enabled or not, or even the file name. The caller only needs to decide which dump output information is relevant, and under what conditions. This determines the associated flags. Consider the following example from ‘loop-unroll.cc’ where an informative message about a loop (along with its location) is printed when any of the following flags is enabled − optimization messages − RTL dumps − detailed dumps int report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_RTL | TDF_DETAILS; dump_printf_loc (report_flags, insn, "loop turned into non-loop; it never loops.\n"); ‘dump_basic_block’ Output basic block. ‘dump_generic_expr’ Output generic expression. ‘dump_gimple_stmt’ Output gimple statement. Note that the above methods also have variants prefixed with ‘_loc’, such as ‘dump_printf_loc’, which are similar except they also output the source location information. The ‘_loc’ variants take a ‘const dump_location_t &’. This class can be constructed from a ‘gimple *’ or from a ‘rtx_insn *’, and so callers can pass a ‘gimple *’ or a ‘rtx_insn *’ as the ‘_loc’ argument. The ‘dump_location_t’ constructor will extract the source location from the statement or instruction, along with the profile count, and the location in GCC's own source code (or the plugin) from which the dump call was emitted. Only the source location is currently used. There is also a ‘dump_user_location_t’ class, capturing the source location and profile count, but not the dump emission location, so that locations in the user's code can be passed around. This can also be constructed from a ‘gimple *’ and from a ‘rtx_insn *’, and it too can be passed as the ‘_loc’ argument.  File: gccint.info, Node: Dump examples, Prev: Dump types, Up: Optimization info 9.7.6 Dump examples ------------------- gcc -O3 -fopt-info-missed=missed.all outputs missed optimization report from all the passes into ‘missed.all’. As another example, gcc -O3 -fopt-info-inline-optimized-missed=inline.txt will output information about missed optimizations as well as optimized locations from all the inlining passes into ‘inline.txt’. If the FILENAME is provided, then the dumps from all the applicable optimizations are concatenated into the ‘filename’. Otherwise the dump is output onto ‘stderr’. If OPTIONS is omitted, it defaults to ‘optimized-optall’, which means dump all information about successful optimizations from all the passes. In the following example, the optimization information is output on to ‘stderr’. gcc -O3 -fopt-info Note that ‘-fopt-info-vec-missed’ behaves the same as ‘-fopt-info-missed-vec’. The order of the optimization group names and message types listed after ‘-fopt-info’ does not matter. As another example, consider gcc -fopt-info-vec-missed=vec.miss -fopt-info-loop-optimized=loop.opt Here the two output file names ‘vec.miss’ and ‘loop.opt’ are in conflict since only one output file is allowed. In this case, only the first option takes effect and the subsequent options are ignored. Thus only the ‘vec.miss’ is produced which containts dumps from the vectorizer about missed opportunities.  File: gccint.info, Node: poly_int, Next: GENERIC, Prev: Passes, Up: Top 10 Sizes and offsets as runtime invariants ****************************************** GCC allows the size of a hardware register to be a runtime invariant rather than a compile-time constant. This in turn means that various sizes and offsets must also be runtime invariants rather than compile-time constants, such as: • the size of a general ‘machine_mode’ (*note Machine Modes::); • the size of a spill slot; • the offset of something within a stack frame; • the number of elements in a vector; • the size and offset of a ‘mem’ rtx (*note Regs and Memory::); and • the byte offset in a ‘subreg’ rtx (*note Regs and Memory::). The motivating example is the Arm SVE ISA, whose vector registers can be any multiple of 128 bits between 128 and 2048 inclusive. The compiler normally produces code that works for all SVE register sizes, with the actual size only being known at runtime. GCC's main representation of such runtime invariants is the ‘poly_int’ class. This chapter describes what ‘poly_int’ does, lists the available operations, and gives some general usage guidelines. * Menu: * Overview of poly_int:: * Consequences of using poly_int:: * Comparisons involving poly_int:: * Arithmetic on poly_ints:: * Alignment of poly_ints:: * Computing bounds on poly_ints:: * Converting poly_ints:: * Miscellaneous poly_int routines:: * Guidelines for using poly_int::  File: gccint.info, Node: Overview of poly_int, Next: Consequences of using poly_int, Up: poly_int 10.1 Overview of ‘poly_int’ =========================== We define indeterminates X1, ..., XN whose values are only known at runtime and use polynomials of the form: C0 + C1 * X1 + ... + CN * XN to represent a size or offset whose value might depend on some of these indeterminates. The coefficients C0, ..., CN are always known at compile time, with the C0 term being the "constant" part that does not depend on any runtime value. GCC uses the ‘poly_int’ class to represent these coefficients. The class has two template parameters: the first specifies the number of coefficients (N + 1) and the second specifies the type of the coefficients. For example, ‘poly_int<2, unsigned short>’ represents a polynomial with two coefficients (and thus one indeterminate), with each coefficient having type ‘unsigned short’. When N is 0, the class degenerates to a single compile-time constant C0. The number of coefficients needed for compilation is a fixed property of each target and is specified by the configuration macro ‘NUM_POLY_INT_COEFFS’. The default value is 1, since most targets do not have such runtime invariants. Targets that need a different value should ‘#define’ the macro in their ‘CPU-modes.def’ file. *Note Back End::. ‘poly_int’ makes the simplifying requirement that each indeterminate must be a nonnegative integer. An indeterminate value of 0 should usually represent the minimum possible runtime value, with C0 specifying the value in that case. For example, when targetting the Arm SVE ISA, the single indeterminate represents the number of 128-bit blocks in a vector _beyond the minimum length of 128 bits_. Thus the number of 64-bit doublewords in a vector is 2 + 2 * X1. If an aggregate has a single SVE vector and 16 additional bytes, its total size is 32 + 16 * X1 bytes. The header file ‘poly-int-types.h’ provides typedefs for the most common forms of ‘poly_int’, all having ‘NUM_POLY_INT_COEFFS’ coefficients: ‘poly_uint16’ a ‘poly_int’ with ‘unsigned short’ coefficients. ‘poly_int64’ a ‘poly_int’ with ‘HOST_WIDE_INT’ coefficients. ‘poly_uint64’ a ‘poly_int’ with ‘unsigned HOST_WIDE_INT’ coefficients. ‘poly_offset_int’ a ‘poly_int’ with ‘offset_int’ coefficients. ‘poly_wide_int’ a ‘poly_int’ with ‘wide_int’ coefficients. ‘poly_widest_int’ a ‘poly_int’ with ‘widest_int’ coefficients. Since the main purpose of ‘poly_int’ is to represent sizes and offsets, the last two typedefs are only rarely used.  File: gccint.info, Node: Consequences of using poly_int, Next: Comparisons involving poly_int, Prev: Overview of poly_int, Up: poly_int 10.2 Consequences of using ‘poly_int’ ===================================== The two main consequences of using polynomial sizes and offsets are that: • there is no total ordering between the values at compile time, and • some operations might yield results that cannot be expressed as a ‘poly_int’. For example, if X is a runtime invariant, we cannot tell at compile time whether: 3 + 4X <= 1 + 5X since the condition is false when X <= 1 and true when X >= 2. Similarly, ‘poly_int’ cannot represent the result of: (3 + 4X) * (1 + 5X) since it cannot (and in practice does not need to) store powers greater than one. It also cannot represent the result of: (3 + 4X) / (1 + 5X) The following sections describe how we deal with these restrictions. As described earlier, a ‘poly_int<1, T>’ has no indeterminates and so degenerates to a compile-time constant of type T. It would be possible in that case to do all normal arithmetic on the T, and to compare the T using the normal C++ operators. We deliberately prevent target-independent code from doing this, since the compiler needs to support other ‘poly_int’ as well, regardless of the current target's ‘NUM_POLY_INT_COEFFS’. However, it would be very artificial to force target-specific code to follow these restrictions if the target has no runtime indeterminates. There is therefore an implicit conversion from ‘poly_int<1, T>’ to T when compiling target-specific translation units.  File: gccint.info, Node: Comparisons involving poly_int, Next: Arithmetic on poly_ints, Prev: Consequences of using poly_int, Up: poly_int 10.3 Comparisons involving ‘poly_int’ ===================================== In general we need to compare sizes and offsets in two situations: those in which the values need to be ordered, and those in which the values can be unordered. More loosely, the distinction is often between values that have a definite link (usually because they refer to the same underlying register or memory location) and values that have no definite link. An example of the former is the relationship between the inner and outer sizes of a subreg, where we must know at compile time whether the subreg is paradoxical, partial, or complete. An example of the latter is alias analysis: we might want to check whether two arbitrary memory references overlap. Referring back to the examples in the previous section, it makes sense to ask whether a memory reference of size ‘3 + 4X’ overlaps one of size ‘1 + 5X’, but it does not make sense to have a subreg in which the outer mode has ‘3 + 4X’ bytes and the inner mode has ‘1 + 5X’ bytes (or vice versa). Such subregs are always invalid and should trigger an internal compiler error if formed. The underlying operators are the same in both cases, but the distinction affects how they are used. * Menu: * Comparison functions for poly_int:: * Properties of the poly_int comparisons:: * Comparing potentially-unordered poly_ints:: * Comparing ordered poly_ints:: * Checking for a poly_int marker value:: * Range checks on poly_ints:: * Sorting poly_ints::  File: gccint.info, Node: Comparison functions for poly_int, Next: Properties of the poly_int comparisons, Up: Comparisons involving poly_int 10.3.1 Comparison functions for ‘poly_int’ ------------------------------------------ ‘poly_int’ provides the following routines for checking whether a particular condition "may be" (might be) true: maybe_lt maybe_le maybe_eq maybe_ge maybe_gt maybe_ne The functions have their natural meaning: ‘maybe_lt(A, B)’ Return true if A might be less than B. ‘maybe_le(A, B)’ Return true if A might be less than or equal to B. ‘maybe_eq(A, B)’ Return true if A might be equal to B. ‘maybe_ne(A, B)’ Return true if A might not be equal to B. ‘maybe_ge(A, B)’ Return true if A might be greater than or equal to B. ‘maybe_gt(A, B)’ Return true if A might be greater than B. For readability, ‘poly_int’ also provides "known" inverses of these functions: known_lt (A, B) == !maybe_ge (A, B) known_le (A, B) == !maybe_gt (A, B) known_eq (A, B) == !maybe_ne (A, B) known_ge (A, B) == !maybe_lt (A, B) known_gt (A, B) == !maybe_le (A, B) known_ne (A, B) == !maybe_eq (A, B)  File: gccint.info, Node: Properties of the poly_int comparisons, Next: Comparing potentially-unordered poly_ints, Prev: Comparison functions for poly_int, Up: Comparisons involving poly_int 10.3.2 Properties of the ‘poly_int’ comparisons ----------------------------------------------- All "maybe" relations except ‘maybe_ne’ are transitive, so for example: maybe_lt (A, B) && maybe_lt (B, C) implies maybe_lt (A, C) for all A, B and C. ‘maybe_lt’, ‘maybe_gt’ and ‘maybe_ne’ are irreflexive, so for example: !maybe_lt (A, A) is true for all A. ‘maybe_le’, ‘maybe_eq’ and ‘maybe_ge’ are reflexive, so for example: maybe_le (A, A) is true for all A. ‘maybe_eq’ and ‘maybe_ne’ are symmetric, so: maybe_eq (A, B) == maybe_eq (B, A) maybe_ne (A, B) == maybe_ne (B, A) for all A and B. In addition: maybe_le (A, B) == maybe_lt (A, B) || maybe_eq (A, B) maybe_ge (A, B) == maybe_gt (A, B) || maybe_eq (A, B) maybe_lt (A, B) == maybe_gt (B, A) maybe_le (A, B) == maybe_ge (B, A) However: maybe_le (A, B) && maybe_le (B, A) does not imply !maybe_ne (A, B) [== known_eq (A, B)] maybe_ge (A, B) && maybe_ge (B, A) does not imply !maybe_ne (A, B) [== known_eq (A, B)] One example is again ‘A == 3 + 4X’ and ‘B == 1 + 5X’, where ‘maybe_le (A, B)’, ‘maybe_ge (A, B)’ and ‘maybe_ne (A, B)’ all hold. ‘maybe_le’ and ‘maybe_ge’ are therefore not antisymetric and do not form a partial order. From the above, it follows that: • All "known" relations except ‘known_ne’ are transitive. • ‘known_lt’, ‘known_ne’ and ‘known_gt’ are irreflexive. • ‘known_le’, ‘known_eq’ and ‘known_ge’ are reflexive. Also: known_lt (A, B) == known_gt (B, A) known_le (A, B) == known_ge (B, A) known_lt (A, B) implies !known_lt (B, A) [asymmetry] known_gt (A, B) implies !known_gt (B, A) known_le (A, B) && known_le (B, A) == known_eq (A, B) [== !maybe_ne (A, B)] known_ge (A, B) && known_ge (B, A) == known_eq (A, B) [== !maybe_ne (A, B)] ‘known_le’ and ‘known_ge’ are therefore antisymmetric and are partial orders. However: known_le (A, B) does not imply known_lt (A, B) || known_eq (A, B) known_ge (A, B) does not imply known_gt (A, B) || known_eq (A, B) For example, ‘known_le (4, 4 + 4X)’ holds because the runtime indeterminate X is a nonnegative integer, but neither ‘known_lt (4, 4 + 4X)’ nor ‘known_eq (4, 4 + 4X)’ hold.  File: gccint.info, Node: Comparing potentially-unordered poly_ints, Next: Comparing ordered poly_ints, Prev: Properties of the poly_int comparisons, Up: Comparisons involving poly_int 10.3.3 Comparing potentially-unordered ‘poly_int’s -------------------------------------------------- In cases where there is no definite link between two ‘poly_int’s, we can usually make a conservatively-correct assumption. For example, the conservative assumption for alias analysis is that two references _might_ alias. One way of checking whether [BEGIN1, END1) might overlap [BEGIN2, END2) using the ‘poly_int’ comparisons is: maybe_gt (END1, BEGIN2) && maybe_gt (END2, BEGIN1) and another (equivalent) way is: !(known_le (END1, BEGIN2) || known_le (END2, BEGIN1)) However, in this particular example, it is better to use the range helper functions instead. *Note Range checks on poly_ints::.  File: gccint.info, Node: Comparing ordered poly_ints, Next: Checking for a poly_int marker value, Prev: Comparing potentially-unordered poly_ints, Up: Comparisons involving poly_int 10.3.4 Comparing ordered ‘poly_int’s ------------------------------------ In cases where there is a definite link between two ‘poly_int’s, such as the outer and inner sizes of subregs, we usually require the sizes to be ordered by the ‘known_le’ partial order. ‘poly_int’ provides the following utility functions for ordered values: ‘ordered_p (A, B)’ Return true if A and B are ordered by the ‘known_le’ partial order. ‘ordered_min (A, B)’ Assert that A and B are ordered by ‘known_le’ and return the minimum of the two. When using this function, please add a comment explaining why the values are known to be ordered. ‘ordered_max (A, B)’ Assert that A and B are ordered by ‘known_le’ and return the maximum of the two. When using this function, please add a comment explaining why the values are known to be ordered. For example, if a subreg has an outer mode of size OUTER and an inner mode of size INNER: • the subreg is complete if known_eq (INNER, OUTER) • otherwise, the subreg is paradoxical if known_le (INNER, OUTER) • otherwise, the subreg is partial if known_le (OUTER, INNER) • otherwise, the subreg is ill-formed Thus the subreg is only valid if ‘ordered_p (OUTER, INNER)’ is true. If this condition is already known to be true then: • the subreg is complete if known_eq (INNER, OUTER) • the subreg is paradoxical if maybe_lt (INNER, OUTER) • the subreg is partial if maybe_lt (OUTER, INNER) with the three conditions being mutually exclusive. Code that checks whether a subreg is valid would therefore generally check whether ‘ordered_p’ holds (in addition to whatever other checks are required for subreg validity). Code that is dealing with existing subregs can assert that ‘ordered_p’ holds and use either of the classifications above.  File: gccint.info, Node: Checking for a poly_int marker value, Next: Range checks on poly_ints, Prev: Comparing ordered poly_ints, Up: Comparisons involving poly_int 10.3.5 Checking for a ‘poly_int’ marker value --------------------------------------------- It is sometimes useful to have a special "marker value" that is not meant to be taken literally. For example, some code uses a size of -1 to represent an unknown size, rather than having to carry around a separate boolean to say whether the size is known. The best way of checking whether something is a marker value is ‘known_eq’. Conversely the best way of checking whether something is _not_ a marker value is ‘maybe_ne’. Thus in the size example just mentioned, ‘known_eq (size, -1)’ would check for an unknown size and ‘maybe_ne (size, -1)’ would check for a known size.  File: gccint.info, Node: Range checks on poly_ints, Next: Sorting poly_ints, Prev: Checking for a poly_int marker value, Up: Comparisons involving poly_int 10.3.6 Range checks on ‘poly_int’s ---------------------------------- As well as the core comparisons (*note Comparison functions for poly_int::), ‘poly_int’ provides utilities for various kinds of range check. In each case the range is represented by a start position and a size rather than a start position and an end position; this is because the former is used much more often than the latter in GCC. Also, the sizes can be -1 (or all ones for unsigned sizes) to indicate a range with a known start position but an unknown size. All other sizes must be nonnegative. A range of size 0 does not contain anything or overlap anything. ‘known_size_p (SIZE)’ Return true if SIZE represents a known range size, false if it is -1 or all ones (for signed and unsigned types respectively). ‘ranges_maybe_overlap_p (POS1, SIZE1, POS2, SIZE2)’ Return true if the range described by POS1 and SIZE1 _might_ overlap the range described by POS2 and SIZE2 (in other words, return true if we cannot prove that the ranges are disjoint). ‘ranges_known_overlap_p (POS1, SIZE1, POS2, SIZE2)’ Return true if the range described by POS1 and SIZE1 is known to overlap the range described by POS2 and SIZE2. ‘known_subrange_p (POS1, SIZE1, POS2, SIZE2)’ Return true if the range described by POS1 and SIZE1 is known to be contained in the range described by POS2 and SIZE2. ‘maybe_in_range_p (VALUE, POS, SIZE)’ Return true if VALUE _might_ be in the range described by POS and SIZE (in other words, return true if we cannot prove that VALUE is outside that range). ‘known_in_range_p (VALUE, POS, SIZE)’ Return true if VALUE is known to be in the range described by POS and SIZE. ‘endpoint_representable_p (POS, SIZE)’ Return true if the range described by POS and SIZE is open-ended or if the endpoint (POS + SIZE) is representable in the same type as POS and SIZE. The function returns false if adding SIZE to POS makes conceptual sense but could overflow. There is also a ‘poly_int’ version of the ‘IN_RANGE_P’ macro: ‘coeffs_in_range_p (X, LOWER, UPPER)’ Return true if every coefficient of X is in the inclusive range [LOWER, UPPER]. This function can be useful when testing whether an operation would cause the values of coefficients to overflow. Note that the function does not indicate whether X itself is in the given range. X can be either a constant or a ‘poly_int’.  File: gccint.info, Node: Sorting poly_ints, Prev: Range checks on poly_ints, Up: Comparisons involving poly_int 10.3.7 Sorting ‘poly_int’s -------------------------- ‘poly_int’ provides the following routine for sorting: ‘compare_sizes_for_sort (A, B)’ Compare A and B in reverse lexicographical order (that is, compare the highest-indexed coefficients first). This can be useful when sorting data structures, since it has the effect of separating constant and non-constant values. If all values are nonnegative, the constant values come first. Note that the values do not necessarily end up in numerical order. For example, ‘1 + 1X’ would come after ‘100’ in the sort order, but may well be less than ‘100’ at run time.  File: gccint.info, Node: Arithmetic on poly_ints, Next: Alignment of poly_ints, Prev: Comparisons involving poly_int, Up: poly_int 10.4 Arithmetic on ‘poly_int’s ============================== Addition, subtraction, negation and bit inversion all work normally for ‘poly_int’s. Multiplication by a constant multiplier and left shifting by a constant shift amount also work normally. General multiplication of two ‘poly_int’s is not supported and is not useful in practice. Other operations are only conditionally supported: the operation might succeed or might fail, depending on the inputs. This section describes both types of operation. * Menu: * Using poly_int with C++ arithmetic operators:: * wi arithmetic on poly_ints:: * Division of poly_ints:: * Other poly_int arithmetic::  File: gccint.info, Node: Using poly_int with C++ arithmetic operators, Next: wi arithmetic on poly_ints, Up: Arithmetic on poly_ints 10.4.1 Using ‘poly_int’ with C++ arithmetic operators ----------------------------------------------------- The following C++ expressions are supported, where P1 and P2 are ‘poly_int’s and where C1 and C2 are scalars: -P1 ~P1 P1 + P2 P1 + C2 C1 + P2 P1 - P2 P1 - C2 C1 - P2 C1 * P2 P1 * C2 P1 << C2 P1 += P2 P1 += C2 P1 -= P2 P1 -= C2 P1 *= C2 P1 <<= C2 These arithmetic operations handle integer ranks in a similar way to C++. The main difference is that every coefficient narrower than ‘HOST_WIDE_INT’ promotes to ‘HOST_WIDE_INT’, whereas in C++ everything narrower than ‘int’ promotes to ‘int’. For example: poly_uint16 + int -> poly_int64 unsigned int + poly_uint16 -> poly_int64 poly_int64 + int -> poly_int64 poly_int32 + poly_uint64 -> poly_uint64 uint64 + poly_int64 -> poly_uint64 poly_offset_int + int32 -> poly_offset_int offset_int + poly_uint16 -> poly_offset_int In the first two examples, both coefficients are narrower than ‘HOST_WIDE_INT’, so the result has coefficients of type ‘HOST_WIDE_INT’. In the other examples, the coefficient with the highest rank "wins". If one of the operands is ‘wide_int’ or ‘poly_wide_int’, the rules are the same as for ‘wide_int’ arithmetic.  File: gccint.info, Node: wi arithmetic on poly_ints, Next: Division of poly_ints, Prev: Using poly_int with C++ arithmetic operators, Up: Arithmetic on poly_ints 10.4.2 ‘wi’ arithmetic on ‘poly_int’s ------------------------------------- As well as the C++ operators, ‘poly_int’ supports the following ‘wi’ routines: wi::neg (P1, &OVERFLOW) wi::add (P1, P2) wi::add (P1, C2) wi::add (C1, P1) wi::add (P1, P2, SIGN, &OVERFLOW) wi::sub (P1, P2) wi::sub (P1, C2) wi::sub (C1, P1) wi::sub (P1, P2, SIGN, &OVERFLOW) wi::mul (P1, C2) wi::mul (C1, P1) wi::mul (P1, C2, SIGN, &OVERFLOW) wi::lshift (P1, C2) These routines just check whether overflow occurs on any individual coefficient; it is not possible to know at compile time whether the final runtime value would overflow.  File: gccint.info, Node: Division of poly_ints, Next: Other poly_int arithmetic, Prev: wi arithmetic on poly_ints, Up: Arithmetic on poly_ints 10.4.3 Division of ‘poly_int’s ------------------------------ Division of ‘poly_int’s is possible for certain inputs. The functions for division return true if the operation is possible and in most cases return the results by pointer. The routines are: ‘multiple_p (A, B)’ ‘multiple_p (A, B, "IENT)’ Return true if A is an exact multiple of B, storing the result in QUOTIENT if so. There are overloads for various combinations of polynomial and constant A, B and QUOTIENT. ‘constant_multiple_p (A, B)’ ‘constant_multiple_p (A, B, "IENT)’ Like ‘multiple_p’, but also test whether the multiple is a compile-time constant. ‘can_div_trunc_p (A, B, "IENT)’ ‘can_div_trunc_p (A, B, "IENT, &REMAINDER)’ Return true if we can calculate ‘trunc (A / B)’ at compile time, storing the result in QUOTIENT and REMAINDER if so. ‘can_div_away_from_zero_p (A, B, "IENT)’ Return true if we can calculate ‘A / B’ at compile time, rounding away from zero. Store the result in QUOTIENT if so. Note that this is true if and only if ‘can_div_trunc_p’ is true. The only difference is in the rounding of the result. There is also an asserting form of division: ‘exact_div (A, B)’ Assert that A is a multiple of B and return ‘A / B’. The result is a ‘poly_int’ if A is a ‘poly_int’.  File: gccint.info, Node: Other poly_int arithmetic, Prev: Division of poly_ints, Up: Arithmetic on poly_ints 10.4.4 Other ‘poly_int’ arithmetic ---------------------------------- There are tentative routines for other operations besides division: ‘can_ior_p (A, B, &RESULT)’ Return true if we can calculate ‘A | B’ at compile time, storing the result in RESULT if so. Also, ANDs with a value ‘(1 << Y) - 1’ or its inverse can be treated as alignment operations. *Note Alignment of poly_ints::. In addition, the following miscellaneous routines are available: ‘coeff_gcd (A)’ Return the greatest common divisor of all nonzero coefficients in A, or zero if A is known to be zero. ‘common_multiple (A, B)’ Return a value that is a multiple of both A and B, where one value is a ‘poly_int’ and the other is a scalar. The result will be the least common multiple for some indeterminate values but not necessarily for all. ‘force_common_multiple (A, B)’ Return a value that is a multiple of both ‘poly_int’ A and ‘poly_int’ B, asserting that such a value exists. The result will be the least common multiple for some indeterminate values but not necessarily for all. When using this routine, please add a comment explaining why the assertion is known to hold. Please add any other operations that you find to be useful.  File: gccint.info, Node: Alignment of poly_ints, Next: Computing bounds on poly_ints, Prev: Arithmetic on poly_ints, Up: poly_int 10.5 Alignment of ‘poly_int’s ============================= ‘poly_int’ provides various routines for aligning values and for querying misalignments. In each case the alignment must be a power of 2. ‘can_align_p (VALUE, ALIGN)’ Return true if we can align VALUE up or down to the nearest multiple of ALIGN at compile time. The answer is the same for both directions. ‘can_align_down (VALUE, ALIGN, &ALIGNED)’ Return true if ‘can_align_p’; if so, set ALIGNED to the greatest aligned value that is less than or equal to VALUE. ‘can_align_up (VALUE, ALIGN, &ALIGNED)’ Return true if ‘can_align_p’; if so, set ALIGNED to the lowest aligned value that is greater than or equal to VALUE. ‘known_equal_after_align_down (A, B, ALIGN)’ Return true if we can align A and B down to the nearest ALIGN boundary at compile time and if the two results are equal. ‘known_equal_after_align_up (A, B, ALIGN)’ Return true if we can align A and B up to the nearest ALIGN boundary at compile time and if the two results are equal. ‘aligned_lower_bound (VALUE, ALIGN)’ Return a result that is no greater than VALUE and that is aligned to ALIGN. The result will the closest aligned value for some indeterminate values but not necessarily for all. For example, suppose we are allocating an object of SIZE bytes in a downward-growing stack whose current limit is given by LIMIT. If the object requires ALIGN bytes of alignment, the new stack limit is given by: aligned_lower_bound (LIMIT - SIZE, ALIGN) ‘aligned_upper_bound (VALUE, ALIGN)’ Likewise return a result that is no less than VALUE and that is aligned to ALIGN. This is the routine that would be used for upward-growing stacks in the scenario just described. ‘known_misalignment (VALUE, ALIGN, &MISALIGN)’ Return true if we can calculate the misalignment of VALUE with respect to ALIGN at compile time, storing the result in MISALIGN if so. ‘known_alignment (VALUE)’ Return the minimum alignment that VALUE is known to have (in other words, the largest alignment that can be guaranteed whatever the values of the indeterminates turn out to be). Return 0 if VALUE is known to be 0. ‘force_align_down (VALUE, ALIGN)’ Assert that VALUE can be aligned down to ALIGN at compile time and return the result. When using this routine, please add a comment explaining why the assertion is known to hold. ‘force_align_up (VALUE, ALIGN)’ Likewise, but aligning up. ‘force_align_down_and_div (VALUE, ALIGN)’ Divide the result of ‘force_align_down’ by ALIGN. Again, please add a comment explaining why the assertion in ‘force_align_down’ is known to hold. ‘force_align_up_and_div (VALUE, ALIGN)’ Likewise for ‘force_align_up’. ‘force_get_misalignment (VALUE, ALIGN)’ Assert that we can calculate the misalignment of VALUE with respect to ALIGN at compile time and return the misalignment. When using this function, please add a comment explaining why the assertion is known to hold.  File: gccint.info, Node: Computing bounds on poly_ints, Next: Converting poly_ints, Prev: Alignment of poly_ints, Up: poly_int 10.6 Computing bounds on ‘poly_int’s ==================================== ‘poly_int’ also provides routines for calculating lower and upper bounds: ‘constant_lower_bound (A)’ Assert that A is nonnegative and return the smallest value it can have. ‘constant_lower_bound_with_limit (A, B)’ Return the least value A can have, given that the context in which A appears guarantees that the answer is no less than B. In other words, the caller is asserting that A is greater than or equal to B even if ‘known_ge (A, B)’ doesn't hold. ‘constant_upper_bound_with_limit (A, B)’ Return the greatest value A can have, given that the context in which A appears guarantees that the answer is no greater than B. In other words, the caller is asserting that A is less than or equal to B even if ‘known_le (A, B)’ doesn't hold. ‘lower_bound (A, B)’ Return a value that is always less than or equal to both A and B. It will be the greatest such value for some indeterminate values but necessarily for all. ‘upper_bound (A, B)’ Return a value that is always greater than or equal to both A and B. It will be the least such value for some indeterminate values but necessarily for all.  File: gccint.info, Node: Converting poly_ints, Next: Miscellaneous poly_int routines, Prev: Computing bounds on poly_ints, Up: poly_int 10.7 Converting ‘poly_int’s =========================== A ‘poly_int’ can be constructed from up to N individual T coefficients, with the remaining coefficients being implicitly zero. In particular, this means that every ‘poly_int’ can be constructed from a single scalar T, or something compatible with T. Also, a ‘poly_int’ can be constructed from a ‘poly_int’ if T can be constructed from U. The following functions provide other forms of conversion, or test whether such a conversion would succeed. ‘VALUE.is_constant ()’ Return true if ‘poly_int’ VALUE is a compile-time constant. ‘VALUE.is_constant (&C1)’ Return true if ‘poly_int’ VALUE is a compile-time constant, storing it in C1 if so. C1 must be able to hold all constant values of VALUE without loss of precision. ‘VALUE.to_constant ()’ Assert that VALUE is a compile-time constant and return its value. When using this function, please add a comment explaining why the condition is known to hold (for example, because an earlier phase of analysis rejected non-constants). ‘VALUE.to_shwi (&P2)’ Return true if ‘poly_int’ VALUE can be represented without loss of precision as a ‘poly_int’, storing it in that form in P2 if so. ‘VALUE.to_uhwi (&P2)’ Return true if ‘poly_int’ VALUE can be represented without loss of precision as a ‘poly_int’, storing it in that form in P2 if so. ‘VALUE.force_shwi ()’ Forcibly convert each coefficient of ‘poly_int’ VALUE to ‘HOST_WIDE_INT’, truncating any that are out of range. Return the result as a ‘poly_int’. ‘VALUE.force_uhwi ()’ Forcibly convert each coefficient of ‘poly_int’ VALUE to ‘unsigned HOST_WIDE_INT’, truncating any that are out of range. Return the result as a ‘poly_int’. ‘wi::shwi (VALUE, PRECISION)’ Return a ‘poly_int’ with the same value as VALUE, but with the coefficients converted from ‘HOST_WIDE_INT’ to ‘wide_int’. PRECISION specifies the precision of the ‘wide_int’ cofficients; if this is wider than a ‘HOST_WIDE_INT’, the coefficients of VALUE will be sign-extended to fit. ‘wi::uhwi (VALUE, PRECISION)’ Like ‘wi::shwi’, except that VALUE has coefficients of type ‘unsigned HOST_WIDE_INT’. If PRECISION is wider than a ‘HOST_WIDE_INT’, the coefficients of VALUE will be zero-extended to fit. ‘wi::sext (VALUE, PRECISION)’ Return a ‘poly_int’ of the same type as VALUE, sign-extending every coefficient from the low PRECISION bits. This in effect applies ‘wi::sext’ to each coefficient individually. ‘wi::zext (VALUE, PRECISION)’ Like ‘wi::sext’, but for zero extension. ‘poly_wide_int::from (VALUE, PRECISION, SIGN)’ Convert VALUE to a ‘poly_wide_int’ in which each coefficient has PRECISION bits. Extend the coefficients according to SIGN if the coefficients have fewer bits. ‘poly_offset_int::from (VALUE, SIGN)’ Convert VALUE to a ‘poly_offset_int’, extending its coefficients according to SIGN if they have fewer bits than ‘offset_int’. ‘poly_widest_int::from (VALUE, SIGN)’ Convert VALUE to a ‘poly_widest_int’, extending its coefficients according to SIGN if they have fewer bits than ‘widest_int’.  File: gccint.info, Node: Miscellaneous poly_int routines, Next: Guidelines for using poly_int, Prev: Converting poly_ints, Up: poly_int 10.8 Miscellaneous ‘poly_int’ routines ====================================== ‘print_dec (VALUE, FILE, SIGN)’ ‘print_dec (VALUE, FILE)’ Print VALUE to FILE as a decimal value, interpreting the coefficients according to SIGN. The final argument is optional if VALUE has an inherent sign; for example, ‘poly_int64’ values print as signed by default and ‘poly_uint64’ values print as unsigned by default. This is a simply a ‘poly_int’ version of a wide-int routine.  File: gccint.info, Node: Guidelines for using poly_int, Prev: Miscellaneous poly_int routines, Up: poly_int 10.9 Guidelines for using ‘poly_int’ ==================================== One of the main design goals of ‘poly_int’ was to make it easy to write target-independent code that handles variable-sized registers even when the current target has fixed-sized registers. There are two aspects to this: • The set of ‘poly_int’ operations should be complete enough that the question in most cases becomes "Can we do this operation on these particular ‘poly_int’ values? If not, bail out" rather than "Are these ‘poly_int’ values constant? If so, do the operation, otherwise bail out". • If target-independent code compiles and runs correctly on a target with one value of ‘NUM_POLY_INT_COEFFS’, and if the code does not use asserting functions like ‘to_constant’, it is reasonable to assume that the code also works on targets with other values of ‘NUM_POLY_INT_COEFFS’. There is no need to check this during everyday development. So the general principle is: if target-independent code is dealing with a ‘poly_int’ value, it is better to operate on it as a ‘poly_int’ if at all possible, choosing conservatively-correct behavior if a particular operation fails. For example, the following code handles an index ‘pos’ into a sequence of vectors that each have ‘nunits’ elements: /* Calculate which vector contains the result, and which lane of that vector we need. */ if (!can_div_trunc_p (pos, nunits, &vec_entry, &vec_index)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "Cannot determine which vector holds the" " final result.\n"); return false; } However, there are some contexts in which operating on a ‘poly_int’ is not possible or does not make sense. One example is when handling static initializers, since no current target supports the concept of a variable-length static initializer. In these situations, a reasonable fallback is: if (POLY_VALUE.is_constant (&CONST_VALUE)) { ... /* Operate on CONST_VALUE. */ ... } else { ... /* Conservatively correct fallback. */ ... } ‘poly_int’ also provides some asserting functions like ‘to_constant’. Please only use these functions if there is a good theoretical reason to believe that the assertion cannot fire. For example, if some work is divided into an analysis phase and an implementation phase, the analysis phase might reject inputs that are not ‘is_constant’, in which case the implementation phase can reasonably use ‘to_constant’ on the remaining inputs. The assertions should not be used to discover whether a condition ever occurs "in the field"; in other words, they should not be used to restrict code to constants at first, with the intention of only implementing a ‘poly_int’ version if a user hits the assertion. If a particular asserting function like ‘to_constant’ is needed more than once for the same reason, it is probably worth adding a helper function or macro for that situation, so that the justification only needs to be given once. For example: /* Return the size of an element in a vector of size SIZE, given that the vector has NELTS elements. The return value is in the same units as SIZE (either bits or bytes). to_constant () is safe in this situation because vector elements are always constant-sized scalars. */ #define vector_element_size(SIZE, NELTS) \ (exact_div (SIZE, NELTS).to_constant ()) Target-specific code in ‘config/CPU’ only needs to handle non-constant ‘poly_int’s if ‘NUM_POLY_INT_COEFFS’ is greater than one. For other targets, ‘poly_int’ degenerates to a compile-time constant and is often interchangable with a normal scalar integer. There are two main exceptions: • Sometimes an explicit cast to an integer type might be needed, such as to resolve ambiguities in a ‘?:’ expression, or when passing values through ‘...’ to things like print functions. • Target macros are included in target-independent code and so do not have access to the implicit conversion to a scalar integer. If this becomes a problem for a particular target macro, the possible solutions, in order of preference, are: • Convert the target macro to a target hook (for all targets). • Put the target's implementation of the target macro in its ‘CPU.c’ file and call it from the target macro in the ‘CPU.h’ file. • Add ‘to_constant ()’ calls where necessary. The previous option is preferable because it will help with any future conversion of the macro to a hook.  File: gccint.info, Node: GENERIC, Next: GIMPLE, Prev: poly_int, Up: Top 11 GENERIC ********** The purpose of GENERIC is simply to provide a language-independent way of representing an entire function in trees. To this end, it was necessary to add a few new tree codes to the back end, but almost everything was already there. If you can express it with the codes in ‘gcc/tree.def’, it's GENERIC. Early on, there was a great deal of debate about how to think about statements in a tree IL. In GENERIC, a statement is defined as any expression whose value, if any, is ignored. A statement will always have ‘TREE_SIDE_EFFECTS’ set (or it will be discarded), but a non-statement expression may also have side effects. A ‘CALL_EXPR’, for instance. It would be possible for some local optimizations to work on the GENERIC form of a function; indeed, the adapted tree inliner works fine on GENERIC, but the current compiler performs inlining after lowering to GIMPLE (a restricted form described in the next section). Indeed, currently the frontends perform this lowering before handing off to ‘tree_rest_of_compilation’, but this seems inelegant. * Menu: * Deficiencies:: Topics not yet covered in this document. * Tree overview:: All about ‘tree’s. * Types:: Fundamental and aggregate types. * Declarations:: Type declarations and variables. * Attributes:: Declaration and type attributes. * Expressions: Expression trees. Operating on data. * Statements:: Control flow and related trees. * Functions:: Function bodies, linkage, and other aspects. * Language-dependent trees:: Topics and trees specific to language front ends. * C and C++ Trees:: Trees specific to C and C++.  File: gccint.info, Node: Deficiencies, Next: Tree overview, Up: GENERIC 11.1 Deficiencies ================= There are many places in which this document is incomplet and incorrekt. It is, as of yet, only _preliminary_ documentation.  File: gccint.info, Node: Tree overview, Next: Types, Prev: Deficiencies, Up: GENERIC 11.2 Overview ============= The central data structure used by the internal representation is the ‘tree’. These nodes, while all of the C type ‘tree’, are of many varieties. A ‘tree’ is a pointer type, but the object to which it points may be of a variety of types. From this point forward, we will refer to trees in ordinary type, rather than in ‘this font’, except when talking about the actual C type ‘tree’. You can tell what kind of node a particular tree is by using the ‘TREE_CODE’ macro. Many, many macros take trees as input and return trees as output. However, most macros require a certain kind of tree node as input. In other words, there is a type-system for trees, but it is not reflected in the C type-system. For safety, it is useful to configure GCC with ‘--enable-checking’. Although this results in a significant performance penalty (since all tree types are checked at run-time), and is therefore inappropriate in a release version, it is extremely helpful during the development process. Many macros behave as predicates. Many, although not all, of these predicates end in ‘_P’. Do not rely on the result type of these macros being of any particular type. You may, however, rely on the fact that the type can be compared to ‘0’, so that statements like if (TEST_P (t) && !TEST_P (y)) x = 1; and int i = (TEST_P (t) != 0); are legal. Macros that return ‘int’ values now may be changed to return ‘tree’ values, or other pointers in the future. Even those that continue to return ‘int’ may return multiple nonzero codes where previously they returned only zero and one. Therefore, you should not write code like if (TEST_P (t) == 1) as this code is not guaranteed to work correctly in the future. You should not take the address of values returned by the macros or functions described here. In particular, no guarantee is given that the values are lvalues. In general, the names of macros are all in uppercase, while the names of functions are entirely in lowercase. There are rare exceptions to this rule. You should assume that any macro or function whose name is made up entirely of uppercase letters may evaluate its arguments more than once. You may assume that a macro or function whose name is made up entirely of lowercase letters will evaluate its arguments only once. The ‘error_mark_node’ is a special tree. Its tree code is ‘ERROR_MARK’, but since there is only ever one node with that code, the usual practice is to compare the tree against ‘error_mark_node’. (This test is just a test for pointer equality.) If an error has occurred during front-end processing the flag ‘errorcount’ will be set. If the front end has encountered code it cannot handle, it will issue a message to the user and set ‘sorrycount’. When these flags are set, any macro or function which normally returns a tree of a particular kind may instead return the ‘error_mark_node’. Thus, if you intend to do any processing of erroneous code, you must be prepared to deal with the ‘error_mark_node’. Occasionally, a particular tree slot (like an operand to an expression, or a particular field in a declaration) will be referred to as "reserved for the back end". These slots are used to store RTL when the tree is converted to RTL for use by the GCC back end. However, if that process is not taking place (e.g., if the front end is being hooked up to an intelligent editor), then those slots may be used by the back end presently in use. If you encounter situations that do not match this documentation, such as tree nodes of types not mentioned here, or macros documented to return entities of a particular kind that instead return entities of some different kind, you have found a bug, either in the front end or in the documentation. Please report these bugs as you would any other bug. * Menu: * Macros and Functions::Macros and functions that can be used with all trees. * Identifiers:: The names of things. * Containers:: Lists and vectors.  File: gccint.info, Node: Macros and Functions, Next: Identifiers, Up: Tree overview 11.2.1 Trees ------------ All GENERIC trees have two fields in common. First, ‘TREE_CHAIN’ is a pointer that can be used as a singly-linked list to other trees. The other is ‘TREE_TYPE’. Many trees store the type of an expression or declaration in this field. These are some other functions for handling trees: ‘tree_size’ Return the number of bytes a tree takes. ‘build0’ ‘build1’ ‘build2’ ‘build3’ ‘build4’ ‘build5’ ‘build6’ These functions build a tree and supply values to put in each parameter. The basic signature is ‘code, type, [operands]’. ‘code’ is the ‘TREE_CODE’, and ‘type’ is a tree representing the ‘TREE_TYPE’. These are followed by the operands, each of which is also a tree.  File: gccint.info, Node: Identifiers, Next: Containers, Prev: Macros and Functions, Up: Tree overview 11.2.2 Identifiers ------------------ An ‘IDENTIFIER_NODE’ represents a slightly more general concept than the standard C or C++ concept of identifier. In particular, an ‘IDENTIFIER_NODE’ may contain a ‘$’, or other extraordinary characters. There are never two distinct ‘IDENTIFIER_NODE’s representing the same identifier. Therefore, you may use pointer equality to compare ‘IDENTIFIER_NODE’s, rather than using a routine like ‘strcmp’. Use ‘get_identifier’ to obtain the unique ‘IDENTIFIER_NODE’ for a supplied string. You can use the following macros to access identifiers: ‘IDENTIFIER_POINTER’ The string represented by the identifier, represented as a ‘char*’. This string is always ‘NUL’-terminated, and contains no embedded ‘NUL’ characters. ‘IDENTIFIER_LENGTH’ The length of the string returned by ‘IDENTIFIER_POINTER’, not including the trailing ‘NUL’. This value of ‘IDENTIFIER_LENGTH (x)’ is always the same as ‘strlen (IDENTIFIER_POINTER (x))’. ‘IDENTIFIER_OPNAME_P’ This predicate holds if the identifier represents the name of an overloaded operator. In this case, you should not depend on the contents of either the ‘IDENTIFIER_POINTER’ or the ‘IDENTIFIER_LENGTH’. ‘IDENTIFIER_TYPENAME_P’ This predicate holds if the identifier represents the name of a user-defined conversion operator. In this case, the ‘TREE_TYPE’ of the ‘IDENTIFIER_NODE’ holds the type to which the conversion operator converts.  File: gccint.info, Node: Containers, Prev: Identifiers, Up: Tree overview 11.2.3 Containers ----------------- Two common container data structures can be represented directly with tree nodes. A ‘TREE_LIST’ is a singly linked list containing two trees per node. These are the ‘TREE_PURPOSE’ and ‘TREE_VALUE’ of each node. (Often, the ‘TREE_PURPOSE’ contains some kind of tag, or additional information, while the ‘TREE_VALUE’ contains the majority of the payload. In other cases, the ‘TREE_PURPOSE’ is simply ‘NULL_TREE’, while in still others both the ‘TREE_PURPOSE’ and ‘TREE_VALUE’ are of equal stature.) Given one ‘TREE_LIST’ node, the next node is found by following the ‘TREE_CHAIN’. If the ‘TREE_CHAIN’ is ‘NULL_TREE’, then you have reached the end of the list. A ‘TREE_VEC’ is a simple vector. The ‘TREE_VEC_LENGTH’ is an integer (not a tree) giving the number of nodes in the vector. The nodes themselves are accessed using the ‘TREE_VEC_ELT’ macro, which takes two arguments. The first is the ‘TREE_VEC’ in question; the second is an integer indicating which element in the vector is desired. The elements are indexed from zero.  File: gccint.info, Node: Types, Next: Declarations, Prev: Tree overview, Up: GENERIC 11.3 Types ========== All types have corresponding tree nodes. However, you should not assume that there is exactly one tree node corresponding to each type. There are often multiple nodes corresponding to the same type. For the most part, different kinds of types have different tree codes. (For example, pointer types use a ‘POINTER_TYPE’ code while arrays use an ‘ARRAY_TYPE’ code.) However, pointers to member functions use the ‘RECORD_TYPE’ code. Therefore, when writing a ‘switch’ statement that depends on the code associated with a particular type, you should take care to handle pointers to member functions under the ‘RECORD_TYPE’ case label. The following functions and macros deal with cv-qualification of types: ‘TYPE_MAIN_VARIANT’ This macro returns the unqualified version of a type. It may be applied to an unqualified type, but it is not always the identity function in that case. A few other macros and functions are usable with all types: ‘TYPE_SIZE’ The number of bits required to represent the type, represented as an ‘INTEGER_CST’. For an incomplete type, ‘TYPE_SIZE’ will be ‘NULL_TREE’. ‘TYPE_ALIGN’ The alignment of the type, in bits, represented as an ‘int’. ‘TYPE_NAME’ This macro returns a declaration (in the form of a ‘TYPE_DECL’) for the type. (Note this macro does _not_ return an ‘IDENTIFIER_NODE’, as you might expect, given its name!) You can look at the ‘DECL_NAME’ of the ‘TYPE_DECL’ to obtain the actual name of the type. The ‘TYPE_NAME’ will be ‘NULL_TREE’ for a type that is not a built-in type, the result of a typedef, or a named class type. ‘TYPE_CANONICAL’ This macro returns the "canonical" type for the given type node. Canonical types are used to improve performance in the C++ and Objective-C++ front ends by allowing efficient comparison between two type nodes in ‘same_type_p’: if the ‘TYPE_CANONICAL’ values of the types are equal, the types are equivalent; otherwise, the types are not equivalent. The notion of equivalence for canonical types is the same as the notion of type equivalence in the language itself. For instance, When ‘TYPE_CANONICAL’ is ‘NULL_TREE’, there is no canonical type for the given type node. In this case, comparison between this type and any other type requires the compiler to perform a deep, "structural" comparison to see if the two type nodes have the same form and properties. The canonical type for a node is always the most fundamental type in the equivalence class of types. For instance, ‘int’ is its own canonical type. A typedef ‘I’ of ‘int’ will have ‘int’ as its canonical type. Similarly, ‘I*’ and a typedef ‘IP’ (defined to ‘I*’) will has ‘int*’ as their canonical type. When building a new type node, be sure to set ‘TYPE_CANONICAL’ to the appropriate canonical type. If the new type is a compound type (built from other types), and any of those other types require structural equality, use ‘SET_TYPE_STRUCTURAL_EQUALITY’ to ensure that the new type also requires structural equality. Finally, if for some reason you cannot guarantee that ‘TYPE_CANONICAL’ will point to the canonical type, use ‘SET_TYPE_STRUCTURAL_EQUALITY’ to make sure that the new type-and any type constructed based on it-requires structural equality. If you suspect that the canonical type system is miscomparing types, pass ‘--param verify-canonical-types=1’ to the compiler or configure with ‘--enable-checking’ to force the compiler to verify its canonical-type comparisons against the structural comparisons; the compiler will then print any warnings if the canonical types miscompare. ‘TYPE_STRUCTURAL_EQUALITY_P’ This predicate holds when the node requires structural equality checks, e.g., when ‘TYPE_CANONICAL’ is ‘NULL_TREE’. ‘SET_TYPE_STRUCTURAL_EQUALITY’ This macro states that the type node it is given requires structural equality checks, e.g., it sets ‘TYPE_CANONICAL’ to ‘NULL_TREE’. ‘same_type_p’ This predicate takes two types as input, and holds if they are the same type. For example, if one type is a ‘typedef’ for the other, or both are ‘typedef’s for the same type. This predicate also holds if the two trees given as input are simply copies of one another; i.e., there is no difference between them at the source level, but, for whatever reason, a duplicate has been made in the representation. You should never use ‘==’ (pointer equality) to compare types; always use ‘same_type_p’ instead. Detailed below are the various kinds of types, and the macros that can be used to access them. Although other kinds of types are used elsewhere in G++, the types described here are the only ones that you will encounter while examining the intermediate representation. ‘VOID_TYPE’ Used to represent the ‘void’ type. ‘INTEGER_TYPE’ Used to represent the various integral types, including ‘char’, ‘short’, ‘int’, ‘long’, and ‘long long’. This code is not used for enumeration types, nor for the ‘bool’ type. The ‘TYPE_PRECISION’ is the number of bits used in the representation, represented as an ‘unsigned int’. (Note that in the general case this is not the same value as ‘TYPE_SIZE’; suppose that there were a 24-bit integer type, but that alignment requirements for the ABI required 32-bit alignment. Then, ‘TYPE_SIZE’ would be an ‘INTEGER_CST’ for 32, while ‘TYPE_PRECISION’ would be 24.) The integer type is unsigned if ‘TYPE_UNSIGNED’ holds; otherwise, it is signed. The ‘TYPE_MIN_VALUE’ is an ‘INTEGER_CST’ for the smallest integer that may be represented by this type. Similarly, the ‘TYPE_MAX_VALUE’ is an ‘INTEGER_CST’ for the largest integer that may be represented by this type. ‘BITINT_TYPE’ Used to represent the bit-precise integer types, ‘_BitInt(N)’. These types are similar to ‘INTEGER_TYPE’, but can have arbitrary user selected precisions and do or can have different alignment, function argument and return value passing conventions. Larger BITINT_TYPEs can have ‘BLKmode’ ‘TYPE_MODE’ and need to be lowered by a special BITINT_TYPE lowering pass. ‘REAL_TYPE’ Used to represent the ‘float’, ‘double’, and ‘long double’ types. The number of bits in the floating-point representation is given by ‘TYPE_PRECISION’, as in the ‘INTEGER_TYPE’ case. ‘FIXED_POINT_TYPE’ Used to represent the ‘short _Fract’, ‘_Fract’, ‘long _Fract’, ‘long long _Fract’, ‘short _Accum’, ‘_Accum’, ‘long _Accum’, and ‘long long _Accum’ types. The number of bits in the fixed-point representation is given by ‘TYPE_PRECISION’, as in the ‘INTEGER_TYPE’ case. There may be padding bits, fractional bits and integral bits. The number of fractional bits is given by ‘TYPE_FBIT’, and the number of integral bits is given by ‘TYPE_IBIT’. The fixed-point type is unsigned if ‘TYPE_UNSIGNED’ holds; otherwise, it is signed. The fixed-point type is saturating if ‘TYPE_SATURATING’ holds; otherwise, it is not saturating. ‘COMPLEX_TYPE’ Used to represent GCC built-in ‘__complex__’ data types. The ‘TREE_TYPE’ is the type of the real and imaginary parts. ‘ENUMERAL_TYPE’ Used to represent an enumeration type. The ‘TYPE_PRECISION’ gives (as an ‘int’), the number of bits used to represent the type. If there are no negative enumeration constants, ‘TYPE_UNSIGNED’ will hold. The minimum and maximum enumeration constants may be obtained with ‘TYPE_MIN_VALUE’ and ‘TYPE_MAX_VALUE’, respectively; each of these macros returns an ‘INTEGER_CST’. The actual enumeration constants themselves may be obtained by looking at the ‘TYPE_VALUES’. This macro will return a ‘TREE_LIST’, containing the constants. The ‘TREE_PURPOSE’ of each node will be an ‘IDENTIFIER_NODE’ giving the name of the constant; the ‘TREE_VALUE’ will be an ‘INTEGER_CST’ giving the value assigned to that constant. These constants will appear in the order in which they were declared. The ‘TREE_TYPE’ of each of these constants will be the type of enumeration type itself. ‘OPAQUE_TYPE’ Used for things that have a ‘MODE_OPAQUE’ mode class in the backend. Opaque types have a size and precision, and can be held in memory or registers. They are used when we do not want the compiler to make assumptions about the availability of other operations as would happen with integer types. ‘BOOLEAN_TYPE’ Used to represent the ‘bool’ type. ‘POINTER_TYPE’ Used to represent pointer types, and pointer to data member types. The ‘TREE_TYPE’ gives the type to which this type points. ‘REFERENCE_TYPE’ Used to represent reference types. The ‘TREE_TYPE’ gives the type to which this type refers. ‘FUNCTION_TYPE’ Used to represent the type of non-member functions and of static member functions. The ‘TREE_TYPE’ gives the return type of the function. The ‘TYPE_ARG_TYPES’ are a ‘TREE_LIST’ of the argument types. The ‘TREE_VALUE’ of each node in this list is the type of the corresponding argument; the ‘TREE_PURPOSE’ is an expression for the default argument value, if any. If the last node in the list is ‘void_list_node’ (a ‘TREE_LIST’ node whose ‘TREE_VALUE’ is the ‘void_type_node’), then functions of this type do not take variable arguments. Otherwise, they do take a variable number of arguments. Note that in C (but not in C++) a function declared like ‘void f()’ is an unprototyped function taking a variable number of arguments; the ‘TYPE_ARG_TYPES’ of such a function will be ‘NULL’. ‘METHOD_TYPE’ Used to represent the type of a non-static member function. Like a ‘FUNCTION_TYPE’, the return type is given by the ‘TREE_TYPE’. The type of ‘*this’, i.e., the class of which functions of this type are a member, is given by the ‘TYPE_METHOD_BASETYPE’. The ‘TYPE_ARG_TYPES’ is the parameter list, as for a ‘FUNCTION_TYPE’, and includes the ‘this’ argument. ‘ARRAY_TYPE’ Used to represent array types. The ‘TREE_TYPE’ gives the type of the elements in the array. If the array-bound is present in the type, the ‘TYPE_DOMAIN’ is an ‘INTEGER_TYPE’ whose ‘TYPE_MIN_VALUE’ and ‘TYPE_MAX_VALUE’ will be the lower and upper bounds of the array, respectively. The ‘TYPE_MIN_VALUE’ will always be an ‘INTEGER_CST’ for zero, while the ‘TYPE_MAX_VALUE’ will be one less than the number of elements in the array, i.e., the highest value which may be used to index an element in the array. ‘RECORD_TYPE’ Used to represent ‘struct’ and ‘class’ types, as well as pointers to member functions and similar constructs in other languages. ‘TYPE_FIELDS’ contains the items contained in this type, each of which can be a ‘FIELD_DECL’, ‘VAR_DECL’, ‘CONST_DECL’, or ‘TYPE_DECL’. You may not make any assumptions about the ordering of the fields in the type or whether one or more of them overlap. ‘UNION_TYPE’ Used to represent ‘union’ types. Similar to ‘RECORD_TYPE’ except that all ‘FIELD_DECL’ nodes in ‘TYPE_FIELD’ start at bit position zero. ‘QUAL_UNION_TYPE’ Used to represent part of a variant record in Ada. Similar to ‘UNION_TYPE’ except that each ‘FIELD_DECL’ has a ‘DECL_QUALIFIER’ field, which contains a boolean expression that indicates whether the field is present in the object. The type will only have one field, so each field's ‘DECL_QUALIFIER’ is only evaluated if none of the expressions in the previous fields in ‘TYPE_FIELDS’ are nonzero. Normally these expressions will reference a field in the outer object using a ‘PLACEHOLDER_EXPR’. ‘LANG_TYPE’ This node is used to represent a language-specific type. The front end must handle it. ‘OFFSET_TYPE’ This node is used to represent a pointer-to-data member. For a data member ‘X::m’ the ‘TYPE_OFFSET_BASETYPE’ is ‘X’ and the ‘TREE_TYPE’ is the type of ‘m’. There are variables whose values represent some of the basic types. These include: ‘void_type_node’ A node for ‘void’. ‘integer_type_node’ A node for ‘int’. ‘unsigned_type_node.’ A node for ‘unsigned int’. ‘char_type_node.’ A node for ‘char’. It may sometimes be useful to compare one of these variables with a type in hand, using ‘same_type_p’.  File: gccint.info, Node: Declarations, Next: Attributes, Prev: Types, Up: GENERIC 11.4 Declarations ================= This section covers the various kinds of declarations that appear in the internal representation, except for declarations of functions (represented by ‘FUNCTION_DECL’ nodes), which are described in *note Functions::. * Menu: * Working with declarations:: Macros and functions that work on declarations. * Internal structure:: How declaration nodes are represented.  File: gccint.info, Node: Working with declarations, Next: Internal structure, Up: Declarations 11.4.1 Working with declarations -------------------------------- Some macros can be used with any kind of declaration. These include: ‘DECL_NAME’ This macro returns an ‘IDENTIFIER_NODE’ giving the name of the entity. ‘TREE_TYPE’ This macro returns the type of the entity declared. ‘EXPR_FILENAME’ This macro returns the name of the file in which the entity was declared, as a ‘char*’. For an entity declared implicitly by the compiler (like ‘__builtin_memcpy’), this will be the string ‘""’. ‘EXPR_LINENO’ This macro returns the line number at which the entity was declared, as an ‘int’. ‘DECL_ARTIFICIAL’ This predicate holds if the declaration was implicitly generated by the compiler. For example, this predicate will hold of an implicitly declared member function, or of the ‘TYPE_DECL’ implicitly generated for a class type. Recall that in C++ code like: struct S {}; is roughly equivalent to C code like: struct S {}; typedef struct S S; The implicitly generated ‘typedef’ declaration is represented by a ‘TYPE_DECL’ for which ‘DECL_ARTIFICIAL’ holds. The various kinds of declarations include: ‘LABEL_DECL’ These nodes are used to represent labels in function bodies. For more information, see *note Functions::. These nodes only appear in block scopes. ‘CONST_DECL’ These nodes are used to represent enumeration constants. The value of the constant is given by ‘DECL_INITIAL’ which will be an ‘INTEGER_CST’ with the same type as the ‘TREE_TYPE’ of the ‘CONST_DECL’, i.e., an ‘ENUMERAL_TYPE’. ‘RESULT_DECL’ These nodes represent the value returned by a function. When a value is assigned to a ‘RESULT_DECL’, that indicates that the value should be returned, via bitwise copy, by the function. You can use ‘DECL_SIZE’ and ‘DECL_ALIGN’ on a ‘RESULT_DECL’, just as with a ‘VAR_DECL’. ‘TYPE_DECL’ These nodes represent ‘typedef’ declarations. The ‘TREE_TYPE’ is the type declared to have the name given by ‘DECL_NAME’. In some cases, there is no associated name. ‘VAR_DECL’ These nodes represent variables with namespace or block scope, as well as static data members. The ‘DECL_SIZE’ and ‘DECL_ALIGN’ are analogous to ‘TYPE_SIZE’ and ‘TYPE_ALIGN’. For a declaration, you should always use the ‘DECL_SIZE’ and ‘DECL_ALIGN’ rather than the ‘TYPE_SIZE’ and ‘TYPE_ALIGN’ given by the ‘TREE_TYPE’, since special attributes may have been applied to the variable to give it a particular size and alignment. You may use the predicates ‘DECL_THIS_STATIC’ or ‘DECL_THIS_EXTERN’ to test whether the storage class specifiers ‘static’ or ‘extern’ were used to declare a variable. If this variable is initialized (but does not require a constructor), the ‘DECL_INITIAL’ will be an expression for the initializer. The initializer should be evaluated, and a bitwise copy into the variable performed. If the ‘DECL_INITIAL’ is the ‘error_mark_node’, there is an initializer, but it is given by an explicit statement later in the code; no bitwise copy is required. GCC provides an extension that allows either automatic variables, or global variables, to be placed in particular registers. This extension is being used for a particular ‘VAR_DECL’ if ‘DECL_REGISTER’ holds for the ‘VAR_DECL’, and if ‘DECL_ASSEMBLER_NAME’ is not equal to ‘DECL_NAME’. In that case, ‘DECL_ASSEMBLER_NAME’ is the name of the register into which the variable will be placed. ‘PARM_DECL’ Used to represent a parameter to a function. Treat these nodes similarly to ‘VAR_DECL’ nodes. These nodes only appear in the ‘DECL_ARGUMENTS’ for a ‘FUNCTION_DECL’. The ‘DECL_ARG_TYPE’ for a ‘PARM_DECL’ is the type that will actually be used when a value is passed to this function. It may be a wider type than the ‘TREE_TYPE’ of the parameter; for example, the ordinary type might be ‘short’ while the ‘DECL_ARG_TYPE’ is ‘int’. ‘DEBUG_EXPR_DECL’ Used to represent an anonymous debug-information temporary created to hold an expression as it is optimized away, so that its value can be referenced in debug bind statements. ‘FIELD_DECL’ These nodes represent non-static data members. The ‘DECL_SIZE’ and ‘DECL_ALIGN’ behave as for ‘VAR_DECL’ nodes. The position of the field within the parent record is specified by a combination of three attributes. ‘DECL_FIELD_OFFSET’ is the position, counting in bytes, of the ‘DECL_OFFSET_ALIGN’-bit sized word containing the bit of the field closest to the beginning of the structure. ‘DECL_FIELD_BIT_OFFSET’ is the bit offset of the first bit of the field within this word; this may be nonzero even for fields that are not bit-fields, since ‘DECL_OFFSET_ALIGN’ may be greater than the natural alignment of the field's type. If ‘DECL_C_BIT_FIELD’ holds, this field is a bit-field. In a bit-field, ‘DECL_BIT_FIELD_TYPE’ also contains the type that was originally specified for it, while DECL_TYPE may be a modified type with lesser precision, according to the size of the bit field. ‘NAMESPACE_DECL’ Namespaces provide a name hierarchy for other declarations. They appear in the ‘DECL_CONTEXT’ of other ‘_DECL’ nodes.  File: gccint.info, Node: Internal structure, Prev: Working with declarations, Up: Declarations 11.4.2 Internal structure ------------------------- ‘DECL’ nodes are represented internally as a hierarchy of structures. * Menu: * Current structure hierarchy:: The current DECL node structure hierarchy. * Adding new DECL node types:: How to add a new DECL node to a frontend.  File: gccint.info, Node: Current structure hierarchy, Next: Adding new DECL node types, Up: Internal structure 11.4.2.1 Current structure hierarchy .................................... ‘struct tree_decl_minimal’ This is the minimal structure to inherit from in order for common ‘DECL’ macros to work. The fields it contains are a unique ID, source location, context, and name. ‘struct tree_decl_common’ This structure inherits from ‘struct tree_decl_minimal’. It contains fields that most ‘DECL’ nodes need, such as a field to store alignment, machine mode, size, and attributes. ‘struct tree_field_decl’ This structure inherits from ‘struct tree_decl_common’. It is used to represent ‘FIELD_DECL’. ‘struct tree_label_decl’ This structure inherits from ‘struct tree_decl_common’. It is used to represent ‘LABEL_DECL’. ‘struct tree_translation_unit_decl’ This structure inherits from ‘struct tree_decl_common’. It is used to represent ‘TRANSLATION_UNIT_DECL’. ‘struct tree_decl_with_rtl’ This structure inherits from ‘struct tree_decl_common’. It contains a field to store the low-level RTL associated with a ‘DECL’ node. ‘struct tree_result_decl’ This structure inherits from ‘struct tree_decl_with_rtl’. It is used to represent ‘RESULT_DECL’. ‘struct tree_const_decl’ This structure inherits from ‘struct tree_decl_with_rtl’. It is used to represent ‘CONST_DECL’. ‘struct tree_parm_decl’ This structure inherits from ‘struct tree_decl_with_rtl’. It is used to represent ‘PARM_DECL’. ‘struct tree_decl_with_vis’ This structure inherits from ‘struct tree_decl_with_rtl’. It contains fields necessary to store visibility information, as well as a section name and assembler name. ‘struct tree_var_decl’ This structure inherits from ‘struct tree_decl_with_vis’. It is used to represent ‘VAR_DECL’. ‘struct tree_function_decl’ This structure inherits from ‘struct tree_decl_with_vis’. It is used to represent ‘FUNCTION_DECL’.  File: gccint.info, Node: Adding new DECL node types, Prev: Current structure hierarchy, Up: Internal structure 11.4.2.2 Adding new DECL node types ................................... Adding a new ‘DECL’ tree consists of the following steps Add a new tree code for the ‘DECL’ node For language specific ‘DECL’ nodes, there is a ‘.def’ file in each frontend directory where the tree code should be added. For ‘DECL’ nodes that are part of the middle-end, the code should be added to ‘tree.def’. Create a new structure type for the ‘DECL’ node These structures should inherit from one of the existing structures in the language hierarchy by using that structure as the first member. struct tree_foo_decl { struct tree_decl_with_vis common; } Would create a structure name ‘tree_foo_decl’ that inherits from ‘struct tree_decl_with_vis’. For language specific ‘DECL’ nodes, this new structure type should go in the appropriate ‘.h’ file. For ‘DECL’ nodes that are part of the middle-end, the structure type should go in ‘tree.h’. Add a member to the tree structure enumerator for the node For garbage collection and dynamic checking purposes, each ‘DECL’ node structure type is required to have a unique enumerator value specified with it. For language specific ‘DECL’ nodes, this new enumerator value should go in the appropriate ‘.def’ file. For ‘DECL’ nodes that are part of the middle-end, the enumerator values are specified in ‘treestruct.def’. Update ‘union tree_node’ In order to make your new structure type usable, it must be added to ‘union tree_node’. For language specific ‘DECL’ nodes, a new entry should be added to the appropriate ‘.h’ file of the form struct tree_foo_decl GTY ((tag ("TS_VAR_DECL"))) foo_decl; For ‘DECL’ nodes that are part of the middle-end, the additional member goes directly into ‘union tree_node’ in ‘tree.h’. Update dynamic checking info In order to be able to check whether accessing a named portion of ‘union tree_node’ is legal, and whether a certain ‘DECL’ node contains one of the enumerated ‘DECL’ node structures in the hierarchy, a simple lookup table is used. This lookup table needs to be kept up to date with the tree structure hierarchy, or else checking and containment macros will fail inappropriately. For language specific ‘DECL’ nodes, there is an ‘init_ts’ function in an appropriate ‘.c’ file, which initializes the lookup table. Code setting up the table for new ‘DECL’ nodes should be added there. For each ‘DECL’ tree code and enumerator value representing a member of the inheritance hierarchy, the table should contain 1 if that tree code inherits (directly or indirectly) from that member. Thus, a ‘FOO_DECL’ node derived from ‘struct decl_with_rtl’, and enumerator value ‘TS_FOO_DECL’, would be set up as follows tree_contains_struct[FOO_DECL][TS_FOO_DECL] = 1; tree_contains_struct[FOO_DECL][TS_DECL_WRTL] = 1; tree_contains_struct[FOO_DECL][TS_DECL_COMMON] = 1; tree_contains_struct[FOO_DECL][TS_DECL_MINIMAL] = 1; For ‘DECL’ nodes that are part of the middle-end, the setup code goes into ‘tree.cc’. Add macros to access any new fields and flags Each added field or flag should have a macro that is used to access it, that performs appropriate checking to ensure only the right type of ‘DECL’ nodes access the field. These macros generally take the following form #define FOO_DECL_FIELDNAME(NODE) FOO_DECL_CHECK(NODE)->foo_decl.fieldname However, if the structure is simply a base class for further structures, something like the following should be used #define BASE_STRUCT_CHECK(T) CONTAINS_STRUCT_CHECK(T, TS_BASE_STRUCT) #define BASE_STRUCT_FIELDNAME(NODE) \ (BASE_STRUCT_CHECK(NODE)->base_struct.fieldname Reading them from the generated ‘all-tree.def’ file (which in turn includes all the ‘tree.def’ files), ‘gencheck.cc’ is used during GCC's build to generate the ‘*_CHECK’ macros for all tree codes.  File: gccint.info, Node: Attributes, Next: Expression trees, Prev: Declarations, Up: GENERIC 11.5 Attributes in trees ======================== Attributes, as specified using the ‘__attribute__’ keyword, are represented internally as a ‘TREE_LIST’. The ‘TREE_PURPOSE’ is the name of the attribute, as an ‘IDENTIFIER_NODE’. The ‘TREE_VALUE’ is a ‘TREE_LIST’ of the arguments of the attribute, if any, or ‘NULL_TREE’ if there are no arguments; the arguments are stored as the ‘TREE_VALUE’ of successive entries in the list, and may be identifiers or expressions. The ‘TREE_CHAIN’ of the attribute is the next attribute in a list of attributes applying to the same declaration or type, or ‘NULL_TREE’ if there are no further attributes in the list. Attributes may be attached to declarations and to types; these attributes may be accessed with the following macros. All attributes are stored in this way, and many also cause other changes to the declaration or type or to other internal compiler data structures. -- Tree Macro: tree DECL_ATTRIBUTES (tree DECL) This macro returns the attributes on the declaration DECL. -- Tree Macro: tree TYPE_ATTRIBUTES (tree TYPE) This macro returns the attributes on the type TYPE.  File: gccint.info, Node: Expression trees, Next: Statements, Prev: Attributes, Up: GENERIC 11.6 Expressions ================ The internal representation for expressions is for the most part quite straightforward. However, there are a few facts that one must bear in mind. In particular, the expression "tree" is actually a directed acyclic graph. (For example there may be many references to the integer constant zero throughout the source program; many of these will be represented by the same expression node.) You should not rely on certain kinds of node being shared, nor should you rely on certain kinds of nodes being unshared. The following macros can be used with all expression nodes: ‘TREE_TYPE’ Returns the type of the expression. This value may not be precisely the same type that would be given the expression in the original program. In what follows, some nodes that one might expect to always have type ‘bool’ are documented to have either integral or boolean type. At some point in the future, the C front end may also make use of this same intermediate representation, and at this point these nodes will certainly have integral type. The previous sentence is not meant to imply that the C++ front end does not or will not give these nodes integral type. Below, we list the various kinds of expression nodes. Except where noted otherwise, the operands to an expression are accessed using the ‘TREE_OPERAND’ macro. For example, to access the first operand to a binary plus expression ‘expr’, use: TREE_OPERAND (expr, 0) As this example indicates, the operands are zero-indexed. * Menu: * Constants: Constant expressions. * Storage References:: * Unary and Binary Expressions:: * Vectors::  File: gccint.info, Node: Constant expressions, Next: Storage References, Up: Expression trees 11.6.1 Constant expressions --------------------------- The table below begins with constants, moves on to unary expressions, then proceeds to binary expressions, and concludes with various other kinds of expressions: ‘INTEGER_CST’ These nodes represent integer constants. Note that the type of these constants is obtained with ‘TREE_TYPE’; they are not always of type ‘int’. In particular, ‘char’ constants are represented with ‘INTEGER_CST’ nodes. The value of the integer constant ‘e’ is represented in an array of HOST_WIDE_INT. There are enough elements in the array to represent the value without taking extra elements for redundant 0s or -1. The number of elements used to represent ‘e’ is available via ‘TREE_INT_CST_NUNITS’. Element ‘i’ can be extracted by using ‘TREE_INT_CST_ELT (e, i)’. ‘TREE_INT_CST_LOW’ is a shorthand for ‘TREE_INT_CST_ELT (e, 0)’. The functions ‘tree_fits_shwi_p’ and ‘tree_fits_uhwi_p’ can be used to tell if the value is small enough to fit in a signed HOST_WIDE_INT or an unsigned HOST_WIDE_INT respectively. The value can then be extracted using ‘tree_to_shwi’ and ‘tree_to_uhwi’. ‘REAL_CST’ FIXME: Talk about how to obtain representations of this constant, do comparisons, and so forth. ‘FIXED_CST’ These nodes represent fixed-point constants. The type of these constants is obtained with ‘TREE_TYPE’. ‘TREE_FIXED_CST_PTR’ points to a ‘struct fixed_value’; ‘TREE_FIXED_CST’ returns the structure itself. ‘struct fixed_value’ contains ‘data’ with the size of two ‘HOST_BITS_PER_WIDE_INT’ and ‘mode’ as the associated fixed-point machine mode for ‘data’. ‘COMPLEX_CST’ These nodes are used to represent complex number constants, that is a ‘__complex__’ whose parts are constant nodes. The ‘TREE_REALPART’ and ‘TREE_IMAGPART’ return the real and the imaginary parts respectively. ‘VECTOR_CST’ These nodes are used to represent vector constants. Each vector constant V is treated as a specific instance of an arbitrary-length sequence that itself contains ‘VECTOR_CST_NPATTERNS (V)’ interleaved patterns. Each pattern has the form: { BASE0, BASE1, BASE1 + STEP, BASE1 + STEP * 2, ... } The first three elements in each pattern are enough to determine the values of the other elements. However, if all STEPs are zero, only the first two elements are needed. If in addition each BASE1 is equal to the corresponding BASE0, only the first element in each pattern is needed. The number of encoded elements per pattern is given by ‘VECTOR_CST_NELTS_PER_PATTERN (V)’. For example, the constant: { 0, 1, 2, 6, 3, 8, 4, 10, 5, 12, 6, 14, 7, 16, 8, 18 } is interpreted as an interleaving of the sequences: { 0, 2, 3, 4, 5, 6, 7, 8 } { 1, 6, 8, 10, 12, 14, 16, 18 } where the sequences are represented by the following patterns: BASE0 == 0, BASE1 == 2, STEP == 1 BASE0 == 1, BASE1 == 6, STEP == 2 In this case: VECTOR_CST_NPATTERNS (V) == 2 VECTOR_CST_NELTS_PER_PATTERN (V) == 3 The vector is therefore encoded using the first 6 elements (‘{ 0, 1, 2, 6, 3, 8 }’), with the remaining 10 elements being implicit extensions of them. Sometimes this scheme can create two possible encodings of the same vector. For example { 0, 1 } could be seen as two patterns with one element each or one pattern with two elements (BASE0 and BASE1). The canonical encoding is always the one with the fewest patterns or (if both encodings have the same number of patterns) the one with the fewest encoded elements. ‘vector_cst_encoding_nelts (V)’ gives the total number of encoded elements in V, which is 6 in the example above. ‘VECTOR_CST_ENCODED_ELTS (V)’ gives a pointer to the elements encoded in V and ‘VECTOR_CST_ENCODED_ELT (V, I)’ accesses the value of encoded element I. ‘VECTOR_CST_DUPLICATE_P (V)’ is true if V simply contains repeated instances of ‘VECTOR_CST_NPATTERNS (V)’ values. This is a shorthand for testing ‘VECTOR_CST_NELTS_PER_PATTERN (V) == 1’. ‘VECTOR_CST_STEPPED_P (V)’ is true if at least one pattern in V has a nonzero step. This is a shorthand for testing ‘VECTOR_CST_NELTS_PER_PATTERN (V) == 3’. The utility function ‘vector_cst_elt’ gives the value of an arbitrary index as a ‘tree’. ‘vector_cst_int_elt’ gives the same value as a ‘wide_int’. ‘STRING_CST’ These nodes represent string-constants. The ‘TREE_STRING_LENGTH’ returns the length of the string, as an ‘int’. The ‘TREE_STRING_POINTER’ is a ‘char*’ containing the string itself. The string may not be ‘NUL’-terminated, and it may contain embedded ‘NUL’ characters. Therefore, the ‘TREE_STRING_LENGTH’ includes the trailing ‘NUL’ if it is present. For wide string constants, the ‘TREE_STRING_LENGTH’ is the number of bytes in the string, and the ‘TREE_STRING_POINTER’ points to an array of the bytes of the string, as represented on the target system (that is, as integers in the target endianness). Wide and non-wide string constants are distinguished only by the ‘TREE_TYPE’ of the ‘STRING_CST’. FIXME: The formats of string constants are not well-defined when the target system bytes are not the same width as host system bytes. ‘POLY_INT_CST’ These nodes represent invariants that depend on some target-specific runtime parameters. They consist of ‘NUM_POLY_INT_COEFFS’ coefficients, with the first coefficient being the constant term and the others being multipliers that are applied to the runtime parameters. ‘POLY_INT_CST_ELT (X, I)’ references coefficient number I of ‘POLY_INT_CST’ node X. Each coefficient is an ‘INTEGER_CST’.  File: gccint.info, Node: Storage References, Next: Unary and Binary Expressions, Prev: Constant expressions, Up: Expression trees 11.6.2 References to storage ---------------------------- ‘ARRAY_REF’ These nodes represent array accesses. The first operand is the array; the second is the index. To calculate the address of the memory accessed, you must scale the index by the size of the type of the array elements. The type of these expressions must be the type of a component of the array. The third and fourth operands are used after gimplification to represent the lower bound and component size but should not be used directly; call ‘array_ref_low_bound’ and ‘array_ref_element_size’ instead. ‘ARRAY_RANGE_REF’ These nodes represent access to a range (or "slice") of an array. The operands are the same as that for ‘ARRAY_REF’ and have the same meanings. The type of these expressions must be an array whose component type is the same as that of the first operand. The range of that array type determines the amount of data these expressions access. ‘COMPONENT_REF’ These nodes represent non-static data member accesses. The first operand is the object (rather than a pointer to it); the second operand is the ‘FIELD_DECL’ for the data member. The third operand represents the byte offset of the field, but should not be used directly; call ‘component_ref_field_offset’ instead. ‘ADDR_EXPR’ These nodes are used to represent the address of an object. (These expressions will always have pointer or reference type.) The operand may be another expression, or it may be a declaration. As an extension, GCC allows users to take the address of a label. In this case, the operand of the ‘ADDR_EXPR’ will be a ‘LABEL_DECL’. The type of such an expression is ‘void*’. If the object addressed is not an lvalue, a temporary is created, and the address of the temporary is used. ‘INDIRECT_REF’ These nodes are used to represent the object pointed to by a pointer. The operand is the pointer being dereferenced; it will always have pointer or reference type. ‘MEM_REF’ These nodes are used to represent the object pointed to by a pointer offset by a constant. The first operand is the pointer being dereferenced; it will always have pointer or reference type. The second operand is a pointer constant serving as constant offset applied to the pointer being dereferenced with its type specifying the type to be used for type-based alias analysis. The type of the node specifies the alignment of the access. ‘TARGET_MEM_REF’ These nodes represent memory accesses whose address directly map to an addressing mode of the target architecture. The first argument is ‘TMR_BASE’ and is a pointer to the object being accessed. The second argument is ‘TMR_OFFSET’ which is a pointer constant with dual purpose serving both as constant offset and holder of the type used for type-based alias analysis. The first two operands have exactly the same semantics as ‘MEM_REF’. The third and fourth operand are ‘TMR_INDEX’ and ‘TMR_STEP’ where the former is an integer and the latter an integer constant. The fifth and last operand is ‘TMR_INDEX2’ which is an alternate non-constant offset. Any of the third to last operands may be ‘NULL’ if the corresponding component does not appear in the address, but ‘TMR_INDEX’ and ‘TMR_STEP’ shall be always supplied in pair. The Address of the ‘TARGET_MEM_REF’ is determined in the following way. TMR_BASE + TMR_OFFSET + TMR_INDEX * TMR_STEP + TMR_INDEX2 The type of the node specifies the alignment of the access.  File: gccint.info, Node: Unary and Binary Expressions, Next: Vectors, Prev: Storage References, Up: Expression trees 11.6.3 Unary and Binary Expressions ----------------------------------- ‘NEGATE_EXPR’ These nodes represent unary negation of the single operand, for both integer and floating-point types. The type of negation can be determined by looking at the type of the expression. The behavior of this operation on signed arithmetic overflow is controlled by the ‘flag_wrapv’ and ‘flag_trapv’ variables. ‘ABS_EXPR’ These nodes represent the absolute value of the single operand, for both integer and floating-point types. This is typically used to implement the ‘abs’, ‘labs’ and ‘llabs’ builtins for integer types, and the ‘fabs’, ‘fabsf’ and ‘fabsl’ builtins for floating point types. The type of abs operation can be determined by looking at the type of the expression. This node is not used for complex types. To represent the modulus or complex abs of a complex value, use the ‘BUILT_IN_CABS’, ‘BUILT_IN_CABSF’ or ‘BUILT_IN_CABSL’ builtins, as used to implement the C99 ‘cabs’, ‘cabsf’ and ‘cabsl’ built-in functions. ‘ABSU_EXPR’ These nodes represent the absolute value of the single operand in equivalent unsigned type such that ‘ABSU_EXPR’ of ‘TYPE_MIN’ is well defined. ‘BIT_NOT_EXPR’ These nodes represent bitwise complement, and will always have integral type. The only operand is the value to be complemented. ‘TRUTH_NOT_EXPR’ These nodes represent logical negation, and will always have integral (or boolean) type. The operand is the value being negated. The type of the operand and that of the result are always of ‘BOOLEAN_TYPE’ or ‘INTEGER_TYPE’. ‘PREDECREMENT_EXPR’ ‘PREINCREMENT_EXPR’ ‘POSTDECREMENT_EXPR’ ‘POSTINCREMENT_EXPR’ These nodes represent increment and decrement expressions. The value of the single operand is computed, and the operand incremented or decremented. In the case of ‘PREDECREMENT_EXPR’ and ‘PREINCREMENT_EXPR’, the value of the expression is the value resulting after the increment or decrement; in the case of ‘POSTDECREMENT_EXPR’ and ‘POSTINCREMENT_EXPR’ is the value before the increment or decrement occurs. The type of the operand, like that of the result, will be either integral, boolean, or floating-point. ‘FIX_TRUNC_EXPR’ These nodes represent conversion of a floating-point value to an integer. The single operand will have a floating-point type, while the complete expression will have an integral (or boolean) type. The operand is rounded towards zero. ‘FLOAT_EXPR’ These nodes represent conversion of an integral (or boolean) value to a floating-point value. The single operand will have integral type, while the complete expression will have a floating-point type. FIXME: How is the operand supposed to be rounded? Is this dependent on ‘-mieee’? ‘COMPLEX_EXPR’ These nodes are used to represent complex numbers constructed from two expressions of the same (integer or real) type. The first operand is the real part and the second operand is the imaginary part. ‘CONJ_EXPR’ These nodes represent the conjugate of their operand. ‘REALPART_EXPR’ ‘IMAGPART_EXPR’ These nodes represent respectively the real and the imaginary parts of complex numbers (their sole argument). ‘NON_LVALUE_EXPR’ These nodes indicate that their one and only operand is not an lvalue. A back end can treat these identically to the single operand. ‘NOP_EXPR’ These nodes are used to represent conversions that do not require any code-generation. For example, conversion of a ‘char*’ to an ‘int*’ does not require any code be generated; such a conversion is represented by a ‘NOP_EXPR’. The single operand is the expression to be converted. The conversion from a pointer to a reference is also represented with a ‘NOP_EXPR’. ‘CONVERT_EXPR’ These nodes are similar to ‘NOP_EXPR’s, but are used in those situations where code may need to be generated. For example, if an ‘int*’ is converted to an ‘int’ code may need to be generated on some platforms. These nodes are never used for C++-specific conversions, like conversions between pointers to different classes in an inheritance hierarchy. Any adjustments that need to be made in such cases are always indicated explicitly. Similarly, a user-defined conversion is never represented by a ‘CONVERT_EXPR’; instead, the function calls are made explicit. ‘FIXED_CONVERT_EXPR’ These nodes are used to represent conversions that involve fixed-point values. For example, from a fixed-point value to another fixed-point value, from an integer to a fixed-point value, from a fixed-point value to an integer, from a floating-point value to a fixed-point value, or from a fixed-point value to a floating-point value. ‘LSHIFT_EXPR’ ‘RSHIFT_EXPR’ ‘LROTATE_EXPR’ ‘RROTATE_EXPR’ These nodes represent left and right shifts and rotates, respectively. The first operand is the value to shift or rotate; it will always be of integral type. The second operand is an expression for the number of bits by which to shift or rotate. Right shift should be treated as arithmetic, i.e., the high-order bits should be zero-filled when the expression has unsigned type and filled with the sign bit when the expression has signed type. All other operations are logical, operating on the bit representation. Note that the result is undefined if the second operand is larger than or equal to the first operand's type size. Unlike most nodes, these can have a vector as first operand and a scalar as second operand. ‘BIT_IOR_EXPR’ ‘BIT_XOR_EXPR’ ‘BIT_AND_EXPR’ These nodes represent bitwise inclusive or, bitwise exclusive or, and bitwise and, respectively. Both operands will always have integral type. ‘TRUTH_ANDIF_EXPR’ ‘TRUTH_ORIF_EXPR’ These nodes represent logical "and" and logical "or", respectively. These operators are not strict; i.e., the second operand is evaluated only if the value of the expression is not determined by evaluation of the first operand. The type of the operands and that of the result are always of ‘BOOLEAN_TYPE’ or ‘INTEGER_TYPE’. ‘TRUTH_AND_EXPR’ ‘TRUTH_OR_EXPR’ ‘TRUTH_XOR_EXPR’ These nodes represent logical and, logical or, and logical exclusive or. They are strict; both arguments are always evaluated. There are no corresponding operators in C or C++, but the front end will sometimes generate these expressions anyhow, if it can tell that strictness does not matter. The type of the operands and that of the result are always of ‘BOOLEAN_TYPE’ or ‘INTEGER_TYPE’. ‘POINTER_PLUS_EXPR’ This node represents pointer arithmetic. The first operand is always a pointer/reference type. The second operand is always an unsigned integer type compatible with sizetype. This and POINTER_DIFF_EXPR are the only binary arithmetic operators that can operate on pointer types. ‘POINTER_DIFF_EXPR’ This node represents pointer subtraction. The two operands always have pointer/reference type. It returns a signed integer of the same precision as the pointers. The behavior is undefined if the difference of the two pointers, seen as infinite precision non-negative integers, does not fit in the result type. The result does not depend on the pointer type, it is not divided by the size of the pointed-to type. ‘PLUS_EXPR’ ‘MINUS_EXPR’ ‘MULT_EXPR’ These nodes represent various binary arithmetic operations. Respectively, these operations are addition, subtraction (of the second operand from the first) and multiplication. Their operands may have either integral or floating type, but there will never be case in which one operand is of floating type and the other is of integral type. The behavior of these operations on signed arithmetic overflow is controlled by the ‘flag_wrapv’ and ‘flag_trapv’ variables. ‘WIDEN_MULT_EXPR’ This node represents a widening multiplication. The operands have integral types with same B bits of precision, producing an integral type result with at least 2B bits of precision. The behaviour is equivalent to extending both operands, possibly of different signedness, to the result type, then multiplying them. ‘MULT_HIGHPART_EXPR’ This node represents the "high-part" of a widening multiplication. For an integral type with B bits of precision, the result is the most significant B bits of the full 2B product. Both operands must have the same precision and same signedness. ‘RDIV_EXPR’ This node represents a floating point division operation. ‘TRUNC_DIV_EXPR’ ‘FLOOR_DIV_EXPR’ ‘CEIL_DIV_EXPR’ ‘ROUND_DIV_EXPR’ These nodes represent integer division operations that return an integer result. ‘TRUNC_DIV_EXPR’ rounds towards zero, ‘FLOOR_DIV_EXPR’ rounds towards negative infinity, ‘CEIL_DIV_EXPR’ rounds towards positive infinity and ‘ROUND_DIV_EXPR’ rounds to the closest integer. Integer division in C and C++ is truncating, i.e. ‘TRUNC_DIV_EXPR’. The behavior of these operations on signed arithmetic overflow, when dividing the minimum signed integer by minus one, is controlled by the ‘flag_wrapv’ and ‘flag_trapv’ variables. ‘TRUNC_MOD_EXPR’ ‘FLOOR_MOD_EXPR’ ‘CEIL_MOD_EXPR’ ‘ROUND_MOD_EXPR’ These nodes represent the integer remainder or modulus operation. The integer modulus of two operands ‘a’ and ‘b’ is defined as ‘a - (a/b)*b’ where the division calculated using the corresponding division operator. Hence for ‘TRUNC_MOD_EXPR’ this definition assumes division using truncation towards zero, i.e. ‘TRUNC_DIV_EXPR’. Integer remainder in C and C++ uses truncating division, i.e. ‘TRUNC_MOD_EXPR’. ‘EXACT_DIV_EXPR’ The ‘EXACT_DIV_EXPR’ code is used to represent integer divisions where the numerator is known to be an exact multiple of the denominator. This allows the backend to choose between the faster of ‘TRUNC_DIV_EXPR’, ‘CEIL_DIV_EXPR’ and ‘FLOOR_DIV_EXPR’ for the current target. ‘LT_EXPR’ ‘LE_EXPR’ ‘GT_EXPR’ ‘GE_EXPR’ ‘LTGT_EXPR’ ‘EQ_EXPR’ ‘NE_EXPR’ These nodes represent the less than, less than or equal to, greater than, greater than or equal to, less or greater than, equal, and not equal comparison operators. The first and second operands will either be both of integral type, both of floating type or both of vector type, except for LTGT_EXPR where they will only be both of floating type. The result type of these expressions will always be of integral, boolean or signed integral vector type. These operations return the result type's zero value for false, the result type's one value for true, and a vector whose elements are zero (false) or minus one (true) for vectors. For floating point comparisons, if we honor IEEE NaNs and either operand is NaN, then ‘NE_EXPR’ always returns true and the remaining operators always return false. On some targets, comparisons against an IEEE NaN, other than equality and inequality, may generate a floating-point exception. ‘ORDERED_EXPR’ ‘UNORDERED_EXPR’ These nodes represent non-trapping ordered and unordered comparison operators. These operations take two floating point operands and determine whether they are ordered or unordered relative to each other. If either operand is an IEEE NaN, their comparison is defined to be unordered, otherwise the comparison is defined to be ordered. The result type of these expressions will always be of integral or boolean type. These operations return the result type's zero value for false, and the result type's one value for true. ‘UNLT_EXPR’ ‘UNLE_EXPR’ ‘UNGT_EXPR’ ‘UNGE_EXPR’ ‘UNEQ_EXPR’ These nodes represent the unordered comparison operators. These operations take two floating point operands and determine whether the operands are unordered or are less than, less than or equal to, greater than, greater than or equal to, or equal respectively. For example, ‘UNLT_EXPR’ returns true if either operand is an IEEE NaN or the first operand is less than the second. All these operations are guaranteed not to generate a floating point exception. The result type of these expressions will always be of integral or boolean type. These operations return the result type's zero value for false, and the result type's one value for true. ‘MODIFY_EXPR’ These nodes represent assignment. The left-hand side is the first operand; the right-hand side is the second operand. The left-hand side will be a ‘VAR_DECL’, ‘INDIRECT_REF’, ‘COMPONENT_REF’, or other lvalue. These nodes are used to represent not only assignment with ‘=’ but also compound assignments (like ‘+=’), by reduction to ‘=’ assignment. In other words, the representation for ‘i += 3’ looks just like that for ‘i = i + 3’. ‘INIT_EXPR’ These nodes are just like ‘MODIFY_EXPR’, but are used only when a variable is initialized, rather than assigned to subsequently. This means that we can assume that the target of the initialization is not used in computing its own value; any reference to the lhs in computing the rhs is undefined. ‘COMPOUND_EXPR’ These nodes represent comma-expressions. The first operand is an expression whose value is computed and thrown away prior to the evaluation of the second operand. The value of the entire expression is the value of the second operand. ‘COND_EXPR’ These nodes represent ‘?:’ expressions. The first operand is of boolean or integral type. If it evaluates to a nonzero value, the second operand should be evaluated, and returned as the value of the expression. Otherwise, the third operand is evaluated, and returned as the value of the expression. The second operand must have the same type as the entire expression, unless it unconditionally throws an exception or calls a noreturn function, in which case it should have void type. The same constraints apply to the third operand. This allows array bounds checks to be represented conveniently as ‘(i >= 0 && i < 10) ? i : abort()’. As a GNU extension, the C language front-ends allow the second operand of the ‘?:’ operator may be omitted in the source. For example, ‘x ? : 3’ is equivalent to ‘x ? x : 3’, assuming that ‘x’ is an expression without side effects. In the tree representation, however, the second operand is always present, possibly protected by ‘SAVE_EXPR’ if the first argument does cause side effects. ‘CALL_EXPR’ These nodes are used to represent calls to functions, including non-static member functions. ‘CALL_EXPR’s are implemented as expression nodes with a variable number of operands. Rather than using ‘TREE_OPERAND’ to extract them, it is preferable to use the specialized accessor macros and functions that operate specifically on ‘CALL_EXPR’ nodes. ‘CALL_EXPR_FN’ returns a pointer to the function to call; it is always an expression whose type is a ‘POINTER_TYPE’. The number of arguments to the call is returned by ‘call_expr_nargs’, while the arguments themselves can be accessed with the ‘CALL_EXPR_ARG’ macro. The arguments are zero-indexed and numbered left-to-right. You can iterate over the arguments using ‘FOR_EACH_CALL_EXPR_ARG’, as in: tree call, arg; call_expr_arg_iterator iter; FOR_EACH_CALL_EXPR_ARG (arg, iter, call) /* arg is bound to successive arguments of call. */ ...; For non-static member functions, there will be an operand corresponding to the ‘this’ pointer. There will always be expressions corresponding to all of the arguments, even if the function is declared with default arguments and some arguments are not explicitly provided at the call sites. ‘CALL_EXPR’s also have a ‘CALL_EXPR_STATIC_CHAIN’ operand that is used to implement nested functions. This operand is otherwise null. ‘CLEANUP_POINT_EXPR’ These nodes represent full-expressions. The single operand is an expression to evaluate. Any destructor calls engendered by the creation of temporaries during the evaluation of that expression should be performed immediately after the expression is evaluated. ‘CONSTRUCTOR’ These nodes represent the brace-enclosed initializers for a structure or an array. They contain a sequence of component values made out of a vector of constructor_elt, which is a (‘INDEX’, ‘VALUE’) pair. If the ‘TREE_TYPE’ of the ‘CONSTRUCTOR’ is a ‘RECORD_TYPE’, ‘UNION_TYPE’ or ‘QUAL_UNION_TYPE’ then the ‘INDEX’ of each node in the sequence will be a ‘FIELD_DECL’ and the ‘VALUE’ will be the expression used to initialize that field. If the ‘TREE_TYPE’ of the ‘CONSTRUCTOR’ is an ‘ARRAY_TYPE’, then the ‘INDEX’ of each node in the sequence will be an ‘INTEGER_CST’ or a ‘RANGE_EXPR’ of two ‘INTEGER_CST’s. A single ‘INTEGER_CST’ indicates which element of the array is being assigned to. A ‘RANGE_EXPR’ indicates an inclusive range of elements to initialize. In both cases the ‘VALUE’ is the corresponding initializer. It is re-evaluated for each element of a ‘RANGE_EXPR’. If the ‘INDEX’ is ‘NULL_TREE’, then the initializer is for the next available array element. In the front end, you should not depend on the fields appearing in any particular order. However, in the middle end, fields must appear in declaration order. You should not assume that all fields will be represented. Unrepresented fields will be cleared (zeroed), unless the CONSTRUCTOR_NO_CLEARING flag is set, in which case their value becomes undefined. ‘COMPOUND_LITERAL_EXPR’ These nodes represent ISO C99 compound literals. The ‘COMPOUND_LITERAL_EXPR_DECL_EXPR’ is a ‘DECL_EXPR’ containing an anonymous ‘VAR_DECL’ for the unnamed object represented by the compound literal; the ‘DECL_INITIAL’ of that ‘VAR_DECL’ is a ‘CONSTRUCTOR’ representing the brace-enclosed list of initializers in the compound literal. That anonymous ‘VAR_DECL’ can also be accessed directly by the ‘COMPOUND_LITERAL_EXPR_DECL’ macro. ‘SAVE_EXPR’ A ‘SAVE_EXPR’ represents an expression (possibly involving side effects) that is used more than once. The side effects should occur only the first time the expression is evaluated. Subsequent uses should just reuse the computed value. The first operand to the ‘SAVE_EXPR’ is the expression to evaluate. The side effects should be executed where the ‘SAVE_EXPR’ is first encountered in a depth-first preorder traversal of the expression tree. ‘TARGET_EXPR’ A ‘TARGET_EXPR’ represents a temporary object. The first operand is a ‘VAR_DECL’ for the temporary variable. The second operand is the initializer for the temporary. The initializer is evaluated and, if non-void, copied (bitwise) into the temporary. If the initializer is void, that means that it will perform the initialization itself. Often, a ‘TARGET_EXPR’ occurs on the right-hand side of an assignment, or as the second operand to a comma-expression which is itself the right-hand side of an assignment, etc. In this case, we say that the ‘TARGET_EXPR’ is "normal"; otherwise, we say it is "orphaned". For a normal ‘TARGET_EXPR’ the temporary variable should be treated as an alias for the left-hand side of the assignment, rather than as a new temporary variable. The third operand to the ‘TARGET_EXPR’, if present, is a cleanup-expression (i.e., destructor call) for the temporary. If this expression is orphaned, then this expression must be executed when the statement containing this expression is complete. These cleanups must always be executed in the order opposite to that in which they were encountered. Note that if a temporary is created on one branch of a conditional operator (i.e., in the second or third operand to a ‘COND_EXPR’), the cleanup must be run only if that branch is actually executed. ‘VA_ARG_EXPR’ This node is used to implement support for the C/C++ variable argument-list mechanism. It represents expressions like ‘va_arg (ap, type)’. Its ‘TREE_TYPE’ yields the tree representation for ‘type’ and its sole argument yields the representation for ‘ap’. ‘ANNOTATE_EXPR’ This node is used to attach markers to an expression. The first operand is the annotated expression, the second is an ‘INTEGER_CST’ with a value from ‘enum annot_expr_kind’, the third is an ‘INTEGER_CST’.  File: gccint.info, Node: Vectors, Prev: Unary and Binary Expressions, Up: Expression trees 11.6.4 Vectors -------------- ‘VEC_DUPLICATE_EXPR’ This node has a single operand and represents a vector in which every element is equal to that operand. ‘VEC_SERIES_EXPR’ This node represents a vector formed from a scalar base and step, given as the first and second operands respectively. Element I of the result is equal to ‘BASE + I*STEP’. This node is restricted to integral types, in order to avoid specifying the rounding behavior for floating-point types. ‘VEC_LSHIFT_EXPR’ ‘VEC_RSHIFT_EXPR’ These nodes represent whole vector left and right shifts, respectively. The first operand is the vector to shift; it will always be of vector type. The second operand is an expression for the number of bits by which to shift. Note that the result is undefined if the second operand is larger than or equal to the first operand's type size. ‘VEC_WIDEN_MULT_HI_EXPR’ ‘VEC_WIDEN_MULT_LO_EXPR’ These nodes represent widening vector multiplication of the high and low parts of the two input vectors, respectively. Their operands are vectors that contain the same number of elements (‘N’) of the same integral type. The result is a vector that contains half as many elements, of an integral type whose size is twice as wide. In the case of ‘VEC_WIDEN_MULT_HI_EXPR’ the high ‘N/2’ elements of the two vector are multiplied to produce the vector of ‘N/2’ products. In the case of ‘VEC_WIDEN_MULT_LO_EXPR’ the low ‘N/2’ elements of the two vector are multiplied to produce the vector of ‘N/2’ products. ‘IFN_VEC_WIDEN_PLUS’ This internal function represents widening vector addition of two input vectors. Its operands are vectors that contain the same number of elements (‘N’) of the same integral type. The result is a vector that contains the same amount (‘N’) of elements, of an integral type whose size is twice as wide, as the input vectors. If the current target does not implement the corresponding optabs the vectorizer may choose to split it into either a pair of ‘IFN_VEC_WIDEN_PLUS_HI’ and ‘IFN_VEC_WIDEN_PLUS_LO’ or ‘IFN_VEC_WIDEN_PLUS_EVEN’ and ‘IFN_VEC_WIDEN_PLUS_ODD’, depending on what optabs the target implements. ‘IFN_VEC_WIDEN_PLUS_HI’ ‘IFN_VEC_WIDEN_PLUS_LO’ These internal functions represent widening vector addition of the high and low parts of the two input vectors, respectively. Their operands are vectors that contain the same number of elements (‘N’) of the same integral type. The result is a vector that contains half as many elements, of an integral type whose size is twice as wide. In the case of ‘IFN_VEC_WIDEN_PLUS_HI’ the high ‘N/2’ elements of the two vectors are added to produce the vector of ‘N/2’ additions. In the case of ‘IFN_VEC_WIDEN_PLUS_LO’ the low ‘N/2’ elements of the two vectors are added to produce the vector of ‘N/2’ additions. ‘IFN_VEC_WIDEN_PLUS_EVEN’ ‘IFN_VEC_WIDEN_PLUS_ODD’ These internal functions represent widening vector addition of the even and odd elements of the two input vectors, respectively. Their operands are vectors that contain the same number of elements (‘N’) of the same integral type. The result is a vector that contains half as many elements, of an integral type whose size is twice as wide. In the case of ‘IFN_VEC_WIDEN_PLUS_EVEN’ the even ‘N/2’ elements of the two vectors are added to produce the vector of ‘N/2’ additions. In the case of ‘IFN_VEC_WIDEN_PLUS_ODD’ the odd ‘N/2’ elements of the two vectors are added to produce the vector of ‘N/2’ additions. ‘IFN_VEC_WIDEN_MINUS’ This internal function represents widening vector subtraction of two input vectors. Its operands are vectors that contain the same number of elements (‘N’) of the same integral type. The result is a vector that contains the same amount (‘N’) of elements, of an integral type whose size is twice as wide, as the input vectors. If the current target does not implement the corresponding optabs the vectorizer may choose to split it into either a pair of ‘IFN_VEC_WIDEN_MINUS_HI’ and ‘IFN_VEC_WIDEN_MINUS_LO’ or ‘IFN_VEC_WIDEN_MINUS_EVEN’ and ‘IFN_VEC_WIDEN_MINUS_ODD’, depending on what optabs the target implements. ‘IFN_VEC_WIDEN_MINUS_HI’ ‘IFN_VEC_WIDEN_MINUS_LO’ These internal functions represent widening vector subtraction of the high and low parts of the two input vectors, respectively. Their operands are vectors that contain the same number of elements (‘N’) of the same integral type. The high/low elements of the second vector are subtracted from the high/low elements of the first. The result is a vector that contains half as many elements, of an integral type whose size is twice as wide. In the case of ‘IFN_VEC_WIDEN_MINUS_HI’ the high ‘N/2’ elements of the second vector are subtracted from the high ‘N/2’ of the first to produce the vector of ‘N/2’ subtractions. In the case of ‘IFN_VEC_WIDEN_MINUS_LO’ the low ‘N/2’ elements of the second vector are subtracted from the low ‘N/2’ of the first to produce the vector of ‘N/2’ subtractions. ‘IFN_VEC_WIDEN_MINUS_EVEN’ ‘IFN_VEC_WIDEN_MINUS_ODD’ These internal functions represent widening vector subtraction of the even and odd parts of the two input vectors, respectively. Their operands are vectors that contain the same number of elements (‘N’) of the same integral type. The even/odd elements of the second vector are subtracted from the even/odd elements of the first. The result is a vector that contains half as many elements, of an integral type whose size is twice as wide. In the case of ‘IFN_VEC_WIDEN_MINUS_EVEN’ the even ‘N/2’ elements of the second vector are subtracted from the even ‘N/2’ of the first to produce the vector of ‘N/2’ subtractions. In the case of ‘IFN_VEC_WIDEN_MINUS_ODD’ the odd ‘N/2’ elements of the second vector are subtracted from the odd ‘N/2’ of the first to produce the vector of ‘N/2’ subtractions. ‘VEC_UNPACK_HI_EXPR’ ‘VEC_UNPACK_LO_EXPR’ These nodes represent unpacking of the high and low parts of the input vector, respectively. The single operand is a vector that contains ‘N’ elements of the same integral or floating point type. The result is a vector that contains half as many elements, of an integral or floating point type whose size is twice as wide. In the case of ‘VEC_UNPACK_HI_EXPR’ the high ‘N/2’ elements of the vector are extracted and widened (promoted). In the case of ‘VEC_UNPACK_LO_EXPR’ the low ‘N/2’ elements of the vector are extracted and widened (promoted). ‘VEC_UNPACK_FLOAT_HI_EXPR’ ‘VEC_UNPACK_FLOAT_LO_EXPR’ These nodes represent unpacking of the high and low parts of the input vector, where the values are converted from fixed point to floating point. The single operand is a vector that contains ‘N’ elements of the same integral type. The result is a vector that contains half as many elements of a floating point type whose size is twice as wide. In the case of ‘VEC_UNPACK_FLOAT_HI_EXPR’ the high ‘N/2’ elements of the vector are extracted, converted and widened. In the case of ‘VEC_UNPACK_FLOAT_LO_EXPR’ the low ‘N/2’ elements of the vector are extracted, converted and widened. ‘VEC_UNPACK_FIX_TRUNC_HI_EXPR’ ‘VEC_UNPACK_FIX_TRUNC_LO_EXPR’ These nodes represent unpacking of the high and low parts of the input vector, where the values are truncated from floating point to fixed point. The single operand is a vector that contains ‘N’ elements of the same floating point type. The result is a vector that contains half as many elements of an integral type whose size is twice as wide. In the case of ‘VEC_UNPACK_FIX_TRUNC_HI_EXPR’ the high ‘N/2’ elements of the vector are extracted and converted with truncation. In the case of ‘VEC_UNPACK_FIX_TRUNC_LO_EXPR’ the low ‘N/2’ elements of the vector are extracted and converted with truncation. ‘VEC_PACK_TRUNC_EXPR’ This node represents packing of truncated elements of the two input vectors into the output vector. Input operands are vectors that contain the same number of elements of the same integral or floating point type. The result is a vector that contains twice as many elements of an integral or floating point type whose size is half as wide. The elements of the two vectors are demoted and merged (concatenated) to form the output vector. ‘VEC_PACK_SAT_EXPR’ This node represents packing of elements of the two input vectors into the output vector using saturation. Input operands are vectors that contain the same number of elements of the same integral type. The result is a vector that contains twice as many elements of an integral type whose size is half as wide. The elements of the two vectors are demoted and merged (concatenated) to form the output vector. ‘VEC_PACK_FIX_TRUNC_EXPR’ This node represents packing of elements of the two input vectors into the output vector, where the values are converted from floating point to fixed point. Input operands are vectors that contain the same number of elements of a floating point type. The result is a vector that contains twice as many elements of an integral type whose size is half as wide. The elements of the two vectors are merged (concatenated) to form the output vector. ‘VEC_PACK_FLOAT_EXPR’ This node represents packing of elements of the two input vectors into the output vector, where the values are converted from fixed point to floating point. Input operands are vectors that contain the same number of elements of an integral type. The result is a vector that contains twice as many elements of floating point type whose size is half as wide. The elements of the two vectors are merged (concatenated) to form the output vector. ‘VEC_COND_EXPR’ These nodes represent ‘?:’ expressions. The three operands must be vectors of the same size and number of elements. The second and third operands must have the same type as the entire expression. The first operand is of signed integral vector type. If an element of the first operand evaluates to a zero value, the corresponding element of the result is taken from the third operand. If it evaluates to a minus one value, it is taken from the second operand. It should never evaluate to any other value currently, but optimizations should not rely on that property. In contrast with a ‘COND_EXPR’, all operands are always evaluated. ‘SAD_EXPR’ This node represents the Sum of Absolute Differences operation. The three operands must be vectors of integral types. The first and second operand must have the same type. The size of the vector element of the third operand must be at lease twice of the size of the vector element of the first and second one. The SAD is calculated between the first and second operands, added to the third operand, and returned.  File: gccint.info, Node: Statements, Next: Functions, Prev: Expression trees, Up: GENERIC 11.7 Statements =============== Most statements in GIMPLE are assignment statements, represented by ‘GIMPLE_ASSIGN’. No other C expressions can appear at statement level; a reference to a volatile object is converted into a ‘GIMPLE_ASSIGN’. There are also several varieties of complex statements. * Menu: * Basic Statements:: * Blocks:: * Statement Sequences:: * Empty Statements:: * Jumps:: * Cleanups:: * OpenMP:: * OpenACC::  File: gccint.info, Node: Basic Statements, Next: Blocks, Up: Statements 11.7.1 Basic Statements ----------------------- ‘ASM_EXPR’ Used to represent an inline assembly statement. For an inline assembly statement like: asm ("mov x, y"); The ‘ASM_STRING’ macro will return a ‘STRING_CST’ node for ‘"mov x, y"’. If the original statement made use of the extended-assembly syntax, then ‘ASM_OUTPUTS’, ‘ASM_INPUTS’, and ‘ASM_CLOBBERS’ will be the outputs, inputs, and clobbers for the statement, represented as ‘STRING_CST’ nodes. The extended-assembly syntax looks like: asm ("fsinx %1,%0" : "=f" (result) : "f" (angle)); The first string is the ‘ASM_STRING’, containing the instruction template. The next two strings are the output and inputs, respectively; this statement has no clobbers. As this example indicates, "plain" assembly statements are merely a special case of extended assembly statements; they have no cv-qualifiers, outputs, inputs, or clobbers. All of the strings will be ‘NUL’-terminated, and will contain no embedded ‘NUL’-characters. If the assembly statement is declared ‘volatile’, or if the statement was not an extended assembly statement, and is therefore implicitly volatile, then the predicate ‘ASM_VOLATILE_P’ will hold of the ‘ASM_EXPR’. ‘DECL_EXPR’ Used to represent a local declaration. The ‘DECL_EXPR_DECL’ macro can be used to obtain the entity declared. This declaration may be a ‘LABEL_DECL’, indicating that the label declared is a local label. (As an extension, GCC allows the declaration of labels with scope.) In C, this declaration may be a ‘FUNCTION_DECL’, indicating the use of the GCC nested function extension. For more information, *note Functions::. ‘LABEL_EXPR’ Used to represent a label. The ‘LABEL_DECL’ declared by this statement can be obtained with the ‘LABEL_EXPR_LABEL’ macro. The ‘IDENTIFIER_NODE’ giving the name of the label can be obtained from the ‘LABEL_DECL’ with ‘DECL_NAME’. ‘GOTO_EXPR’ Used to represent a ‘goto’ statement. The ‘GOTO_DESTINATION’ will usually be a ‘LABEL_DECL’. However, if the "computed goto" extension has been used, the ‘GOTO_DESTINATION’ will be an arbitrary expression indicating the destination. This expression will always have pointer type. ‘RETURN_EXPR’ Used to represent a ‘return’ statement. Operand 0 represents the value to return. It should either be the ‘RESULT_DECL’ for the containing function, or a ‘MODIFY_EXPR’ or ‘INIT_EXPR’ setting the function's ‘RESULT_DECL’. It will be ‘NULL_TREE’ if the statement was just return; ‘LOOP_EXPR’ These nodes represent "infinite" loops. The ‘LOOP_EXPR_BODY’ represents the body of the loop. It should be executed forever, unless an ‘EXIT_EXPR’ is encountered. ‘EXIT_EXPR’ These nodes represent conditional exits from the nearest enclosing ‘LOOP_EXPR’. The single operand is the condition; if it is nonzero, then the loop should be exited. An ‘EXIT_EXPR’ will only appear within a ‘LOOP_EXPR’. ‘SWITCH_EXPR’ Used to represent a ‘switch’ statement. The ‘SWITCH_COND’ is the expression on which the switch is occurring. The ‘SWITCH_BODY’ is the body of the switch statement. ‘SWITCH_ALL_CASES_P’ is true if the switch includes a default label or the case label ranges cover all possible values of the condition expression. Note that ‘TREE_TYPE’ for a ‘SWITCH_EXPR’ represents the original type of switch expression as given in the source, before any compiler conversions, instead of the type of the switch expression itself (which is not meaningful). ‘CASE_LABEL_EXPR’ Use to represent a ‘case’ label, range of ‘case’ labels, or a ‘default’ label. If ‘CASE_LOW’ is ‘NULL_TREE’, then this is a ‘default’ label. Otherwise, if ‘CASE_HIGH’ is ‘NULL_TREE’, then this is an ordinary ‘case’ label. In this case, ‘CASE_LOW’ is an expression giving the value of the label. Both ‘CASE_LOW’ and ‘CASE_HIGH’ are ‘INTEGER_CST’ nodes. These values will have the same type as the condition expression in the switch statement. Otherwise, if both ‘CASE_LOW’ and ‘CASE_HIGH’ are defined, the statement is a range of case labels. Such statements originate with the extension that allows users to write things of the form: case 2 ... 5: The first value will be ‘CASE_LOW’, while the second will be ‘CASE_HIGH’. ‘DEBUG_BEGIN_STMT’ Marks the beginning of a source statement, for purposes of debug information generation.  File: gccint.info, Node: Blocks, Next: Statement Sequences, Prev: Basic Statements, Up: Statements 11.7.2 Blocks ------------- Block scopes and the variables they declare in GENERIC are expressed using the ‘BIND_EXPR’ code, which in previous versions of GCC was primarily used for the C statement-expression extension. Variables in a block are collected into ‘BIND_EXPR_VARS’ in declaration order through their ‘TREE_CHAIN’ field. Any runtime initialization is moved out of ‘DECL_INITIAL’ and into a statement in the controlled block. When gimplifying from C or C++, this initialization replaces the ‘DECL_STMT’. These variables will never require cleanups. The scope of these variables is just the body Variable-length arrays (VLAs) complicate this process, as their size often refers to variables initialized earlier in the block and their initialization involves an explicit stack allocation. To handle this, we add an indirection and replace them with a pointer to stack space allocated by means of ‘alloca’. In most cases, we also arrange for this space to be reclaimed when the enclosing ‘BIND_EXPR’ is exited, the exception to this being when there is an explicit call to ‘alloca’ in the source code, in which case the stack is left depressed on exit of the ‘BIND_EXPR’. A C++ program will usually contain more ‘BIND_EXPR’s than there are syntactic blocks in the source code, since several C++ constructs have implicit scopes associated with them. On the other hand, although the C++ front end uses pseudo-scopes to handle cleanups for objects with destructors, these don't translate into the GIMPLE form; multiple declarations at the same level use the same ‘BIND_EXPR’.  File: gccint.info, Node: Statement Sequences, Next: Empty Statements, Prev: Blocks, Up: Statements 11.7.3 Statement Sequences -------------------------- Multiple statements at the same nesting level are collected into a ‘STATEMENT_LIST’. Statement lists are modified and traversed using the interface in ‘tree-iterator.h’.  File: gccint.info, Node: Empty Statements, Next: Jumps, Prev: Statement Sequences, Up: Statements 11.7.4 Empty Statements ----------------------- Whenever possible, statements with no effect are discarded. But if they are nested within another construct which cannot be discarded for some reason, they are instead replaced with an empty statement, generated by ‘build_empty_stmt’. Initially, all empty statements were shared, after the pattern of the Java front end, but this caused a lot of trouble in practice. An empty statement is represented as ‘(void)0’.  File: gccint.info, Node: Jumps, Next: Cleanups, Prev: Empty Statements, Up: Statements 11.7.5 Jumps ------------ Other jumps are expressed by either ‘GOTO_EXPR’ or ‘RETURN_EXPR’. The operand of a ‘GOTO_EXPR’ must be either a label or a variable containing the address to jump to. The operand of a ‘RETURN_EXPR’ is either ‘NULL_TREE’, ‘RESULT_DECL’, or a ‘MODIFY_EXPR’ which sets the return value. It would be nice to move the ‘MODIFY_EXPR’ into a separate statement, but the special return semantics in ‘expand_return’ make that difficult. It may still happen in the future, perhaps by moving most of that logic into ‘expand_assignment’.  File: gccint.info, Node: Cleanups, Next: OpenMP, Prev: Jumps, Up: Statements 11.7.6 Cleanups --------------- Destructors for local C++ objects and similar dynamic cleanups are represented in GIMPLE by a ‘TRY_FINALLY_EXPR’. ‘TRY_FINALLY_EXPR’ has two operands, both of which are a sequence of statements to execute. The first sequence is executed. When it completes the second sequence is executed. The first sequence may complete in the following ways: 1. Execute the last statement in the sequence and fall off the end. 2. Execute a goto statement (‘GOTO_EXPR’) to an ordinary label outside the sequence. 3. Execute a return statement (‘RETURN_EXPR’). 4. Throw an exception. This is currently not explicitly represented in GIMPLE. The second sequence is not executed if the first sequence completes by calling ‘setjmp’ or ‘exit’ or any other function that does not return. The second sequence is also not executed if the first sequence completes via a non-local goto or a computed goto (in general the compiler does not know whether such a goto statement exits the first sequence or not, so we assume that it doesn't). After the second sequence is executed, if it completes normally by falling off the end, execution continues wherever the first sequence would have continued, by falling off the end, or doing a goto, etc. If the second sequence is an ‘EH_ELSE_EXPR’ selector, then the sequence in its first operand is used when the first sequence completes normally, and that in its second operand is used for exceptional cleanups, i.e., when an exception propagates out of the first sequence. ‘TRY_FINALLY_EXPR’ complicates the flow graph, since the cleanup needs to appear on every edge out of the controlled block; this reduces the freedom to move code across these edges. Therefore, the EH lowering pass which runs before most of the optimization passes eliminates these expressions by explicitly adding the cleanup to each edge. Rethrowing the exception is represented using ‘RESX_EXPR’.  File: gccint.info, Node: OpenMP, Next: OpenACC, Prev: Cleanups, Up: Statements 11.7.7 OpenMP ------------- All the statements starting with ‘OMP_’ represent directives and clauses used by the OpenMP API . ‘OMP_PARALLEL’ Represents ‘#pragma omp parallel [clause1 ... clauseN]’. It has four operands: Operand ‘OMP_PARALLEL_BODY’ is valid while in GENERIC and High GIMPLE forms. It contains the body of code to be executed by all the threads. During GIMPLE lowering, this operand becomes ‘NULL’ and the body is emitted linearly after ‘OMP_PARALLEL’. Operand ‘OMP_PARALLEL_CLAUSES’ is the list of clauses associated with the directive. Operand ‘OMP_PARALLEL_FN’ is created by ‘pass_lower_omp’, it contains the ‘FUNCTION_DECL’ for the function that will contain the body of the parallel region. Operand ‘OMP_PARALLEL_DATA_ARG’ is also created by ‘pass_lower_omp’. If there are shared variables to be communicated to the children threads, this operand will contain the ‘VAR_DECL’ that contains all the shared values and variables. ‘OMP_FOR’ ‘OMP_SIMD’ ‘OMP_DISTRIBUTE’ ‘OMP_TASKLOOP’ ‘OMP_LOOP’ Represents ‘#pragma omp for [clause1 ... clauseN]’ and related loop constructs (respectively). A single ‘OMP_FOR’ node represents an entire nest of collapsed loops; as noted below, some of its arguments are vectors of length equal to the collapse depth, and the corresponding elements holding data specific to a particular loop in the nest. These vectors are numbered from the outside in so that the outermost loop is element 0. These constructs have seven operands: Operand ‘OMP_FOR_BODY’ contains the loop body. Operand ‘OMP_FOR_CLAUSES’ is the list of clauses associated with the directive. Operand ‘OMP_FOR_INIT’ is a vector containing iteration variable initializations of the form ‘VAR = N1’. Operand ‘OMP_FOR_COND’ is vector containing loop conditional expressions of the form ‘VAR {<,>,<=,>=,!=} N2’. Operand ‘OMP_FOR_INCR’ is a vector containing loop index increment expressions of the form ‘VAR {+=,-=} INCR’. Operand ‘OMP_FOR_PRE_BODY’ contains side effect code from operands ‘OMP_FOR_INIT’, ‘OMP_FOR_COND’ and ‘OMP_FOR_INCR’. These side effects are part of the ‘OMP_FOR’ block but must be evaluated before the start of loop body. ‘OMP_FOR_PRE_BODY’ specifically includes ‘DECL_EXPR’s for iteration variables that are declared in the nested ‘for’ loops. Note this field is not a vector; it may be null, but otherwise is usually a statement list collecting the side effect code from all the collapsed loops. Operand ‘OMP_FOR_ORIG_DECLS’ holds ‘VAR_DECLS’ for the original user-specified iterator variables in the source code. In some cases, like C++ class iterators or range ‘for’ with decomposition, the ‘for’ loop is rewritten by the front end to use a temporary iteration variable. The purpose of this field is to make the original variables available to the gimplifier so it can adjust their data-sharing attributes and diagnose errors. ‘OMP_FOR_ORIG_DECLS’ is a vector field, with each element holding a list of ‘VAR_DECLS’ for the corresponding collapse level. The loop index variable ‘VAR’ must be an integer variable, which is implicitly private to each thread. For rectangular loops, the bounds ‘N1’ and ‘N2’ and the increment expression ‘INCR’ are required to be loop-invariant integer expressions that are evaluated without any synchronization. The evaluation order, frequency of evaluation and side effects are otherwise unspecified by the standard. For non-rectangular loops, in which the bounds of an inner loop depend on the index of an outer loop, the bit ‘OMP_FOR_NON_RECTANGULAR’ must be set. In this case ‘N1’ and ‘N2’ are not ordinary expressions, but instead a ‘TREE_VEC’ with three elements: the ‘DECL’ for the outer loop variable, a multiplication factor, and an offset. ‘OMP_SECTIONS’ Represents ‘#pragma omp sections [clause1 ... clauseN]’. Operand ‘OMP_SECTIONS_BODY’ contains the sections body, which in turn contains a set of ‘OMP_SECTION’ nodes for each of the concurrent sections delimited by ‘#pragma omp section’. Operand ‘OMP_SECTIONS_CLAUSES’ is the list of clauses associated with the directive. ‘OMP_SECTION’ Section delimiter for ‘OMP_SECTIONS’. ‘OMP_SINGLE’ Represents ‘#pragma omp single’. Operand ‘OMP_SINGLE_BODY’ contains the body of code to be executed by a single thread. Operand ‘OMP_SINGLE_CLAUSES’ is the list of clauses associated with the directive. ‘OMP_MASTER’ Represents ‘#pragma omp master’. Operand ‘OMP_MASTER_BODY’ contains the body of code to be executed by the master thread. ‘OMP_ORDERED’ Represents ‘#pragma omp ordered’. Operand ‘OMP_ORDERED_BODY’ contains the body of code to be executed in the sequential order dictated by the loop index variable. ‘OMP_CRITICAL’ Represents ‘#pragma omp critical [name]’. Operand ‘OMP_CRITICAL_BODY’ is the critical section. Operand ‘OMP_CRITICAL_NAME’ is an optional identifier to label the critical section. ‘OMP_RETURN’ This does not represent any OpenMP directive, it is an artificial marker to indicate the end of the body of an OpenMP. It is used by the flow graph (‘tree-cfg.cc’) and OpenMP region building code (‘omp-low.cc’). ‘OMP_CONTINUE’ Similarly, this instruction does not represent an OpenMP directive, it is used by ‘OMP_FOR’ (and similar codes) as well as ‘OMP_SECTIONS’ to mark the place where the code needs to loop to the next iteration, or the next section, respectively. In some cases, ‘OMP_CONTINUE’ is placed right before ‘OMP_RETURN’. But if there are cleanups that need to occur right after the looping body, it will be emitted between ‘OMP_CONTINUE’ and ‘OMP_RETURN’. ‘OMP_STRUCTURED_BLOCK’ This is another statement that doesn't correspond to an OpenMP directive. It is used to mark sections of code in another directive that must be structured block sequences, in particular for sequences of intervening code in the body of an ‘OMP_FOR’. It is not necessary to use this when the entire body of a directive is required to be a structured block sequence, since that is implicit in the representation of the corresponding node. This tree node is used only to allow error checking transfers of control in/out of the structured block sequence after gimplification. It has a single operand (‘OMP_STRUCTURED_BLOCK_BODY’) that is the code within the structured block sequence. ‘OMP_ATOMIC’ Represents ‘#pragma omp atomic’. Operand 0 is the address at which the atomic operation is to be performed. Operand 1 is the expression to evaluate. The gimplifier tries three alternative code generation strategies. Whenever possible, an atomic update built-in is used. If that fails, a compare-and-swap loop is attempted. If that also fails, a regular critical section around the expression is used. ‘OMP_CLAUSE’ Represents clauses associated with one of the ‘OMP_’ directives. Clauses are represented by separate subcodes defined in ‘tree.h’. Clauses codes can be one of: ‘OMP_CLAUSE_PRIVATE’, ‘OMP_CLAUSE_SHARED’, ‘OMP_CLAUSE_FIRSTPRIVATE’, ‘OMP_CLAUSE_LASTPRIVATE’, ‘OMP_CLAUSE_COPYIN’, ‘OMP_CLAUSE_COPYPRIVATE’, ‘OMP_CLAUSE_IF’, ‘OMP_CLAUSE_NUM_THREADS’, ‘OMP_CLAUSE_SCHEDULE’, ‘OMP_CLAUSE_NOWAIT’, ‘OMP_CLAUSE_ORDERED’, ‘OMP_CLAUSE_DEFAULT’, ‘OMP_CLAUSE_REDUCTION’, ‘OMP_CLAUSE_COLLAPSE’, ‘OMP_CLAUSE_UNTIED’, ‘OMP_CLAUSE_FINAL’, and ‘OMP_CLAUSE_MERGEABLE’. Each code represents the corresponding OpenMP clause. Clauses associated with the same directive are chained together via ‘OMP_CLAUSE_CHAIN’. Those clauses that accept a list of variables are restricted to exactly one, accessed with ‘OMP_CLAUSE_VAR’. Therefore, multiple variables under the same clause ‘C’ need to be represented as multiple ‘C’ clauses chained together. This facilitates adding new clauses during compilation.  File: gccint.info, Node: OpenACC, Prev: OpenMP, Up: Statements 11.7.8 OpenACC -------------- All the statements starting with ‘OACC_’ represent directives and clauses used by the OpenACC API . ‘OACC_CACHE’ Represents ‘#pragma acc cache (var ...)’. ‘OACC_DATA’ Represents ‘#pragma acc data [clause1 ... clauseN]’. ‘OACC_DECLARE’ Represents ‘#pragma acc declare [clause1 ... clauseN]’. ‘OACC_ENTER_DATA’ Represents ‘#pragma acc enter data [clause1 ... clauseN]’. ‘OACC_EXIT_DATA’ Represents ‘#pragma acc exit data [clause1 ... clauseN]’. ‘OACC_HOST_DATA’ Represents ‘#pragma acc host_data [clause1 ... clauseN]’. ‘OACC_KERNELS’ Represents ‘#pragma acc kernels [clause1 ... clauseN]’. ‘OACC_LOOP’ Represents ‘#pragma acc loop [clause1 ... clauseN]’. See the description of the ‘OMP_FOR’ code. ‘OACC_PARALLEL’ Represents ‘#pragma acc parallel [clause1 ... clauseN]’. ‘OACC_SERIAL’ Represents ‘#pragma acc serial [clause1 ... clauseN]’. ‘OACC_UPDATE’ Represents ‘#pragma acc update [clause1 ... clauseN]’.  File: gccint.info, Node: Functions, Next: Language-dependent trees, Prev: Statements, Up: GENERIC 11.8 Functions ============== A function is represented by a ‘FUNCTION_DECL’ node. It stores the basic pieces of the function such as body, parameters, and return type as well as information on the surrounding context, visibility, and linkage. * Menu: * Function Basics:: Function names, body, and parameters. * Function Properties:: Context, linkage, etc.  File: gccint.info, Node: Function Basics, Next: Function Properties, Up: Functions 11.8.1 Function Basics ---------------------- A function has four core parts: the name, the parameters, the result, and the body. The following macros and functions access these parts of a ‘FUNCTION_DECL’ as well as other basic features: ‘DECL_NAME’ This macro returns the unqualified name of the function, as an ‘IDENTIFIER_NODE’. For an instantiation of a function template, the ‘DECL_NAME’ is the unqualified name of the template, not something like ‘f’. The value of ‘DECL_NAME’ is undefined when used on a constructor, destructor, overloaded operator, or type-conversion operator, or any function that is implicitly generated by the compiler. See below for macros that can be used to distinguish these cases. ‘DECL_ASSEMBLER_NAME’ This macro returns the mangled name of the function, also an ‘IDENTIFIER_NODE’. This name does not contain leading underscores on systems that prefix all identifiers with underscores. The mangled name is computed in the same way on all platforms; if special processing is required to deal with the object file format used on a particular platform, it is the responsibility of the back end to perform those modifications. (Of course, the back end should not modify ‘DECL_ASSEMBLER_NAME’ itself.) Using ‘DECL_ASSEMBLER_NAME’ will cause additional memory to be allocated (for the mangled name of the entity) so it should be used only when emitting assembly code. It should not be used within the optimizers to determine whether or not two declarations are the same, even though some of the existing optimizers do use it in that way. These uses will be removed over time. ‘DECL_ARGUMENTS’ This macro returns the ‘PARM_DECL’ for the first argument to the function. Subsequent ‘PARM_DECL’ nodes can be obtained by following the ‘TREE_CHAIN’ links. ‘DECL_RESULT’ This macro returns the ‘RESULT_DECL’ for the function. ‘DECL_SAVED_TREE’ This macro returns the complete body of the function. ‘TREE_TYPE’ This macro returns the ‘FUNCTION_TYPE’ or ‘METHOD_TYPE’ for the function. ‘DECL_INITIAL’ A function that has a definition in the current translation unit will have a non-‘NULL’ ‘DECL_INITIAL’. However, back ends should not make use of the particular value given by ‘DECL_INITIAL’. It should contain a tree of ‘BLOCK’ nodes that mirrors the scopes that variables are bound in the function. Each block contains a list of decls declared in a basic block, a pointer to a chain of blocks at the next lower scope level, then a pointer to the next block at the same level and a backpointer to the parent ‘BLOCK’ or ‘FUNCTION_DECL’. So given a function as follows: void foo() { int a; { int b; } int c; } you would get the following: tree foo = FUNCTION_DECL; tree decl_a = VAR_DECL; tree decl_b = VAR_DECL; tree decl_c = VAR_DECL; tree block_a = BLOCK; tree block_b = BLOCK; tree block_c = BLOCK; BLOCK_VARS(block_a) = decl_a; BLOCK_SUBBLOCKS(block_a) = block_b; BLOCK_CHAIN(block_a) = block_c; BLOCK_SUPERCONTEXT(block_a) = foo; BLOCK_VARS(block_b) = decl_b; BLOCK_SUPERCONTEXT(block_b) = block_a; BLOCK_VARS(block_c) = decl_c; BLOCK_SUPERCONTEXT(block_c) = foo; DECL_INITIAL(foo) = block_a;  File: gccint.info, Node: Function Properties, Prev: Function Basics, Up: Functions 11.8.2 Function Properties -------------------------- To determine the scope of a function, you can use the ‘DECL_CONTEXT’ macro. This macro will return the class (either a ‘RECORD_TYPE’ or a ‘UNION_TYPE’) or namespace (a ‘NAMESPACE_DECL’) of which the function is a member. For a virtual function, this macro returns the class in which the function was actually defined, not the base class in which the virtual declaration occurred. In C, the ‘DECL_CONTEXT’ for a function maybe another function. This representation indicates that the GNU nested function extension is in use. For details on the semantics of nested functions, see the GCC Manual. The nested function can refer to local variables in its containing function. Such references are not explicitly marked in the tree structure; back ends must look at the ‘DECL_CONTEXT’ for the referenced ‘VAR_DECL’. If the ‘DECL_CONTEXT’ for the referenced ‘VAR_DECL’ is not the same as the function currently being processed, and neither ‘DECL_EXTERNAL’ nor ‘TREE_STATIC’ hold, then the reference is to a local variable in a containing function, and the back end must take appropriate action. ‘DECL_EXTERNAL’ This predicate holds if the function is undefined. ‘TREE_PUBLIC’ This predicate holds if the function has external linkage. ‘TREE_STATIC’ This predicate holds if the function has been defined. ‘TREE_THIS_VOLATILE’ This predicate holds if the function does not return normally. ‘TREE_READONLY’ This predicate holds if the function can only read its arguments. ‘DECL_PURE_P’ This predicate holds if the function can only read its arguments, but may also read global memory. ‘DECL_VIRTUAL_P’ This predicate holds if the function is virtual. ‘DECL_ARTIFICIAL’ This macro holds if the function was implicitly generated by the compiler, rather than explicitly declared. In addition to implicitly generated class member functions, this macro holds for the special functions created to implement static initialization and destruction, to compute run-time type information, and so forth. ‘DECL_FUNCTION_SPECIFIC_TARGET’ This macro returns a tree node that holds the target options that are to be used to compile this particular function or ‘NULL_TREE’ if the function is to be compiled with the target options specified on the command line. ‘DECL_FUNCTION_SPECIFIC_OPTIMIZATION’ This macro returns a tree node that holds the optimization options that are to be used to compile this particular function or ‘NULL_TREE’ if the function is to be compiled with the optimization options specified on the command line.  File: gccint.info, Node: Language-dependent trees, Next: C and C++ Trees, Prev: Functions, Up: GENERIC 11.9 Language-dependent trees ============================= Front ends may wish to keep some state associated with various GENERIC trees while parsing. To support this, trees provide a set of flags that may be used by the front end. They are accessed using ‘TREE_LANG_FLAG_n’ where ‘n’ is currently 0 through 6. If necessary, a front end can use some language-dependent tree codes in its GENERIC representation, so long as it provides a hook for converting them to GIMPLE and doesn't expect them to work with any (hypothetical) optimizers that run before the conversion to GIMPLE. The intermediate representation used while parsing C and C++ looks very little like GENERIC, but the C and C++ gimplifier hooks are perfectly happy to take it as input and spit out GIMPLE.  File: gccint.info, Node: C and C++ Trees, Prev: Language-dependent trees, Up: GENERIC 11.10 C and C++ Trees ===================== This section documents the internal representation used by GCC to represent C and C++ source programs. When presented with a C or C++ source program, GCC parses the program, performs semantic analysis (including the generation of error messages), and then produces the internal representation described here. This representation contains a complete representation for the entire translation unit provided as input to the front end. This representation is then typically processed by a code-generator in order to produce machine code, but could also be used in the creation of source browsers, intelligent editors, automatic documentation generators, interpreters, and any other programs needing the ability to process C or C++ code. This section explains the internal representation. In particular, it documents the internal representation for C and C++ source constructs, and the macros, functions, and variables that can be used to access these constructs. The C++ representation is largely a superset of the representation used in the C front end. There is only one construct used in C that does not appear in the C++ front end and that is the GNU "nested function" extension. Many of the macros documented here do not apply in C because the corresponding language constructs do not appear in C. The C and C++ front ends generate a mix of GENERIC trees and ones specific to C and C++. These language-specific trees are higher-level constructs than the ones in GENERIC to make the parser's job easier. This section describes those trees that aren't part of GENERIC as well as aspects of GENERIC trees that are treated in a language-specific manner. If you are developing a "back end", be it is a code-generator or some other tool, that uses this representation, you may occasionally find that you need to ask questions not easily answered by the functions and macros available here. If that situation occurs, it is quite likely that GCC already supports the functionality you desire, but that the interface is simply not documented here. In that case, you should ask the GCC maintainers (via mail to ) about documenting the functionality you require. Similarly, if you find yourself writing functions that do not deal directly with your back end, but instead might be useful to other people using the GCC front end, you should submit your patches for inclusion in GCC. * Menu: * Types for C++:: Fundamental and aggregate types. * Namespaces:: Namespaces. * Classes:: Classes. * Functions for C++:: Overloading and accessors for C++. * Statements for C and C++:: Statements specific to C and C++. * C++ Expressions:: From ‘typeid’ to ‘throw’.  File: gccint.info, Node: Types for C++, Next: Namespaces, Up: C and C++ Trees 11.10.1 Types for C++ --------------------- In C++, an array type is not qualified; rather the type of the array elements is qualified. This situation is reflected in the intermediate representation. The macros described here will always examine the qualification of the underlying element type when applied to an array type. (If the element type is itself an array, then the recursion continues until a non-array type is found, and the qualification of this type is examined.) So, for example, ‘CP_TYPE_CONST_P’ will hold of the type ‘const int ()[7]’, denoting an array of seven ‘int’s. The following functions and macros deal with cv-qualification of types: ‘cp_type_quals’ This function returns the set of type qualifiers applied to this type. This value is ‘TYPE_UNQUALIFIED’ if no qualifiers have been applied. The ‘TYPE_QUAL_CONST’ bit is set if the type is ‘const’-qualified. The ‘TYPE_QUAL_VOLATILE’ bit is set if the type is ‘volatile’-qualified. The ‘TYPE_QUAL_RESTRICT’ bit is set if the type is ‘restrict’-qualified. ‘CP_TYPE_CONST_P’ This macro holds if the type is ‘const’-qualified. ‘CP_TYPE_VOLATILE_P’ This macro holds if the type is ‘volatile’-qualified. ‘CP_TYPE_RESTRICT_P’ This macro holds if the type is ‘restrict’-qualified. ‘CP_TYPE_CONST_NON_VOLATILE_P’ This predicate holds for a type that is ‘const’-qualified, but _not_ ‘volatile’-qualified; other cv-qualifiers are ignored as well: only the ‘const’-ness is tested. A few other macros and functions are usable with all types: ‘TYPE_SIZE’ The number of bits required to represent the type, represented as an ‘INTEGER_CST’. For an incomplete type, ‘TYPE_SIZE’ will be ‘NULL_TREE’. ‘TYPE_ALIGN’ The alignment of the type, in bits, represented as an ‘int’. ‘TYPE_NAME’ This macro returns a declaration (in the form of a ‘TYPE_DECL’) for the type. (Note this macro does _not_ return an ‘IDENTIFIER_NODE’, as you might expect, given its name!) You can look at the ‘DECL_NAME’ of the ‘TYPE_DECL’ to obtain the actual name of the type. The ‘TYPE_NAME’ will be ‘NULL_TREE’ for a type that is not a built-in type, the result of a typedef, or a named class type. ‘CP_INTEGRAL_TYPE’ This predicate holds if the type is an integral type. Notice that in C++, enumerations are _not_ integral types. ‘ARITHMETIC_TYPE_P’ This predicate holds if the type is an integral type (in the C++ sense) or a floating point type. ‘CLASS_TYPE_P’ This predicate holds for a class-type. ‘TYPE_BUILT_IN’ This predicate holds for a built-in type. ‘TYPE_PTRDATAMEM_P’ This predicate holds if the type is a pointer to data member. ‘TYPE_PTR_P’ This predicate holds if the type is a pointer type, and the pointee is not a data member. ‘TYPE_PTRFN_P’ This predicate holds for a pointer to function type. ‘TYPE_PTROB_P’ This predicate holds for a pointer to object type. Note however that it does not hold for the generic pointer to object type ‘void *’. You may use ‘TYPE_PTROBV_P’ to test for a pointer to object type as well as ‘void *’. The table below describes types specific to C and C++ as well as language-dependent info about GENERIC types. ‘POINTER_TYPE’ Used to represent pointer types, and pointer to data member types. If ‘TREE_TYPE’ is a pointer to data member type, then ‘TYPE_PTRDATAMEM_P’ will hold. For a pointer to data member type of the form ‘T X::*’, ‘TYPE_PTRMEM_CLASS_TYPE’ will be the type ‘X’, while ‘TYPE_PTRMEM_POINTED_TO_TYPE’ will be the type ‘T’. ‘RECORD_TYPE’ Used to represent ‘struct’ and ‘class’ types in C and C++. If ‘TYPE_PTRMEMFUNC_P’ holds, then this type is a pointer-to-member type. In that case, the ‘TYPE_PTRMEMFUNC_FN_TYPE’ is a ‘POINTER_TYPE’ pointing to a ‘METHOD_TYPE’. The ‘METHOD_TYPE’ is the type of a function pointed to by the pointer-to-member function. If ‘TYPE_PTRMEMFUNC_P’ does not hold, this type is a class type. For more information, *note Classes::. ‘UNKNOWN_TYPE’ This node is used to represent a type the knowledge of which is insufficient for a sound processing. ‘TYPENAME_TYPE’ Used to represent a construct of the form ‘typename T::A’. The ‘TYPE_CONTEXT’ is ‘T’; the ‘TYPE_NAME’ is an ‘IDENTIFIER_NODE’ for ‘A’. If the type is specified via a template-id, then ‘TYPENAME_TYPE_FULLNAME’ yields a ‘TEMPLATE_ID_EXPR’. The ‘TREE_TYPE’ is non-‘NULL’ if the node is implicitly generated in support for the implicit typename extension; in which case the ‘TREE_TYPE’ is a type node for the base-class. ‘TYPEOF_TYPE’ Used to represent the ‘__typeof__’ extension. The ‘TYPE_FIELDS’ is the expression the type of which is being represented.  File: gccint.info, Node: Namespaces, Next: Classes, Prev: Types for C++, Up: C and C++ Trees 11.10.2 Namespaces ------------------ The root of the entire intermediate representation is the variable ‘global_namespace’. This is the namespace specified with ‘::’ in C++ source code. All other namespaces, types, variables, functions, and so forth can be found starting with this namespace. However, except for the fact that it is distinguished as the root of the representation, the global namespace is no different from any other namespace. Thus, in what follows, we describe namespaces generally, rather than the global namespace in particular. A namespace is represented by a ‘NAMESPACE_DECL’ node. The following macros and functions can be used on a ‘NAMESPACE_DECL’: ‘DECL_NAME’ This macro is used to obtain the ‘IDENTIFIER_NODE’ corresponding to the unqualified name of the name of the namespace (*note Identifiers::). The name of the global namespace is ‘::’, even though in C++ the global namespace is unnamed. However, you should use comparison with ‘global_namespace’, rather than ‘DECL_NAME’ to determine whether or not a namespace is the global one. An unnamed namespace will have a ‘DECL_NAME’ equal to ‘anonymous_namespace_name’. Within a single translation unit, all unnamed namespaces will have the same name. ‘DECL_CONTEXT’ This macro returns the enclosing namespace. The ‘DECL_CONTEXT’ for the ‘global_namespace’ is ‘NULL_TREE’. ‘DECL_NAMESPACE_ALIAS’ If this declaration is for a namespace alias, then ‘DECL_NAMESPACE_ALIAS’ is the namespace for which this one is an alias. Do not attempt to use ‘cp_namespace_decls’ for a namespace which is an alias. Instead, follow ‘DECL_NAMESPACE_ALIAS’ links until you reach an ordinary, non-alias, namespace, and call ‘cp_namespace_decls’ there. ‘DECL_NAMESPACE_STD_P’ This predicate holds if the namespace is the special ‘::std’ namespace. ‘cp_namespace_decls’ This function will return the declarations contained in the namespace, including types, overloaded functions, other namespaces, and so forth. If there are no declarations, this function will return ‘NULL_TREE’. The declarations are connected through their ‘TREE_CHAIN’ fields. Although most entries on this list will be declarations, ‘TREE_LIST’ nodes may also appear. In this case, the ‘TREE_VALUE’ will be an ‘OVERLOAD’. The value of the ‘TREE_PURPOSE’ is unspecified; back ends should ignore this value. As with the other kinds of declarations returned by ‘cp_namespace_decls’, the ‘TREE_CHAIN’ will point to the next declaration in this list. For more information on the kinds of declarations that can occur on this list, *Note Declarations::. Some declarations will not appear on this list. In particular, no ‘FIELD_DECL’, ‘LABEL_DECL’, or ‘PARM_DECL’ nodes will appear here. This function cannot be used with namespaces that have ‘DECL_NAMESPACE_ALIAS’ set.  File: gccint.info, Node: Classes, Next: Functions for C++, Prev: Namespaces, Up: C and C++ Trees 11.10.3 Classes --------------- Besides namespaces, the other high-level scoping construct in C++ is the class. (Throughout this manual the term “class” is used to mean the types referred to in the ANSI/ISO C++ Standard as classes; these include types defined with the ‘class’, ‘struct’, and ‘union’ keywords.) A class type is represented by either a ‘RECORD_TYPE’ or a ‘UNION_TYPE’. A class declared with the ‘union’ tag is represented by a ‘UNION_TYPE’, while classes declared with either the ‘struct’ or the ‘class’ tag are represented by ‘RECORD_TYPE’s. You can use the ‘CLASSTYPE_DECLARED_CLASS’ macro to discern whether or not a particular type is a ‘class’ as opposed to a ‘struct’. This macro will be true only for classes declared with the ‘class’ tag. Almost all members are available on the ‘TYPE_FIELDS’ list. Given one member, the next can be found by following the ‘TREE_CHAIN’. You should not depend in any way on the order in which fields appear on this list. All nodes on this list will be ‘DECL’ nodes. A ‘FIELD_DECL’ is used to represent a non-static data member, a ‘VAR_DECL’ is used to represent a static data member, and a ‘TYPE_DECL’ is used to represent a type. Note that the ‘CONST_DECL’ for an enumeration constant will appear on this list, if the enumeration type was declared in the class. (Of course, the ‘TYPE_DECL’ for the enumeration type will appear here as well.) There are no entries for base classes on this list. In particular, there is no ‘FIELD_DECL’ for the "base-class portion" of an object. If a function member is overloaded, each of the overloaded functions appears; no ‘OVERLOAD’ nodes appear on the ‘TYPE_FIELDS’ list. Implicitly declared functions (including default constructors, copy constructors, assignment operators, and destructors) will appear on this list as well. The ‘TYPE_VFIELD’ is a compiler-generated field used to point to virtual function tables. It may or may not appear on the ‘TYPE_FIELDS’ list. However, back ends should handle the ‘TYPE_VFIELD’ just like all the entries on the ‘TYPE_FIELDS’ list. Every class has an associated “binfo”, which can be obtained with ‘TYPE_BINFO’. Binfos are used to represent base-classes. The binfo given by ‘TYPE_BINFO’ is the degenerate case, whereby every class is considered to be its own base-class. The base binfos for a particular binfo are held in a vector, whose length is obtained with ‘BINFO_N_BASE_BINFOS’. The base binfos themselves are obtained with ‘BINFO_BASE_BINFO’ and ‘BINFO_BASE_ITERATE’. To add a new binfo, use ‘BINFO_BASE_APPEND’. The vector of base binfos can be obtained with ‘BINFO_BASE_BINFOS’, but normally you do not need to use that. The class type associated with a binfo is given by ‘BINFO_TYPE’. It is not always the case that ‘BINFO_TYPE (TYPE_BINFO (x))’, because of typedefs and qualified types. Neither is it the case that ‘TYPE_BINFO (BINFO_TYPE (y))’ is the same binfo as ‘y’. The reason is that if ‘y’ is a binfo representing a base-class ‘B’ of a derived class ‘D’, then ‘BINFO_TYPE (y)’ will be ‘B’, and ‘TYPE_BINFO (BINFO_TYPE (y))’ will be ‘B’ as its own base-class, rather than as a base-class of ‘D’. The access to a base type can be found with ‘BINFO_BASE_ACCESS’. This will produce ‘access_public_node’, ‘access_private_node’ or ‘access_protected_node’. If bases are always public, ‘BINFO_BASE_ACCESSES’ may be ‘NULL’. ‘BINFO_VIRTUAL_P’ is used to specify whether the binfo is inherited virtually or not. The other flags, ‘BINFO_FLAG_0’ to ‘BINFO_FLAG_6’, can be used for language specific use. The following macros can be used on a tree node representing a class-type. ‘LOCAL_CLASS_P’ This predicate holds if the class is local class _i.e._ declared inside a function body. ‘TYPE_POLYMORPHIC_P’ This predicate holds if the class has at least one virtual function (declared or inherited). ‘TYPE_HAS_DEFAULT_CONSTRUCTOR’ This predicate holds whenever its argument represents a class-type with default constructor. ‘CLASSTYPE_HAS_MUTABLE’ ‘TYPE_HAS_MUTABLE_P’ These predicates hold for a class-type having a mutable data member. ‘CLASSTYPE_NON_POD_P’ This predicate holds only for class-types that are not PODs. ‘TYPE_HAS_NEW_OPERATOR’ This predicate holds for a class-type that defines ‘operator new’. ‘TYPE_HAS_ARRAY_NEW_OPERATOR’ This predicate holds for a class-type for which ‘operator new[]’ is defined. ‘TYPE_OVERLOADS_CALL_EXPR’ This predicate holds for class-type for which the function call ‘operator()’ is overloaded. ‘TYPE_OVERLOADS_ARRAY_REF’ This predicate holds for a class-type that overloads ‘operator[]’ ‘TYPE_OVERLOADS_ARROW’ This predicate holds for a class-type for which ‘operator->’ is overloaded.  File: gccint.info, Node: Functions for C++, Next: Statements for C and C++, Prev: Classes, Up: C and C++ Trees 11.10.4 Functions for C++ ------------------------- A function is represented by a ‘FUNCTION_DECL’ node. A set of overloaded functions is sometimes represented by an ‘OVERLOAD’ node. An ‘OVERLOAD’ node is not a declaration, so none of the ‘DECL_’ macros should be used on an ‘OVERLOAD’. An ‘OVERLOAD’ node is similar to a ‘TREE_LIST’. Use ‘OVL_CURRENT’ to get the function associated with an ‘OVERLOAD’ node; use ‘OVL_NEXT’ to get the next ‘OVERLOAD’ node in the list of overloaded functions. The macros ‘OVL_CURRENT’ and ‘OVL_NEXT’ are actually polymorphic; you can use them to work with ‘FUNCTION_DECL’ nodes as well as with overloads. In the case of a ‘FUNCTION_DECL’, ‘OVL_CURRENT’ will always return the function itself, and ‘OVL_NEXT’ will always be ‘NULL_TREE’. To determine the scope of a function, you can use the ‘DECL_CONTEXT’ macro. This macro will return the class (either a ‘RECORD_TYPE’ or a ‘UNION_TYPE’) or namespace (a ‘NAMESPACE_DECL’) of which the function is a member. For a virtual function, this macro returns the class in which the function was actually defined, not the base class in which the virtual declaration occurred. If a friend function is defined in a class scope, the ‘DECL_FRIEND_CONTEXT’ macro can be used to determine the class in which it was defined. For example, in class C { friend void f() {} }; the ‘DECL_CONTEXT’ for ‘f’ will be the ‘global_namespace’, but the ‘DECL_FRIEND_CONTEXT’ will be the ‘RECORD_TYPE’ for ‘C’. The following macros and functions can be used on a ‘FUNCTION_DECL’: ‘DECL_MAIN_P’ This predicate holds for a function that is the program entry point ‘::code’. ‘DECL_LOCAL_FUNCTION_P’ This predicate holds if the function was declared at block scope, even though it has a global scope. ‘DECL_ANTICIPATED’ This predicate holds if the function is a built-in function but its prototype is not yet explicitly declared. ‘DECL_EXTERN_C_FUNCTION_P’ This predicate holds if the function is declared as an '‘extern "C"’' function. ‘DECL_LINKONCE_P’ This macro holds if multiple copies of this function may be emitted in various translation units. It is the responsibility of the linker to merge the various copies. Template instantiations are the most common example of functions for which ‘DECL_LINKONCE_P’ holds; G++ instantiates needed templates in all translation units which require them, and then relies on the linker to remove duplicate instantiations. FIXME: This macro is not yet implemented. ‘DECL_FUNCTION_MEMBER_P’ This macro holds if the function is a member of a class, rather than a member of a namespace. ‘DECL_STATIC_FUNCTION_P’ This predicate holds if the function a static member function. ‘DECL_NONSTATIC_MEMBER_FUNCTION_P’ This macro holds for a non-static member function. ‘DECL_CONST_MEMFUNC_P’ This predicate holds for a ‘const’-member function. ‘DECL_VOLATILE_MEMFUNC_P’ This predicate holds for a ‘volatile’-member function. ‘DECL_CONSTRUCTOR_P’ This macro holds if the function is a constructor. ‘DECL_NONCONVERTING_P’ This predicate holds if the constructor is a non-converting constructor. ‘DECL_COMPLETE_CONSTRUCTOR_P’ This predicate holds for a function which is a constructor for an object of a complete type. ‘DECL_BASE_CONSTRUCTOR_P’ This predicate holds for a function which is a constructor for a base class sub-object. ‘DECL_COPY_CONSTRUCTOR_P’ This predicate holds for a function which is a copy-constructor. ‘DECL_DESTRUCTOR_P’ This macro holds if the function is a destructor. ‘DECL_COMPLETE_DESTRUCTOR_P’ This predicate holds if the function is the destructor for an object a complete type. ‘DECL_OVERLOADED_OPERATOR_P’ This macro holds if the function is an overloaded operator. ‘DECL_CONV_FN_P’ This macro holds if the function is a type-conversion operator. ‘DECL_GLOBAL_CTOR_P’ This predicate holds if the function is a file-scope initialization function. ‘DECL_GLOBAL_DTOR_P’ This predicate holds if the function is a file-scope finalization function. ‘DECL_THUNK_P’ This predicate holds if the function is a thunk. These functions represent stub code that adjusts the ‘this’ pointer and then jumps to another function. When the jumped-to function returns, control is transferred directly to the caller, without returning to the thunk. The first parameter to the thunk is always the ‘this’ pointer; the thunk should add ‘THUNK_DELTA’ to this value. (The ‘THUNK_DELTA’ is an ‘int’, not an ‘INTEGER_CST’.) Then, if ‘THUNK_VCALL_OFFSET’ (an ‘INTEGER_CST’) is nonzero the adjusted ‘this’ pointer must be adjusted again. The complete calculation is given by the following pseudo-code: this += THUNK_DELTA if (THUNK_VCALL_OFFSET) this += (*((ptrdiff_t **) this))[THUNK_VCALL_OFFSET] Finally, the thunk should jump to the location given by ‘DECL_INITIAL’; this will always be an expression for the address of a function. ‘DECL_NON_THUNK_FUNCTION_P’ This predicate holds if the function is _not_ a thunk function. ‘GLOBAL_INIT_PRIORITY’ If either ‘DECL_GLOBAL_CTOR_P’ or ‘DECL_GLOBAL_DTOR_P’ holds, then this gives the initialization priority for the function. The linker will arrange that all functions for which ‘DECL_GLOBAL_CTOR_P’ holds are run in increasing order of priority before ‘main’ is called. When the program exits, all functions for which ‘DECL_GLOBAL_DTOR_P’ holds are run in the reverse order. ‘TYPE_RAISES_EXCEPTIONS’ This macro returns the list of exceptions that a (member-)function can raise. The returned list, if non ‘NULL’, is comprised of nodes whose ‘TREE_VALUE’ represents a type. ‘TYPE_NOTHROW_P’ This predicate holds when the exception-specification of its arguments is of the form '‘()’'. ‘DECL_ARRAY_DELETE_OPERATOR_P’ This predicate holds if the function an overloaded ‘operator delete[]’.  File: gccint.info, Node: Statements for C and C++, Next: C++ Expressions, Prev: Functions for C++, Up: C and C++ Trees 11.10.5 Statements for C and C++ -------------------------------- A function that has a definition in the current translation unit has a non-‘NULL’ ‘DECL_INITIAL’. However, back ends should not make use of the particular value given by ‘DECL_INITIAL’. The ‘DECL_SAVED_TREE’ gives the complete body of the function. There are tree nodes corresponding to all of the source-level statement constructs, used within the C and C++ frontends. These are enumerated here, together with a list of the various macros that can be used to obtain information about them. There are a few macros that can be used with all statements: ‘STMT_IS_FULL_EXPR_P’ In C++, statements normally constitute "full expressions"; temporaries created during a statement are destroyed when the statement is complete. However, G++ sometimes represents expressions by statements; these statements will not have ‘STMT_IS_FULL_EXPR_P’ set. Temporaries created during such statements should be destroyed when the innermost enclosing statement with ‘STMT_IS_FULL_EXPR_P’ set is exited. Here is the list of the various statement nodes, and the macros used to access them. This documentation describes the use of these nodes in non-template functions (including instantiations of template functions). In template functions, the same nodes are used, but sometimes in slightly different ways. Many of the statements have substatements. For example, a ‘while’ loop has a body, which is itself a statement. If the substatement is ‘NULL_TREE’, it is considered equivalent to a statement consisting of a single ‘;’, i.e., an expression statement in which the expression has been omitted. A substatement may in fact be a list of statements, connected via their ‘TREE_CHAIN’s. So, you should always process the statement tree by looping over substatements, like this: void process_stmt (stmt) tree stmt; { while (stmt) { switch (TREE_CODE (stmt)) { case IF_STMT: process_stmt (THEN_CLAUSE (stmt)); /* More processing here. */ break; ... } stmt = TREE_CHAIN (stmt); } } In other words, while the ‘then’ clause of an ‘if’ statement in C++ can be only one statement (although that one statement may be a compound statement), the intermediate representation sometimes uses several statements chained together. ‘BREAK_STMT’ Used to represent a ‘break’ statement. There are no additional fields. ‘CLEANUP_STMT’ Used to represent an action that should take place upon exit from the enclosing scope. Typically, these actions are calls to destructors for local objects, but back ends cannot rely on this fact. If these nodes are in fact representing such destructors, ‘CLEANUP_DECL’ will be the ‘VAR_DECL’ destroyed. Otherwise, ‘CLEANUP_DECL’ will be ‘NULL_TREE’. In any case, the ‘CLEANUP_EXPR’ is the expression to execute. The cleanups executed on exit from a scope should be run in the reverse order of the order in which the associated ‘CLEANUP_STMT’s were encountered. ‘CONTINUE_STMT’ Used to represent a ‘continue’ statement. There are no additional fields. ‘CTOR_STMT’ Used to mark the beginning (if ‘CTOR_BEGIN_P’ holds) or end (if ‘CTOR_END_P’ holds of the main body of a constructor. See also ‘SUBOBJECT’ for more information on how to use these nodes. ‘DO_STMT’ Used to represent a ‘do’ loop. The body of the loop is given by ‘DO_BODY’ while the termination condition for the loop is given by ‘DO_COND’. The condition for a ‘do’-statement is always an expression. ‘EMPTY_CLASS_EXPR’ Used to represent a temporary object of a class with no data whose address is never taken. (All such objects are interchangeable.) The ‘TREE_TYPE’ represents the type of the object. ‘EXPR_STMT’ Used to represent an expression statement. Use ‘EXPR_STMT_EXPR’ to obtain the expression. ‘FOR_STMT’ Used to represent a ‘for’ statement. The ‘FOR_INIT_STMT’ is the initialization statement for the loop. The ‘FOR_COND’ is the termination condition. The ‘FOR_EXPR’ is the expression executed right before the ‘FOR_COND’ on each loop iteration; often, this expression increments a counter. The body of the loop is given by ‘FOR_BODY’. ‘FOR_SCOPE’ holds the scope of the ‘for’ statement (used in the C++ front end only). Note that ‘FOR_INIT_STMT’ and ‘FOR_BODY’ return statements, while ‘FOR_COND’ and ‘FOR_EXPR’ return expressions. ‘HANDLER’ Used to represent a C++ ‘catch’ block. The ‘HANDLER_TYPE’ is the type of exception that will be caught by this handler; it is equal (by pointer equality) to ‘NULL’ if this handler is for all types. ‘HANDLER_PARMS’ is the ‘DECL_STMT’ for the catch parameter, and ‘HANDLER_BODY’ is the code for the block itself. ‘IF_STMT’ Used to represent an ‘if’ statement. The ‘IF_COND’ is the expression. If the condition is a ‘TREE_LIST’, then the ‘TREE_PURPOSE’ is a statement (usually a ‘DECL_STMT’). Each time the condition is evaluated, the statement should be executed. Then, the ‘TREE_VALUE’ should be used as the conditional expression itself. This representation is used to handle C++ code like this: if (int i = 7) ... where there is a new local variable (or variables) declared within the condition. The ‘THEN_CLAUSE’ represents the statement given by the ‘then’ condition, while the ‘ELSE_CLAUSE’ represents the statement given by the ‘else’ condition. C++ distinguishes between this and ‘COND_EXPR’ for handling templates. ‘SUBOBJECT’ In a constructor, these nodes are used to mark the point at which a subobject of ‘this’ is fully constructed. If, after this point, an exception is thrown before a ‘CTOR_STMT’ with ‘CTOR_END_P’ set is encountered, the ‘SUBOBJECT_CLEANUP’ must be executed. The cleanups must be executed in the reverse order in which they appear. ‘SWITCH_STMT’ Used to represent a ‘switch’ statement. The ‘SWITCH_STMT_COND’ is the expression on which the switch is occurring. See the documentation for an ‘IF_STMT’ for more information on the representation used for the condition. The ‘SWITCH_STMT_BODY’ is the body of the switch statement. The ‘SWITCH_STMT_TYPE’ is the original type of switch expression as given in the source, before any compiler conversions. The ‘SWITCH_STMT_SCOPE’ is the statement scope (used in the C++ front end only). There are also two boolean flags used with ‘SWITCH_STMT’. ‘SWITCH_STMT_ALL_CASES_P’ is true if the switch includes a default label or the case label ranges cover all possible values of the condition expression. ‘SWITCH_STMT_NO_BREAK_P’ is true if there are no ‘break’ statements in the switch. ‘TRY_BLOCK’ Used to represent a ‘try’ block. The body of the try block is given by ‘TRY_STMTS’. Each of the catch blocks is a ‘HANDLER’ node. The first handler is given by ‘TRY_HANDLERS’. Subsequent handlers are obtained by following the ‘TREE_CHAIN’ link from one handler to the next. The body of the handler is given by ‘HANDLER_BODY’. If ‘CLEANUP_P’ holds of the ‘TRY_BLOCK’, then the ‘TRY_HANDLERS’ will not be a ‘HANDLER’ node. Instead, it will be an expression that should be executed if an exception is thrown in the try block. It must rethrow the exception after executing that code. And, if an exception is thrown while the expression is executing, ‘terminate’ must be called. ‘USING_STMT’ Used to represent a ‘using’ directive. The namespace is given by ‘USING_STMT_NAMESPACE’, which will be a NAMESPACE_DECL. This node is needed inside template functions, to implement using directives during instantiation. ‘WHILE_STMT’ Used to represent a ‘while’ loop. The ‘WHILE_COND’ is the termination condition for the loop. See the documentation for an ‘IF_STMT’ for more information on the representation used for the condition. The ‘WHILE_BODY’ is the body of the loop.