GCC Middle and Back End API Reference
tree-sra.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "hash-table.h"
#include "alloc-pool.h"
#include "tm.h"
#include "tree.h"
#include "gimple.h"
#include "bitmap.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
#include "tree-ssanames.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-pass.h"
#include "ipa-prop.h"
#include "statistics.h"
#include "params.h"
#include "target.h"
#include "flags.h"
#include "dbgcnt.h"
#include "tree-inline.h"
#include "gimple-pretty-print.h"
#include "ipa-inline.h"
#include "ipa-utils.h"
Include dependency graph for tree-sra.c:

Data Structures

struct  access
struct  assign_link
struct  uid_decl_hasher

Typedefs

typedef struct accessaccess_p

Enumerations

enum  sra_mode { SRA_MODE_EARLY_IPA, SRA_MODE_EARLY_INTRA, SRA_MODE_INTRA }
enum  unscalarized_data_handling { SRA_UDH_NONE, SRA_UDH_RIGHT, SRA_UDH_LEFT }
enum  assignment_mod_result { SRA_AM_NONE, SRA_AM_MODIFIED, SRA_AM_REMOVED }
enum  ipa_splicing_result {
  NO_GOOD_ACCESS, UNUSED_PARAMS, BY_VAL_ACCESSES, MODIF_BY_REF_ACCESSES,
  UNMODIF_BY_REF_ACCESSES
}

Functions

static tree candidate ()
static bool no_accesses_p ()
static void dump_access ()
static void dump_access_tree_1 ()
static void dump_access_tree ()
static bool access_has_children_p ()
static bool access_has_replacements_p ()
static vec< access_p > * get_base_access_vector ()
static struct accessfind_access_in_subtree (struct access *access, HOST_WIDE_INT offset, HOST_WIDE_INT size)
static struct accessget_first_repr_for_decl ()
static struct accessget_var_base_offset_size_access (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
static void add_link_to_rhs ()
static void relink_to_new_repr ()
static void add_access_to_work_queue ()
static struct accesspop_access_from_work_queue ()
static void sra_initialize ()
static bool delete_base_accesses (const void *key, void **value, void *data)
static void sra_deinitialize ()
static void disqualify_candidate ()
static bool type_internals_preclude_sra_p ()
static tree get_ssa_base_param ()
static void mark_parm_dereference ()
static struct accesscreate_access_1 ()
static struct accesscreate_access ()
static bool type_consists_of_records_p ()
static void completely_scalarize_record (tree base, tree decl, HOST_WIDE_INT offset, tree ref)
static void completely_scalarize_var ()
static bool contains_view_convert_expr_p ()
static void disqualify_base_of_expr ()
static struct accessbuild_access_from_expr_1 ()
static bool build_access_from_expr ()
static bool disqualify_ops_if_throwing_stmt ()
static bool build_accesses_from_assign ()
static bool asm_visit_addr (gimple stmt, tree op, void *data)
static bool callsite_has_enough_arguments_p ()
static bool scan_function ()
static int compare_access_positions ()
static void make_fancy_decl_name ()
static void make_fancy_name_1 ()
static char * make_fancy_name ()
tree build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, tree exp_type, gimple_stmt_iterator *gsi, bool insert_after)
static tree build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, struct access *model, gimple_stmt_iterator *gsi, bool insert_after)
static tree build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, struct access *model)
static bool build_user_friendly_ref_for_offset (tree *res, tree type, HOST_WIDE_INT offset, tree exp_type)
static bool is_va_list_type ()
static void reject ()
static bool maybe_add_sra_candidate ()
static bool find_var_candidates ()
static struct accesssort_and_splice_var_accesses ()
static tree create_access_replacement ()
static tree get_access_replacement ()
static bool build_access_subtree ()
static bool build_access_trees ()
static bool expr_with_var_bounded_array_refs_p ()
static bool analyze_access_subtree (struct access *root, struct access *parent, bool allow_replacements)
static bool analyze_access_trees ()
static bool child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset, HOST_WIDE_INT size, struct access **exact_match)
static struct accesscreate_artificial_child_access (struct access *parent, struct access *model, HOST_WIDE_INT new_offset)
static bool propagate_subaccesses_across_link ()
static void propagate_all_subaccesses ()
static bool analyze_all_variable_accesses ()
static void generate_subtree_copies (struct access *access, tree agg, HOST_WIDE_INT top_offset, HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size, gimple_stmt_iterator *gsi, bool write, bool insert_after, location_t loc)
static void init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi, bool insert_after, location_t loc)
static struct accessget_access_for_expr ()
static bool sra_modify_expr ()
static enum
unscalarized_data_handling 
handle_unscalarized_data_in_subtree (struct access *top_racc, gimple_stmt_iterator *gsi)
static void load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc, HOST_WIDE_INT left_offset, gimple_stmt_iterator *old_gsi, gimple_stmt_iterator *new_gsi, enum unscalarized_data_handling *refreshed)
static enum assignment_mod_result sra_modify_constructor_assign ()
static tree get_repl_default_def_ssa_name ()
static bool contains_vce_or_bfcref_p ()
static enum assignment_mod_result sra_modify_assign ()
static bool sra_modify_function_body ()
static void initialize_parameter_reductions ()
static unsigned int perform_intra_sra ()
static unsigned int early_intra_sra ()
static unsigned int late_intra_sra ()
static bool gate_intra_sra ()
gimple_opt_passmake_pass_sra_early ()
gimple_opt_passmake_pass_sra ()
static bool is_unused_scalar_param ()
static bool ptr_parm_has_direct_uses ()
static bool find_param_candidates ()
static bool mark_maybe_modified (ao_ref *ao, tree vdef, void *data)
static void analyze_modified_params ()
static void propagate_dereference_distances ()
static void dump_dereferences_table ()
static void analyze_caller_dereference_legality ()
static struct accessunmodified_by_ref_scalar_representative ()
static bool access_precludes_ipa_sra_p ()
static struct accesssplice_param_accesses ()
static int decide_one_param_reduction ()
static enum ipa_splicing_result splice_all_param_accesses ()
static int get_param_index ()
static ipa_parm_adjustment_vec turn_representatives_into_adjustments (vec< access_p > representatives, int adjustments_count)
static ipa_parm_adjustment_vec analyze_all_param_acesses ()
static tree get_replaced_param_substitute ()
static struct ipa_parm_adjustmentget_adjustment_for_base ()
static bool replace_removed_params_ssa_names (gimple stmt, ipa_parm_adjustment_vec adjustments)
static bool sra_ipa_modify_expr (tree *expr, bool convert, ipa_parm_adjustment_vec adjustments)
static bool sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, ipa_parm_adjustment_vec adjustments)
static bool ipa_sra_modify_function_body ()
static void sra_ipa_reset_debug_stmts ()
static bool not_all_callers_have_enough_arguments_p (struct cgraph_node *node, void *data)
static bool convert_callers_for_node (struct cgraph_node *node, void *data)
static void convert_callers (struct cgraph_node *node, tree old_decl, ipa_parm_adjustment_vec adjustments)
static bool modify_function ()
static bool has_caller_p ()
static bool ipa_sra_preliminary_function_checks ()
static unsigned int ipa_early_sra ()
static bool ipa_early_sra_gate ()
gimple_opt_passmake_pass_early_ipa_sra ()

