GCC Middle and Back End API Reference
|
Data Structures | |
struct | funct_state_d |
Typedefs | |
typedef struct funct_state_d * | funct_state |
Enumerations | |
enum | pure_const_state_e { IPA_CONST, IPA_PURE, IPA_NEITHER } |
Variables | |
static struct pointer_set_t * | visited_nodes |
const char * | pure_const_names [3] = {"const", "pure", "neither"} |
static struct funct_state_d | varying_state = { IPA_NEITHER, IPA_NEITHER, true, true, true } |
static vec< funct_state > | funct_state_vec |
static struct cgraph_node_hook_list * | function_insertion_hook_holder |
static struct cgraph_2node_hook_list * | node_duplication_hook_holder |
static struct cgraph_node_hook_list * | node_removal_hook_holder |
typedef struct funct_state_d* funct_state |
enum pure_const_state_e |
|
static |
Called when new function is inserted to callgraph late.
There are some shared nodes, in particular the initializers on static declarations. We do not need to scan them more than once since all we would be interested in are the addressof operations.
|
static |
This is the main routine for finding the reference patterns for global variables within a function FN.
Thunk gets propagated through, so nothing interesting happens.
Const functions cannot have back edges (an indication of possible infinite loop side effect.
Preheaders are needed for SCEV to work. Simple latches and recorded exits improve chances that loop will proved to be finite in testcases such as in loop-15.c and loop-24.c
References dump_file, dump_flags, finite_loop_p(), flow_loops_dump(), loop_optimizer_finalize(), loop_optimizer_init(), funct_state_d::looping, LOOPS_HAVE_PREHEADERS, LOOPS_HAVE_RECORDED_EXITS, LOOPS_HAVE_SIMPLE_LATCHES, mark_irreducible_loops(), loop::num, scev_finalize(), and scev_initialize().
|
inlinestatic |
Merge STATE and STATE2 and LOOPING and LOOPING2 and store into STATE and LOOPING better of the two variants. Be sure to merge looping correctly. IPA_NEITHER functions have looping 0 even if they don't have to return.
References IPA_CONST.
|
static |
Check the parameters of a function call to CALL_EXPR to see if there are any references in the parameters that are not allowed for pure or const functions. Also check to see if this is either an indirect call, a call outside the compilation unit, or has special attributes that may also effect the purity. The CALL_EXPR node for the entire call expression.
The const and pure flags are set by a variety of places in the compiler (including here). If someone has already set the flags for the callee, (such as for some of the builtins) we will use them, otherwise we will compute our own information. Const and pure functions have less clobber effects than other functions so we process these first. Otherwise if it is a call outside the compilation unit or an indirect call we punt. This leaves local calls which will be processed by following the call graph.
When bad things happen to bad functions, they cannot be const or pure.
When not in IPA mode, we can still handle self recursion.
Either callee is unknown or we are doing local analysis. Look to see if there are any bits available for the callee (such as by declaration or because it is builtin) and process solely on the basis of those bits.
Direct functions calls are handled by IPA propagation.
References BUILT_IN_NORMAL, dump_file, IPA_NEITHER, funct_state_d::looping, funct_state_d::pure_const_state, setjmp_call_p(), special_builtin_state(), and worse_state().
Referenced by check_stmt().
|
inlinestatic |
Check to see if the use (or definition when CHECKING_WRITE is true) variable T is legal in a function that is either pure or const.
Do not want to do anything with volatile except mark any function that uses one to be not const or pure.
Do not care about a local automatic that is not static.
If the variable has the "used" attribute, treat it as if it had a been touched by the devil.
In IPA mode we are not interested in checking actual loads and stores; they will be processed at propagation time using ipa_ref.
Since we have dealt with the locals and params cases above, if we are CHECKING_WRITE, this cannot be a pure or constant function.
Readonly reads are safe.
Just a regular read.
Compilation level statics can be read if they are readonly variables.
Just a regular read.
|
static |
Wrapper around check_decl for loads in ipa mode.
|
static |
Wrapper around check_decl for stores in ipa mode.
|
static |
Wrapper around check_decl for loads in local more.
|
inlinestatic |
Check to see if the use (or definition when CHECKING_WRITE is true) variable T is legal in a function that is either pure or const.
|
static |
Look into pointer pointed to by GSIP and figure out what interesting side effects it has.
Look for loads and stores.
Target of long jump.
Abandon all hope, ye who enter here.
Abandon all hope, ye who enter here.
References check_call(), dump_file, gimple_asm_clobbers_memory_p(), gimple_asm_volatile_p(), gimple_label_label(), IPA_NEITHER, funct_state_d::looping, and funct_state_d::pure_const_state.
|
static |
Wrapper around check_decl for stores in local more.
References dump_file, and print_gimple_stmt().
|
static |
Called when new clone is inserted to callgraph late.
|
static |
Emit noreturn warnings.
|
static |
Try to guess if function body will always be visible to compiler when compiling the call and whether compiler will be able to propagate the information by itself.
References option_enabled(), pointer_set_contains(), and pointer_set_create().
|
static |
Don't bother doing anything if the program has errors.
|
static |
|
inlinestatic |
Return the function state from NODE.
We might want to put correct previously_known state into varying.
|
inlinestatic |
Return true if we have a function state for NODE.
|
static |
Referenced by searchc().
|
static |
Simple local pass for pure const discovery reusing the analysis from ipa_pure_const. This pass is effective when executed together with other optimization passes in early optimization pass queue.
Do NORETURN discovery.
Update declaration and reduce profile to executed once.
ipa_opt_pass_d* make_pass_ipa_pure_const | ( | ) |
gimple_opt_pass* make_pass_local_pure_const | ( | ) |
gimple_opt_pass* make_pass_warn_function_noreturn | ( | ) |
|
static |
Produce the global information by preforming a transitive closure on the local information that was produced by generate_summary.
Nothrow makes more function to not lead to return and improve later analysis.
Cleanup.
|
static |
Produce transitive closure over the callgraph and compute nothrow attributes.
Propagate the local information through the call graph to produce the global information. All the nodes within a cycle will have the same info so we collapse cycles first. Then we can do the propagation in one pass from the leaves to the roots.
Find the worst state for any node in the cycle.
Copy back the region's pure_const_state which is shared by all nodes in the region.
|
static |
Produce transitive closure over the callgraph and compute pure/const attributes.
Propagate the local information through the call graph to produce the global information. All the nodes within a cycle will have the same info so we collapse cycles first. Then we can do the propagation in one pass from the leaves to the roots.
Find the worst state for any node in the cycle.
First merge in function body properties.
For overwritable nodes we can not assume anything.
We consider recursive cycles as possibly infinite. This might be relaxed since infinite recursion leads to stack overflow.
Now walk the edges and merge in callee properties.
Merge the results with what we already know.
Now process the indirect call.
Merge the results with what we already know.
And finally all loads and stores.
readonly reads are safe.
Copy back the region's pure_const_state which is shared by all nodes in the region.
All nodes within a cycle share the same info.
|
static |
Analyze each function in the cgraph to see if it is locally PURE or CONST.
There are some shared nodes, in particular the initializers on static declarations. We do not need to scan them more than once since all we would be interested in are the addressof operations.
Process all of the functions. We process AVAIL_OVERWRITABLE functions. We can not use the results by default, but the info can be used at LTO with -fwhole-program or when function got cloned and the clone is AVAILABLE.
|
static |
Deserialize the ipa info for lto.
Note that the flags must be read in the opposite order in which they were written (the bitflags were pushed into FLAGS).
|
static |
Serialize the ipa info for lto.
Process all of the functions.
Note that flags will need to be read in the opposite order as we are pushing the bitflags into FLAGS.
|
static |
|
static |
Called when new clone is inserted to callgraph late.
References count, lto_create_simple_output_block(), and LTO_section_ipa_pure_const.
|
static |
Return true if NODE is self recursive function. Indirectly recursive functions appears as non-trivial strongly connected components, so we need to care about self recursion only.
References dump_file, dump_flags, funct_state_d::looping_previously_known, pure_const_names, funct_state_d::state_previously_known, and worse_state().
|
inlinestatic |
Set the function state S for NODE.
|
static |
Return true if function should be skipped for local pure const analysis.
Because we do not schedule pass_fixup_cfg over whole program after early optimizations we must not promote functions that are called by already processed functions.
References cgraph_set_pure_flag(), and funct_state_d::looping.
|
static |
Recognize special cases of builtins that are by themselves not pure or const but function using them is.
References funct_state_d::can_throw, function::can_throw_non_call_exceptions, cfun, dump_file, gimple_call_flags(), gimple_call_fndecl(), gimple_num_ops(), gimple_op(), funct_state_d::looping, stmt_can_throw_external(), stmt_could_throw_p(), and tree_could_throw_p().
Referenced by check_call().
|
static |
compute state based on ECF FLAGS and store to STATE and LOOPING.
|
staticread |
Emit suggestion about attribute ATTRIB_NAME for DECL. KNOWN_FINITE is true if the function is known to be finite. The diagnostic is controlled by OPTION. WARNED_ABOUT is a pointer_set unique for OPTION, this function may initialize it and it is always returned by the function.
|
static |
Emit suggestion about __attribute_((const)) for DECL. KNOWN_FINITE is true if the function is known to be finite.
|
static |
|
static |
Emit suggestion about __attribute_((pure)) for DECL. KNOWN_FINITE is true if the function is known to be finite.
|
inlinestatic |
Merge STATE and STATE2 and LOOPING and LOOPING2 and store into STATE and LOOPING worse of the two variants.
Referenced by check_call(), and self_recursive_p().
|
static |
The storage of the funct_state is abstracted because there is the possibility that it may be desirable to move this to the cgraph local info.
Array, indexed by cgraph node uid, of function states.
|
static |
Holders of ipa cgraph hooks:
|
static |
|
static |
const char* pure_const_names[3] = {"const", "pure", "neither"} |
Referenced by self_recursive_p().
|
static |
State used when we know nothing about function.
|
static |
@verbatim
Callgraph based analysis of static variables. Copyright (C) 2004-2013 Free Software Foundation, Inc. Contributed by Kenneth Zadeck zadec k@na tural brid ge.co m
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/.
This file marks functions as being either const (TREE_READONLY) or pure (DECL_PURE_P). It can also set a variant of these that are allowed to loop indefinitely (DECL_LOOPING_CONST_PURE_P). This must be run after inlining decisions have been made since otherwise, the local sets will not contain information that is consistent with post inlined state. The global sets are not prone to this problem since they are by definition transitive.
The code in this module is called by the ipa pass manager. It should be one of the later passes since it's information is used by the rest of the compilation.