Variables

static enum sra_mode sra_mode
static alloc_pool access_pool
static alloc_pool link_pool
static struct pointer_map_tbase_access_vec
static bitmap candidate_bitmap
static hash_table
< uid_decl_hasher
candidates
static bitmap should_scalarize_away_bitmap
static bitmap cannot_scalarize_away_bitmap
static struct obstack name_obstack
static struct accesswork_queue_head
static int func_param_count
static bool encountered_apply_args
static bool encountered_recursive_call
static bool encountered_unchangable_recursive_call
static HOST_WIDE_INTbb_dereferences
static bitmap final_bbs
static struct access no_accesses_representant
struct {
   int   replacements
   int   exprs
   int   subtree_copies
   int   subreplacements
   int   deleted
   int   separate_lhs_rhs_handling
   int   deleted_unused_parameters
   int   scalar_by_ref_to_by_val
   int   aggregate_params_reduced
   int   param_reductions_created
sra_stats

Typedef Documentation

typedef struct access* access_p

Enumeration Type Documentation

Result code for SRA assignment modification.

Enumerator:
SRA_AM_NONE 
SRA_AM_MODIFIED 
SRA_AM_REMOVED 

The order of the following enums is important, we need to do extra work for UNUSED_PARAMS, BY_VAL_ACCESSES and UNMODIF_BY_REF_ACCESSES.

Enumerator:
NO_GOOD_ACCESS 
UNUSED_PARAMS 
BY_VAL_ACCESSES 
MODIF_BY_REF_ACCESSES 
UNMODIF_BY_REF_ACCESSES 
enum sra_mode

Scalar Replacement of Aggregates (SRA) converts some structure references into scalar references, exposing them to the scalar optimizers. Copyright (C) 2008-2013 Free Software Foundation, Inc. Contributed by Martin Jambor mjamb.nosp@m.or@s.nosp@m.use.c.nosp@m.z

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 implements Scalar Reduction of Aggregates (SRA). SRA is run twice, once in the early stages of compilation (early SRA) and once in the late stages (late SRA). The aim of both is to turn references to scalar parts of aggregates into uses of independent scalar variables.

The two passes are nearly identical, the only difference is that early SRA does not scalarize unions which are used as the result in a GIMPLE_RETURN statement because together with inlining this can lead to weird type conversions.

Both passes operate in four stages:

  1. The declarations that have properties which make them candidates for scalarization are identified in function find_var_candidates(). The candidates are stored in candidate_bitmap.
  1. The function body is scanned. In the process, declarations which are used in a manner that prevent their scalarization are removed from the candidate bitmap. More importantly, for every access into an aggregate, an access structure (struct access) is created by create_access() and stored in a vector associated with the aggregate. Among other information, the aggregate declaration, the offset and size of the access and its type are stored in the structure.

    On a related note, assign_link structures are created for every assign statement between candidate aggregates and attached to the related accesses.

  1. The vectors of accesses are analyzed. They are first sorted according to their offset and size and then scanned for partially overlapping accesses (i.e. those which overlap but one is not entirely within another). Such an access disqualifies the whole aggregate from being scalarized.

    If there is no such inhibiting overlap, a representative access structure is chosen for every unique combination of offset and size. Afterwards, the pass builds a set of trees from these structures, in which children of an access are within their parent (in terms of offset and size).

    Then accesses are propagated whenever possible (i.e. in cases when it does not create a partially overlapping access) across assign_links from the right hand side to the left hand side.

    Then the set of trees for each declaration is traversed again and those accesses which should be replaced by a scalar are identified.

  1. The function is traversed again, and for every reference into an aggregate that has some component which is about to be scalarized, statements are amended and new statements are created as necessary. Finally, if a parameter got scalarized, the scalar replacements are initialized with values from respective parameter aggregates. Enumeration of all aggregate reductions we can do.
Enumerator:
SRA_MODE_EARLY_IPA 
SRA_MODE_EARLY_INTRA 
SRA_MODE_INTRA 

Where scalar replacements of the RHS have been written to when a replacement of a LHS of an assigments cannot be direclty loaded from a replacement of the RHS.

Enumerator:
SRA_UDH_NONE 
SRA_UDH_RIGHT 
SRA_UDH_LEFT 

Function Documentation

static bool access_has_children_p ( )
inlinestatic

Return true iff ACC is non-NULL and has subaccesses.

References get_first_repr_for_decl(), access::next_grp, access::offset, and access::size.

Referenced by contains_vce_or_bfcref_p().

static bool access_has_replacements_p ( )
static

Return true iff ACC is (partly) covered by at least one replacement.

static bool access_precludes_ipa_sra_p ( )
static

Return true iff this ACCESS precludes IPA-SRA of the parameter it is associated with. REQ_ALIGN is the minimum required alignment.

Avoid issues such as the second simple testcase in PR 42025. The problem is incompatible assign in a call statement (and possibly even in asm statements). This can be relaxed by using a new temporary but only for non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In intraprocedural SRA we deal with this by keeping the old aggregate around, something we cannot do in IPA-SRA.)

static void add_access_to_work_queue ( )
static

Add ACCESS to the work queue (which is actually a stack).

References dump_file, and print_generic_expr().

Referenced by child_would_conflict_in_lacc().

static void add_link_to_rhs ( )
static

Add LINK to the linked list of assign links of RACC.

Referenced by build_access_from_expr_1().

static bool analyze_access_subtree ( struct access root,
struct access parent,
bool  allow_replacements 
)
static

Analyze the subtree of accesses rooted in ROOT, scheduling replacements when both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set all sorts of access flags appropriately along the way, notably always set grp_read and grp_assign_read according to MARK_READ and grp_write when MARK_WRITE is true.

Creating a replacement for a scalar access is considered beneficial if its grp_hint is set (this means we are either attempting total scalarization or there is more than one direct read access) or according to the following table:

Access written to through a scalar type (once or more times) | | Written to in an assignment statement | | | | Access read as scalar once | | | | | | Read in an assignment statement | | | |

| | | | Scalarize Comment

0 0 0 0 No access for the scalar 0 0 0 1 No access for the scalar 0 0 1 0 No Single read - won't help 0 0 1 1 No The same case 0 1 0 0 No access for the scalar 0 1 0 1 No access for the scalar 0 1 1 0 Yes s = *g; return s.i; 0 1 1 1 Yes The same case as above 1 0 0 0 No Won't help 1 0 0 1 Yes s.i = 1; *g = s; 1 0 1 0 Yes s.i = 5; g = s.i; 1 0 1 1 Yes The same case as above 1 1 0 0 No Won't help. 1 1 0 1 Yes s.i = 1; *g = s; 1 1 1 0 Yes s = *g; return s.i; 1 1 1 1 Yes Any of the above yeses

Always create access replacements that cover the whole access. For integral types this means the precision has to match. Avoid assumptions based on the integral type kind, too.

         But leave bitfield accesses alone.   

References access::offset, and access::size.

Referenced by get_access_replacement().

static bool analyze_access_trees ( )
static

Analyze all access trees linked by next_grp by the means of analyze_access_subtree.

static ipa_parm_adjustment_vec analyze_all_param_acesses ( )
static

Analyze the collected accesses and produce a plan what to do with the parameters in the form of adjustments, NULL meaning nothing.

If there are any parameters passed by reference which are not modified directly, we need to check whether they can be modified indirectly.

References TREE_OPERAND.

static bool analyze_all_variable_accesses ( )
static

Go through all accesses collected throughout the (intraprocedural) analysis stage, exclude overlapping ones, identify representatives and build trees out of them, making decisions about scalarization on the way. Return true iff there are any to-be-scalarized variables after this stage.

static void analyze_caller_dereference_legality ( )
static

Determine what (parts of) parameters passed by reference that are not assigned to are not certainly dereferenced in this function and thus the dereferencing cannot be safely moved to the caller without potentially introducing a segfault. Mark such REPRESENTATIVES as grp_not_necessarilly_dereferenced.

The dereferenced maximum "distance," i.e. the offset + size of the accessed part is calculated rather than simple booleans are calculated for each pointer parameter to handle cases when only a fraction of the whole aggregate is allocated (see testsuite/gcc.c-torture/execute/ipa-sra-2.c for an example).

The maximum dereference distances for each pointer parameter and BB are already stored in bb_dereference. This routine simply propagates these values upwards by propagate_dereference_distances and then compares the distances of individual parameters in the ENTRY BB to the equivalent distances of each representative of a (fraction of a) parameter.

References access::base, DECL_UID, dump_access(), dump_file, gcc_assert, access::next_grp, access::non_addressable, POINTER_TYPE_P, print_generic_expr(), tree_low_cst(), TREE_TYPE, and TYPE_SIZE.

static void analyze_modified_params ( )
static

Analyze what representatives (in linked lists accessible from REPRESENTATIVES) can be modified by side effects of statements in the current function.

All accesses are read ones, otherwise grp_maybe_modified would be trivially set.

static bool asm_visit_addr ( gimple  stmt,
tree  op,
void *  data 
)
static

Callback of walk_stmt_load_store_addr_ops visit_addr used to determine GIMPLE_ASM operands with memory constrains which cannot be scalarized.

static bool build_access_from_expr ( )
static

Scan expression EXPR and create access structures for all accesses to candidates for scalarization. Return true if any access has been inserted. STMT must be the statement from which the expression is taken, WRITE must be true if the expression is a store and false otherwise.

This means the aggregate is accesses as a whole in a way other than an assign statement and thus cannot be removed even if we had a scalar replacement for everything.

References DECL_P, disqualify_candidate(), and get_base_address().

Referenced by disqualify_ops_if_throwing_stmt().

static struct access* build_access_from_expr_1 ( )
staticread

Scan expression EXPR and create access structures for all accesses to candidates for scalarization. Return the created access or NULL if none is created.

We need to dive through V_C_Es in order to get the size of its parameter and not the result type. Ada produces such statements. We are also capable of handling the topmost V_C_E but not any of those buried in other handled components.

     fall through  

References add_link_to_rhs(), AGGREGATE_TYPE_P, access::base, bitmap_set_bit, DECL_UID, disqualify_ops_if_throwing_stmt(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_clobber_p(), gimple_has_volatile_ops(), access::grp_assignment_read, access::grp_assignment_write, access::grp_unscalarizable_region, is_gimple_reg_type(), assign_link::lacc, pool_alloc(), assign_link::racc, access::size, SRA_MODE_EARLY_INTRA, SRA_MODE_INTRA, TREE_TYPE, access::type, and useless_type_conversion_p().

static bool build_access_subtree ( )
static

Build a subtree of accesses rooted in *ACCESS, and move the pointer in the linked list along the way. Stop when *ACCESS is NULL or the access pointed to it is not "within" the root. Return false iff some accesses partially overlap.

static bool build_access_trees ( )
static

Build a tree of access representatives, ACCESS is the pointer to the first one, others are linked in a list by the next_grp field. Return false iff some accesses partially overlap.

static bool build_accesses_from_assign ( )
static

Scan expressions occurring in STMT, create access structures for all accesses to candidates for scalarization and remove those candidates which occur in statements or expressions that prevent them from being split apart. Return true if any access has been inserted.

Scope clobbers don't influence scalarization.

static tree build_debug_ref_for_model ( location_t  loc,
tree  base,
HOST_WIDE_INT  offset,
struct access model 
)
static

Attempt to build a memory reference that we could but into a gimple debug_bind statement. Similar to build_ref_for_model but punts if it has to create statements and return s NULL instead. This function also ignores alignment issues and so its results should never end up in non-debug statements.

References TYPE_MAIN_VARIANT, and va_list_type_node.

static tree build_ref_for_model ( location_t  loc,
tree  base,
HOST_WIDE_INT  offset,
struct access model,
gimple_stmt_iterator gsi,
bool  insert_after 
)
static

Construct a memory reference to a part of an aggregate BASE at the given OFFSET and of the same type as MODEL. In case this is a reference to a bit-field, the function will replicate the last component_ref of model's expr to access it. GSI and INSERT_AFTER have the same meaning as in build_ref_for_offset.

This access represents a bit-field.

Referenced by generate_subtree_copies(), sra_modify_constructor_assign(), and sra_modify_expr().

tree build_ref_for_offset ( location_t  loc,
tree  base,
HOST_WIDE_INT  offset,
tree  exp_type,
gimple_stmt_iterator gsi,
bool  insert_after 
)

Construct a MEM_REF that would reference a part of aggregate BASE of type EXP_TYPE at the given OFFSET. If BASE is something for which get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used to insert new statements either before or below the current one as specified by INSERT_AFTER. This function is not capable of handling bitfields.

BASE must be either a declaration or a memory reference that has correct alignment ifformation embeded in it (e.g. a pre-existing one in SRA).

get_addr_base_and_unit_offset returns NULL for references with a variable offset such as array[var_index].

static bool build_user_friendly_ref_for_offset ( tree res,
tree  type,
HOST_WIDE_INT  offset,
tree  exp_type 
)
static

Construct a memory reference consisting of component_refs and array_refs to a part of an aggregate *RES (which is of type TYPE). The requested part should have type EXP_TYPE at be the given OFFSET. This function might not succeed, it returns true when it does and only then *RES points to something meaningful. This function should be used only to build expressions that we might need to present to user (e.g. in warnings). In all other situations, build_ref_for_model or build_ref_for_offset should be used instead.

static bool callsite_has_enough_arguments_p ( )
inlinestatic

Return true iff callsite CALL has at least as many actual arguments as there are formal parameters of the function currently processed by IPA-SRA.

static tree candidate ( )
inlinestatic

For a candidate UID return the candidates decl.

References no_accesses_representant.

static bool child_would_conflict_in_lacc ( struct access lacc,
HOST_WIDE_INT  norm_offset,
HOST_WIDE_INT  size,
struct access **  exact_match 
)
static

Return true iff a potential new child of LACC at offset OFFSET and with size SIZE would conflict with an already existing one. If exactly such a child already exists in LACC, store a pointer to it in EXACT_MATCH.

References add_access_to_work_queue(), access::base, bitmap_bit_p, DECL_UID, access::first_link, gcc_assert, access::group_representative, assign_link::lacc, assign_link::next, pop_access_from_work_queue(), and propagate_subaccesses_across_link().

static int compare_access_positions ( )
static

Helper of QSORT function. There are pointers to accesses in the array. An access is considered smaller than another if it has smaller offset or if the offsets are the same but is size is bigger.

     Put any non-aggregate type before any aggregate type.   
     Put any complex or vector type before any other scalar type.   
     Put the integral type with the bigger precision first.   
     Put any integral type with non-full precision last.   
     Stabilize the sort.   
 We want the bigger accesses first, thus the opposite operator in the next
 line:  
static void completely_scalarize_record ( tree  base,
tree  decl,
HOST_WIDE_INT  offset,
tree  ref 
)
static

Create total_scalarization accesses for all scalar type fields in DECL that must be of a RECORD_TYPE conforming to type_consists_of_records_p. BASE must be the top-most VAR_DECL representing the variable, OFFSET must be the offset of DECL within BASE. REF must be the memory reference expression for the given decl.

Accesses for intraprocedural SRA can have their stmt NULL.

static void completely_scalarize_var ( )
static

Create total_scalarization accesses for all scalar type fields in VAR and for VAR a a whole. VAR must be of a RECORD_TYPE conforming to type_consists_of_records_p.

static bool contains_vce_or_bfcref_p ( )
inlinestatic

Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a bit-field field declaration somewhere in it.

References access_has_children_p(), access::base, access::first_child, force_gimple_operand_gsi(), generate_subtree_copies(), gimple_assign_rhs1(), GSI_SAME_STMT, NULL_TREE, and sra_stats.

static bool contains_view_convert_expr_p ( )
inlinestatic

Return true if REF has an VIEW_CONVERT_EXPR somewhere in it.

static void convert_callers ( struct cgraph_node node,
tree  old_decl,
ipa_parm_adjustment_vec  adjustments 
)
static

Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.

References dbg_cnt().

static bool convert_callers_for_node ( struct cgraph_node node,
void *  data 
)
static

Convert all callers of NODE.

static struct access* create_access ( )
staticread

Create and insert access for EXPR. Return created access, or NULL if it is not possible.

static struct access* create_access_1 ( )
staticread

Allocate an access structure for BASE, OFFSET and SIZE, clear it, fill in the three fields. Also add it to the vector of accesses corresponding to the base. Finally, return the new access.

static tree create_access_replacement ( )
static

Create a variable for the given ACCESS which determines the type, name and a few other properties. Return the variable declaration and store it also to ACCESS->replacement.

Get rid of any SSA_NAMEs embedded in debug_expr, as DECL_DEBUG_EXPR isn't considered when looking for still used SSA_NAMEs and thus they could be freed. All debug info generation cares is whether something is constant or variable and that get_ref_base_and_extent works properly on the expression. It cannot handle accesses at a non-constant offset though, so just give up in those cases.

           FALLTHRU  

Referenced by expr_with_var_bounded_array_refs_p(), and load_assign_lhs_subreplacements().

static struct access* create_artificial_child_access ( struct access parent,
struct access model,
HOST_WIDE_INT  new_offset 
)
staticread

Create a new child access of PARENT, with all properties just like MODEL except for its offset and with its grp_write false and grp_read true. Return the new access or NULL if it cannot be created. Note that this access is created long after all splicing and sorting, it's not located in any access vector and is automatically a representative of its group.

static int decide_one_param_reduction ( )
static

Decide whether parameters with representative accesses given by REPR should be reduced into components.

Taking the address of a non-addressable field is verboten.

     Do not decompose a non-BLKmode param in a way that would
     create BLKmode params.  Especially for by-reference passing
     (thus, pointer-type param) this is hardly worthwhile.   
static bool delete_base_accesses ( const void *  key,
void **  value,
void *  data 
)
static

Hook fed to pointer_map_traverse, deallocate stored vectors.

static void disqualify_base_of_expr ( )
static

Search the given tree for a declaration by skipping handled components and exclude it from the candidates.

References SRA_MODE_EARLY_INTRA, SRA_MODE_INTRA, stmt_can_throw_internal(), and stmt_ends_bb_p().

static void disqualify_candidate ( )
static

Remove DECL from candidates for SRA and write REASON to the dump file if there is one.

Referenced by build_access_from_expr(), and mark_parm_dereference().

static bool disqualify_ops_if_throwing_stmt ( )
static

Disqualify LHS and RHS for scalarization if STMT must end its basic block in modes in which it matters, return true iff they have been disqualified. RHS may be NULL, in that case ignore it. If we scalarize an aggregate in intra-SRA we may need to add statements after each statement. This is not possible if a statement unconditionally has to end the basic block.

References bitmap_set_bit, build_access_from_expr(), gimple_return_retval(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), basic_block_def::index, NULL_TREE, and stmt_can_throw_external().

Referenced by build_access_from_expr_1().

static void dump_access ( )
static
static void dump_access_tree ( )
static

Dump all access trees for a variable, given the pointer to the first root in ACCESS.

static void dump_access_tree_1 ( )
static

Dump a subtree rooted in ACCESS to file F, indent by LEVEL.

References access::first_child, access::next_sibling, access::offset, and access::size.

static void dump_dereferences_table ( )
static

Dump a dereferences TABLE with heading STR to file F.

static unsigned int early_intra_sra ( )
static

Perform early intraprocedural SRA.

static bool expr_with_var_bounded_array_refs_p ( )
static
static struct access* find_access_in_subtree ( struct access access,
HOST_WIDE_INT  offset,
HOST_WIDE_INT  size 
)
staticread

Find an access with required OFFSET and SIZE in a subtree of accesses rooted in ACCESS. Return NULL if it cannot be found.

Referenced by sra_modify_expr().

static bool find_param_candidates ( )
static

Identify candidates for reduction for IPA-SRA based on their type and mark them in candidate_bitmap. Note that these do not necessarily include parameter which are unused and thus can be removed. Return true iff any such candidate has been found.

static bool find_var_candidates ( )
static

The very first phase of intraprocedural SRA. It marks in candidate_bitmap those with type which is suitable for scalarization.

static void generate_subtree_copies ( struct access access,
tree  agg,
HOST_WIDE_INT  top_offset,
HOST_WIDE_INT  start_offset,
HOST_WIDE_INT  chunk_size,
gimple_stmt_iterator gsi,
bool  write,
bool  insert_after,
location_t  loc 
)
static

Generate statements copying scalar replacements of accesses within a subtree into or out of AGG. ACCESS, all its children, siblings and their children are to be processed. AGG is an aggregate type expression (can be a declaration but does not have to be, it can for example also be a mem_ref or a series of handled components). TOP_OFFSET is the offset of the processed subtree which has to be subtracted from offsets of individual accesses to get corresponding offsets for AGG. If CHUNK_SIZE is non-null, copy only replacements in the interval <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a statement iterator used to place the new statements. WRITE should be true when the statements should write from AGG to the replacement and false if vice versa. if INSERT_AFTER is true, new statements will be added after the current statement in GSI, they will be added before the statement otherwise.

References access::base, build_ref_for_model(), access::expr, access::first_child, force_gimple_operand_gsi(), get_access_for_expr(), get_access_replacement(), gimple_build_assign, gimple_build_debug_bind, gimple_location(), gimple_set_location(), access::grp_partial_lhs, access::grp_to_be_debug_replaced, access::grp_to_be_replaced, gsi_insert_after(), gsi_insert_before(), GSI_NEW_STMT, GSI_SAME_STMT, gsi_stmt(), host_integerp(), HOST_WIDE_INT, NULL, NULL_TREE, access::offset, sra_stats, access::stmt, TREE_CODE, TREE_OPERAND, TREE_TYPE, access::type, type(), and useless_type_conversion_p().

Referenced by contains_vce_or_bfcref_p().

static struct access* get_access_for_expr ( )
staticread

Search for an access representative for the given expression EXPR and return it or NULL if it cannot be found.

FIXME: This should not be necessary but Ada produces V_C_Es with a type of a different size than the size of its argument and we need the latter one.

Referenced by generate_subtree_copies().

static tree get_access_replacement ( )
inlinestatic

Return ACCESS scalar replacement, create it if it does not exist yet.

References analyze_access_subtree(), access::grp_covered, access::grp_total_scalarization, access::grp_unscalarized_data, access::offset, and access::size.

Referenced by generate_subtree_copies(), and sra_modify_expr().

static struct ipa_parm_adjustment* get_adjustment_for_base ( )
staticread

Find the first adjustment for a particular parameter BASE in a vector of ADJUSTMENTS which is not a copy_param. Return NULL if there is no such adjustment.

static vec<access_p>* get_base_access_vector ( )
static

Return a vector of pointers to accesses for the variable given in BASE or NULL if there is none.

static struct access* get_first_repr_for_decl ( )
staticread

Return the first group representative for DECL or NULL if none exists.

References gcc_assert, access::grp_queued, access::next_queued, and work_queue_head.

Referenced by access_has_children_p().

static int get_param_index ( )
inlinestatic

Return the index of BASE in PARMS. Abort if it is not found.

References gimple_assign_lhs(), gimple_call_lhs(), gimple_phi_result(), is_gimple_assign(), and is_gimple_call().

static tree get_repl_default_def_ssa_name ( )
static

Create and return a new suitable default definition SSA_NAME for RACC which is an access describing an uninitialized part of an aggregate that is being loaded.

static tree get_replaced_param_substitute ( )
static

If a parameter replacement identified by ADJ does not yet exist in the form of declaration, create it and record it, otherwise return the previously created one.

static tree get_ssa_base_param ( )
static

If T is an SSA_NAME, return NULL if it is not a default def or return its base variable if it is. Return T if it is not an SSA_NAME.

static struct access* get_var_base_offset_size_access ( tree  base,
HOST_WIDE_INT  offset,
HOST_WIDE_INT  size 
)
staticread

Find an access representative for the variable BASE and given OFFSET and SIZE. Requires that access trees have already been built. Return NULL if it cannot be found.

References access::grp_queued, access::next_queued, NULL, and work_queue_head.

static enum unscalarized_data_handling handle_unscalarized_data_in_subtree ( struct access top_racc,
gimple_stmt_iterator gsi 
)
static

Store all replacements in the access tree rooted in TOP_RACC either to their base aggregate if there are unscalarized data or directly to LHS of the statement that is pointed to by GSI otherwise.

Referenced by sra_modify_expr().

static bool has_caller_p ( )
static

If NODE has a caller, return true.

static void init_subtree_with_zero ( struct access access,
gimple_stmt_iterator gsi,
bool  insert_after,
location_t  loc 
)
static

Assign zero to all scalar replacements in an access subtree. ACCESS is the the root of the subtree to be processed. GSI is the statement iterator used for inserting statements which are added after the current statement if INSERT_AFTER is true or before it otherwise.

References access::offset, tree_low_cst(), and TREE_OPERAND.

static void initialize_parameter_reductions ( )
static

Generate statements initializing scalar replacements of parts of function parameters.

References cfun, has_zero_uses(), is_gimple_reg(), and ssa_default_def().

static unsigned int ipa_early_sra ( )
static

Perform early interprocedural SRA.

static bool ipa_early_sra_gate ( )
static

Return if early ipa sra shall be performed.

static bool ipa_sra_modify_function_body ( )
static

Traverse the function body and all modifications as described in ADJUSTMENTS. Return true iff the CFG has been changed.

Operands must be processed before the lhs.

static bool ipa_sra_preliminary_function_checks ( )
static

Return false the function is apparently unsuitable for IPA-SRA based on it's attributes, return true otherwise. NODE is the cgraph node of the current function.

static bool is_unused_scalar_param ( )
static

Return true iff PARM (which must be a parm_decl) is an unused scalar parameter.

References func_param_count, access::next_grp, and visited.

Referenced by gate_intra_sra().

static bool is_va_list_type ( )
inlinestatic

Return true iff TYPE is stdarg va_list type.

Referenced by gate_intra_sra().

static unsigned int late_intra_sra ( )
static

Perform "late" intraprocedural SRA.

static void load_assign_lhs_subreplacements ( struct access lacc,
struct access top_racc,
HOST_WIDE_INT  left_offset,
gimple_stmt_iterator old_gsi,
gimple_stmt_iterator new_gsi,
enum unscalarized_data_handling refreshed 
)
static

Try to generate statements to load all sub-replacements in an access subtree formed by children of LACC from scalar replacements in the TOP_RACC subtree. If that is not possible, refresh the TOP_RACC base aggregate and load the accesses from it. LEFT_OFFSET is the offset of the left whole subtree being copied. NEW_GSI is stmt iterator used for statement insertions after the original assignment, OLD_GSI is used to insert statements before the assignment. *REFRESHED keeps the information whether we have needed to refresh replacements of the LHS and from which side of the assignments this takes place.

No suitable access on the right hand side, need to load from the aggregate. See if we have to update it first...

References cfun, create_access_replacement(), gcc_checking_assert, get_or_create_ssa_default_def(), access::grp_to_be_debug_replaced, access::grp_to_be_replaced, and access::replacement_decl.

static void make_fancy_decl_name ( )
static

Append a name of the declaration to the name obstack. A helper function for make_fancy_name.

static char* make_fancy_name ( )
static
static void make_fancy_name_1 ( )
static

Helper for make_fancy_name.

Arrays with only one element may not have a constant as their index.

gimple_opt_pass* make_pass_early_ipa_sra ( )
gimple_opt_pass* make_pass_sra ( )
gimple_opt_pass* make_pass_sra_early ( )
static bool mark_maybe_modified ( ao_ref ao,
tree  vdef,
void *  data 
)
static

Callback of walk_aliased_vdefs, marks the access passed as DATA as maybe_modified.

static void mark_parm_dereference ( )
static

Mark a dereference of BASE of distance DIST in a basic block tht STMT belongs to, unless the BB has already been marked as a potentially final.

References disqualify_candidate(), and NULL.

static bool maybe_add_sra_candidate ( )
static

Return true if VAR is a candidate for SRA.

static bool modify_function ( )
static

Perform all the modification required in IPA-SRA for NODE to have parameters as given in ADJUSTMENTS. Return true iff the CFG has been changed.

static bool no_accesses_p ( )
inlinestatic

Predicate to test the special value.

static bool not_all_callers_have_enough_arguments_p ( struct cgraph_node node,
void *  data 
)
static

Return false iff all callers have at least as many actual arguments as there are formal parameters in the current function.

static unsigned int perform_intra_sra ( )
static

The "main" function of intraprocedural SRA passes. Runs the analysis and if it reveals there are components of some aggregates to be scalarized, it runs the required transformations.

static struct access* pop_access_from_work_queue ( )
staticread

Pop an access from the work queue, and return it, assuming there is one.

References DECL_CHAIN, TREE_CODE, TREE_THIS_VOLATILE, TREE_TYPE, and TYPE_FIELDS.

Referenced by child_would_conflict_in_lacc().

static void propagate_all_subaccesses ( )
static

Propagate all subaccesses across assignment links.

static void propagate_dereference_distances ( )
static

Propagate distances in bb_dereferences in the opposite direction than the control flow edges, in each step storing the maximum of the current value and the minimum of all successors. These steps are repeated until the table stabilizes. Note that BBs which might terminate the functions (according to final_bbs bitmap) never updated in this way.

References access::expr, get_object_alignment(), is_gimple_call(), access::stmt, and access::write.

static bool propagate_subaccesses_across_link ( )
static

Propagate all subaccesses of RACC across an assignment link to LACC. Return true if any new subaccess was created. Additionally, if RACC is a scalar access but LACC is not, change the type of the latter, if possible.

Referenced by child_would_conflict_in_lacc().

static bool ptr_parm_has_direct_uses ( )
static

Scan immediate uses of a default definition SSA name of a parameter PARM and examine whether there are any direct or otherwise infeasible ones. If so, return true, otherwise return false. PARM must be a gimple register with a non-NULL default definition.

Valid uses include dereferences on the lhs and the rhs.

     If the number of valid uses does not match the number of
     uses in this stmt there is an unhandled use.   
static void reject ( )
static
static void relink_to_new_repr ( )
static

Move all link structures in their linked list in OLD_RACC to the linked list in NEW_RACC.

static bool replace_removed_params_ssa_names ( gimple  stmt,
ipa_parm_adjustment_vec  adjustments 
)
static

If the statement STMT defines an SSA_NAME of a parameter which is to be removed because its value is not used, replace the SSA_NAME with a one relating to a created VAR_DECL together all of its uses and return true. ADJUSTMENTS is a pointer to an adjustments vector.

static bool scan_function ( )
static

Scan function and look for interesting expressions and create access structures for them. Return true iff any access is created.

static struct access* sort_and_splice_var_accesses ( )
staticread

Sort all accesses for the given variable, check for partial overlaps and return NULL if there are any. If there are none, pick a representative for each combination of offset and size and create a linked list out of them. Return the pointer to the first representative and make sure it is the first one in the vector of accesses.

Sort by <OFFSET, SIZE>.

         If there are both aggregate-type and scalar-type accesses with
         this combination of size and offset, the comparison function
         should have put the scalars first.   
static enum ipa_splicing_result splice_all_param_accesses ( )
static

Identify representatives of all accesses to all candidate parameters for IPA-SRA. Return result based on what representatives have been found.

static struct access* splice_param_accesses ( )
staticread

Sort collected accesses for parameter PARM, identify representatives for each accessed region and link them together. Return NULL if there are different but overlapping accesses, return the special ptr value meaning there are no accesses for this parameter if that is the case and return the first representative otherwise. Set *RO_GRP if there is a group of accesses with only read (i.e. no write) accesses.

Access is about to become group representative unless we find some nasty overlap which would preclude us from breaking this parameter apart.

             All or nothing law for parameters.  

References UNMODIF_BY_REF_ACCESSES, and unmodified_by_ref_scalar_representative().

static void sra_deinitialize ( )
static

Deallocate all general structures.

static void sra_initialize ( )
static

Allocate necessary structures.

static bool sra_ipa_modify_assign ( gimple stmt_ptr,
gimple_stmt_iterator gsi,
ipa_parm_adjustment_vec  adjustments 
)
static

If the statement pointed to by STMT_PTR contains any expressions that need to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any potential type incompatibilities (GSI is used to accommodate conversion statements and must point to the statement). Return true iff the statement was modified.

  V_C_Es of constructors can cause trouble (PR 42714).   

This can happen when an assignment in between two single field structures is turned into an assignment in between two pointers to scalars (PR 42237).

static bool sra_ipa_modify_expr ( tree expr,
bool  convert,
ipa_parm_adjustment_vec  adjustments 
)
static

If the expression *EXPR should be replaced by a reduction of a parameter, do so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT specifies whether the function should care about type incompatibility the current and new expressions. If it is false, the function will leave incompatibility issues to the caller. Return true iff the expression was modified.

static void sra_ipa_reset_debug_stmts ( )
static

Call gimple_debug_bind_reset_value on all debug statements describing gimple register parameters that are being removed or replaced.

  All other users must have been removed by
  ipa_sra_modify_function_body.   

Create a VAR_DECL for debug info purposes.

References cgraph_node::callers.

static enum assignment_mod_result sra_modify_assign ( )
static

Examine both sides of the assignment statement pointed to by STMT, replace them with a scalare replacement if there is one and generate copying of replacements if scalarized aggregates have been used in the assignment. GSI is used to hold generated statements for type conversions and subtree copying.

    If we can avoid creating a VIEW_CONVERT_EXPR do so.
    ???  This should move to fold_stmt which we simply should
    call after building a VIEW_CONVERT_EXPR here.   
 From this point on, the function deals with assignments in between
 aggregates when at least one has scalar reductions of some of its
 components.  There are three possible scenarios: Both the LHS and RHS have
 to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.

 In the first case, we would like to load the LHS components from RHS
 components whenever possible.  If that is not possible, we would like to
 read it directly from the RHS (after updating it by storing in it its own
 components).  If there are some necessary unscalarized data in the LHS,
 those will be loaded by the original assignment too.  If neither of these
 cases happen, the original statement can be removed.  Most of this is done
 by load_assign_lhs_subreplacements.

 In the second case, we would like to store all RHS scalarized components
 directly into LHS and if they cover the aggregate completely, remove the
 statement too.  In the third case, we want the LHS components to be loaded
 directly from the RHS (DSE will remove the original statement if it
 becomes redundant).

 This is a bit complex but manageable when types match and when unions do
 not cause confusion in a way that we cannot really load a component of LHS
 from the RHS or vice versa (the access representing this level can have
 subaccesses that are accessible only through a different union field at a
 higher level - different from the one used in the examined expression).
 Unions are fun.

 Therefore, I specially handle a fourth case, happening when there is a
 specific type cast or it is impossible to locate a scalarized subaccess on
 the other side of the expression.  If that happens, I simply "refresh" the
 RHS by storing in it is scalarized components leave the original statement
 there to do the copying and then load the scalar replacements of the LHS.
 This is what the first branch does.   


     This gimplification must be done after generate_subtree_copies,
     lest we insert the subtree copies in the middle of the gimplified
     sequence.   
         When an access represents an unscalarizable region, it usually
         represents accesses with variable offset and thus must not be used
         to generate new memory accesses.   
         Restore the aggregate RHS from its components so the
         prevailing aggregate copy does the right thing.   
         Re-load the components of the aggregate copy destination.
         But use the RHS aggregate to load from to expose more
         optimization opportunities.   
static enum assignment_mod_result sra_modify_constructor_assign ( )
static

Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer to the assignment and GSI is the statement iterator pointing at it. Returns the same values as sra_modify_assign.

Remove clobbers of fully scalarized variables, otherwise do nothing.

     I have never seen this code path trigger but if it can happen the
     following should handle it gracefully.   

References build_ref_for_model(), and gimple_assign_set_lhs().

static bool sra_modify_expr ( )
static

Replace the expression EXPR with a scalar replacement if there is one and generate other statements to do type conversion or subtree copying if necessary. GSI is used to place newly created statements, WRITE is true if the expression is being written to (it is on a LHS of a statement or output in an assembly statement).

If we replace a non-register typed access simply use the original access expression to extract the scalar component afterwards. This happens if scalarizing a function return value or parameter like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and gcc.c-torture/compile/20011217-1.c.

We also want to use this when accessing a complex or vector which can be accessed as a different type too, potentially creating a need for type conversion (see PR42196) and when scalarized unions are involved in assembler statements (see PR42398).

References access::base, build_ref_for_model(), find_access_in_subtree(), fold_build1_loc, force_gimple_operand_gsi(), get_access_replacement(), gimple_build_assign, gimple_set_location(), access::grp_partial_lhs, access::grp_to_be_replaced, gsi_insert_after(), GSI_NEW_STMT, GSI_SAME_STMT, handle_unscalarized_data_in_subtree(), NULL_TREE, access::offset, access::size, sra_stats, SRA_UDH_LEFT, SRA_UDH_NONE, access::stmt, access::type, update_stmt(), and useless_type_conversion_p().

static bool sra_modify_function_body ( )
static

Traverse the function body and all modifications as decided in analyze_all_variable_accesses. Return true iff the CFG has been changed.

Operands must be processed before the lhs.

References dbg_cnt().

static ipa_parm_adjustment_vec turn_representatives_into_adjustments ( vec< access_p representatives,
int  adjustments_count 
)
static

Convert the decisions made at the representative level into compact parameter adjustments. REPRESENTATIVES are pointers to first representatives of each param accesses, ADJUSTMENTS_COUNT is the expected final number of adjustments.

static bool type_consists_of_records_p ( )
static

Return true iff TYPE is a RECORD_TYPE with fields that are either of gimple register types or (recursively) records with only these two kinds of fields. It also returns false if any of these records contains a bit-field.

static bool type_internals_preclude_sra_p ( )
static

Return true iff the type contains a field or an element which does not allow scalarization.

static struct access* unmodified_by_ref_scalar_representative ( )
staticread

Return the representative access for the parameter declaration PARM if it is a scalar passed by reference which is not written to and the pointer value is not used directly. Thus, if it is legal to dereference it in the caller and we can rule out modifications through aliases, such parameter should be turned into one passed by value. Return NULL otherwise.

Referenced by splice_param_accesses().


Variable Documentation

alloc_pool access_pool
static

Alloc pool for allocating access structures.

int aggregate_params_reduced

Number of aggregate parameters that were replaced by one or more of their components.

struct pointer_map_t* base_access_vec
static

Base (tree) -> Vector (vec<access_p> *) map.

HOST_WIDE_INT* bb_dereferences
static

This is a table in which for each basic block and parameter there is a distance (offset + size) in that parameter which is dereferenced and accessed in that BB.

bitmap candidate_bitmap
static

Set of candidates.

hash_table<uid_decl_hasher> candidates
static
bitmap cannot_scalarize_away_bitmap
static
int deleted

Number of times sra_modify_assign has deleted a statement.

Referenced by dse_step3().

int deleted_unused_parameters

Number of parameters that were removed because they were unused.

bool encountered_apply_args
static

scan_function sets the following to true if it encounters a call to __builtin_apply_args.

bool encountered_recursive_call
static

Set by scan_function when it finds a recursive call.

bool encountered_unchangable_recursive_call
static

Set by scan_function when it finds a recursive call with less actual arguments than formal parameters..

int exprs

Number of times sra_modify_expr or sra_modify_assign themselves changed an expression.

bitmap final_bbs
static

Bitmap of BBs that can cause the function to "stop" progressing by returning, throwing externally, looping infinitely or calling a function which might abort etc..

int func_param_count
static

Number of parameters of the analyzed function when doing early ipa SRA.

Referenced by is_unused_scalar_param().

alloc_pool link_pool
static

Alloc pool for allocating assign link structures.

struct obstack name_obstack
static

Obstack for creation of fancy names.

struct access no_accesses_representant
static

Representative of no accesses at all.

Referenced by candidate().

int param_reductions_created

Numbber of components created when splitting aggregate parameters.

int replacements

Number of processed aggregates is readily available in analyze_all_variable_accesses and so is not stored here. Number of created scalar replacements.

int scalar_by_ref_to_by_val

Number of scalars passed as parameters by reference that have been converted to be passed by value.

int separate_lhs_rhs_handling

Number of times sra_modify_assign has to deal with subaccesses of LHS and RHS reparately due to type conversions or nonexistent matching references.

bitmap should_scalarize_away_bitmap
static

Bitmap of candidates which we should try to entirely scalarize away and those which cannot be (because they are and need be used as a whole).

enum sra_mode sra_mode
static

Global variable describing which aggregate reduction we are performing at the moment.

struct { ... } sra_stats

Dump contents of ACCESS to file F in a human friendly way. If GRP is true, representative fields are dumped, otherwise those which only describe the individual access are.

Referenced by contains_vce_or_bfcref_p(), generate_subtree_copies(), and sra_modify_expr().

int subreplacements

Number of statements created by load_assign_lhs_subreplacements.

int subtree_copies

Number of statements created by generate_subtree_copies.

struct access* work_queue_head
static

Head of a linked list of accesses that need to have its subaccesses propagated to their assignment counterparts.

Referenced by get_first_repr_for_decl(), and get_var_base_offset_size_access().