GCC Middle and Back End API Reference
tree-ssa.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "gimplify.h"
#include "gimple-walk.h"
#include "tree-ssa-loop-manip.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "cfgexpand.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
Include dependency graph for tree-ssa.cc:


void redirect_edge_var_map_add (edge e, tree result, tree def, location_t locus)
void redirect_edge_var_map_clear (edge e)
void redirect_edge_var_map_dup (edge newe, edge olde)
vec< edge_var_map > * redirect_edge_var_map_vector (edge e)
void redirect_edge_var_map_empty (void)
edge ssa_redirect_edge (edge e, basic_block dest)
void flush_pending_stmts (edge e)
void gimple_replace_ssa_lhs (gimple *stmt, tree nlhs)
tree target_for_debug_bind (tree var)
tree find_released_ssa_name (tree *tp, int *walk_subtrees, void *data_)
void insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
void insert_debug_temps_for_defs (gimple_stmt_iterator *gsi)
void reset_debug_uses (gimple *stmt)
void release_defs_bitset (bitmap toremove)
bool verify_vssa (basic_block bb, tree current_vdef, sbitmap visited)
static bool verify_ssa_name (tree ssa_name, bool is_virtual)
static bool verify_def (basic_block bb, basic_block *definition_block, tree ssa_name, gimple *stmt, bool is_virtual)
static bool verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p, gimple *stmt, bool check_abnormal, bitmap names_defined_in_bb)
static bool verify_phi_args (gphi *phi, basic_block bb, basic_block *definition_block)
DEBUG_FUNCTION void verify_ssa (bool check_modified_stmt, bool check_ssa_operands)
void init_tree_ssa (struct function *fn, int size)
void delete_tree_ssa (struct function *fn)
bool tree_ssa_useless_type_conversion (tree expr)
tree tree_ssa_strip_useless_type_conversions (tree exp)
bool ssa_defined_default_def_p (tree t)
bool ssa_undefined_value_p (tree t, bool partial)
bool ssa_name_any_use_dominates_bb_p (tree var, basic_block bb)
void mark_ssa_maybe_undefs (void)
static void maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
static tree non_rewritable_mem_ref_base (tree ref)
static bool non_rewritable_lvalue_p (tree lhs)
static void maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, bitmap suitable_for_renaming)
static bool is_asan_mark_p (gimple *stmt)
void execute_update_addresses_taken (void)
gimple_opt_passmake_pass_update_address_taken (gcc::context *ctxt)


static hash_map< edge, auto_vec< edge_var_map > > * edge_var_maps

Function Documentation

◆ delete_tree_ssa()

◆ execute_update_addresses_taken()

void execute_update_addresses_taken ( void )
Compute TREE_ADDRESSABLE and whether we have unhandled partial defs
for local variables.   

References asan_mark_p(), bitmap_bit_p, bitmap_empty_p(), bitmap_set_bit, bitsizetype, build1(), build_clobber(), build_constructor(), build_vector_type(), cfun, DECL_ARGUMENTS, DECL_CHAIN, DECL_P, DECL_UID, fold_build1, fold_builtin_atomic_compare_exchange(), FOR_EACH_BB_FN, FOR_EACH_VEC_SAFE_ELT, g, gcc_assert, get_base_address(), ggc_alloc(), gimple_asm_input_op(), gimple_asm_ninputs(), gimple_asm_noutputs(), gimple_asm_output_op(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs1_ptr(), gimple_assign_set_lhs(), gimple_assign_set_rhs_from_tree(), gimple_assign_set_rhs_with_ops(), gimple_assign_single_p(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_arg_ptr(), gimple_call_internal_p(), gimple_call_num_args(), gimple_call_set_arg(), gimple_call_set_lhs(), gimple_clobber_p(), gimple_debug_bind_get_value_ptr(), gimple_debug_bind_has_value_p(), gimple_debug_bind_p(), gimple_debug_bind_reset_value(), gimple_get_lhs(), gimple_ior_addresses_taken(), gimple_location(), gimple_phi_num_args(), gimple_references_memory_p(), gimple_set_location(), gimple_set_vuse(), gimple_vuse(), walk_stmt_info::gsi, gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_next(), gsi_replace(), GSI_SAME_STMT, gsi_start_bb(), gsi_start_phis(), gsi_stmt(), i, integer_zerop(), is_asan_mark_p(), is_gimple_debug(), known_ge, known_gt, LOOP_CLOSED_SSA, loops_state_satisfies_p(), make_ssa_name(), maybe_optimize_var(), maybe_rewrite_mem_ref_base(), mem_ref_offset(), non_rewritable_lvalue_p(), non_rewritable_mem_ref_base(), NULL, null_pointer_node, NULL_TREE, number_of_loops(), operand_equal_p(), optimize_atomic_compare_exchange_p(), PHI_ARG_DEF, poly_int_tree_p(), rewrite_into_loop_closed_ssa(), walk_stmt_info::stmt, suppress_warning(), timevar_pop(), timevar_push(), wi::to_poly_offset(), TODO_update_ssa, TREE_ADDRESSABLE, TREE_CODE, TREE_OPERAND, TREE_THIS_VOLATILE, tree_to_uhwi(), TREE_TYPE, TREE_VALUE, TYPE_MODE, TYPE_SIZE, TYPE_SIZE_UNIT, types_compatible_p(), unlink_stmt_vdef(), update_ssa(), update_stmt(), useless_type_conversion_p(), valid_vector_subparts_p(), VAR_P, VECTOR_TYPE_P, and wide_int_to_tree().

Referenced by execute_function_todo().

◆ find_released_ssa_name()

tree find_released_ssa_name ( tree * tp,
int * walk_subtrees,
void * data_ )
Called via walk_tree, look for SSA_NAMEs that have already been


Referenced by insert_debug_temp_for_var_def(), and verify_loop_structure().

◆ flush_pending_stmts()

◆ gimple_replace_ssa_lhs()

void gimple_replace_ssa_lhs ( gimple * stmt,
tree nlhs )
Replace the LHS of STMT, an assignment, either a GIMPLE_ASSIGN or a
GIMPLE_CALL, with NLHS, in preparation for modifying the RHS to an
expression with a different value.

This will update any annotations (say debug bind stmts) referring
to the original LHS, so that they use the RHS instead.  This is
done even if NLHS and LHS are the same, for it is understood that
the RHS will be modified afterwards, and NLHS will not be assigned
an equivalent value.

Adjusting any non-annotation uses of the LHS, if needed, is a
responsibility of the caller.

The effect of this call should be pretty much the same as that of
inserting a copy of STMT before STMT, and then removing the
original stmt, at which time gsi_remove() would have update
annotations, but using this function saves all the inserting,
copying and removing.   

References gcc_assert, ggc_alloc(), gimple_get_lhs(), gimple_set_lhs(), insert_debug_temp_for_var_def(), MAY_HAVE_DEBUG_BIND_STMTS, NULL, and SSA_NAME_DEF_STMT.

◆ init_tree_ssa()

◆ insert_debug_temp_for_var_def()

◆ insert_debug_temps_for_defs()

void insert_debug_temps_for_defs ( gimple_stmt_iterator * gsi)
Insert a DEBUG BIND stmt before STMT for each DEF referenced by
other DEBUG stmts, and replace uses of the DEF with the
newly-created debug temp.   

References DEF_FROM_PTR, FOR_EACH_PHI_OR_STMT_DEF, ggc_alloc(), walk_stmt_info::gsi, gsi_stmt(), insert_debug_temp_for_var_def(), MAY_HAVE_DEBUG_BIND_STMTS, SSA_OP_DEF, walk_stmt_info::stmt, and TREE_CODE.

Referenced by gsi_remove(), and remove_phi_node().

◆ is_asan_mark_p()

static bool is_asan_mark_p ( gimple * stmt)

◆ make_pass_update_address_taken()

gimple_opt_pass * make_pass_update_address_taken ( gcc::context * ctxt)

References ggc_alloc().

◆ mark_ssa_maybe_undefs()

◆ maybe_optimize_var()

static void maybe_optimize_var ( tree var,
bitmap addresses_taken,
bitmap not_reg_needs,
bitmap suitable_for_renaming )
When possible, clear TREE_ADDRESSABLE bit, set or clear DECL_NOT_GIMPLE_REG_P
and mark the variable VAR for conversion into SSA.  Return true when updating
stmts is required.   

References bitmap_bit_p, bitmap_set_bit, cfun, DECL_NOT_GIMPLE_REG_P, DECL_UID, dump_file, ggc_alloc(), is_gimple_reg(), is_gimple_reg_type(), is_global_var(), MAX_FIXED_MODE_SIZE, print_generic_expr(), PROP_gimple_lbitint, TREE_ADDRESSABLE, TREE_CODE, TREE_TYPE, and TYPE_PRECISION.

Referenced by execute_update_addresses_taken().

◆ maybe_rewrite_mem_ref_base()

◆ non_rewritable_lvalue_p()

◆ non_rewritable_mem_ref_base()

◆ redirect_edge_var_map_add()

void redirect_edge_var_map_add ( edge e,
tree result,
tree def,
location_t locus )
Add a mapping with PHI RESULT and PHI DEF associated with edge E.   

References edge_var_map::def, edge_var_maps, edge_var_map::locus, NULL, and edge_var_map::result.

Referenced by cleanup_empty_eh_merge_phis(), and ssa_redirect_edge().

◆ redirect_edge_var_map_clear()

◆ redirect_edge_var_map_dup()

void redirect_edge_var_map_dup ( edge newe,
edge olde )
Duplicate the redirected var mappings in OLDE in NEWE.

This assumes a hash_map can have multiple edges mapping to the same
var_map (many to one mapping), since we don't remove the previous mappings.

References edge_var_maps, and ggc_alloc().

Referenced by redirect_edge_succ_nodup().

◆ redirect_edge_var_map_empty()

void redirect_edge_var_map_empty ( void )
Clear the edge variable mappings.   

References edge_var_maps.

Referenced by delete_tree_ssa(), execute_one_ipa_transform_pass(), execute_one_pass(), and set_cfun().

◆ redirect_edge_var_map_vector()

vec< edge_var_map > * redirect_edge_var_map_vector ( edge e)
Return the variable mappings for a given edge.  If there is none, return

References edge_var_maps, and NULL.

Referenced by expand_omp_for_static_chunk(), flush_pending_stmts(), remove_forwarder_block_with_phi(), and transform_to_exit_first_loop_alt().

◆ release_defs_bitset()

void release_defs_bitset ( bitmap toremove)
Delete SSA DEFs for SSA versions in the TOREMOVE bitmap, removing
dominated stmts before their dominators, so that release_ssa_defs
stands a chance of propagating DEFs into debug bind stmts.   

References bitmap_bit_p, bitmap_clear_bit(), bitmap_count_bits(), bitmap_empty_p(), bitmap_list_view(), bitmap_tree_view(), DEF_FROM_PTR, EXECUTE_IF_SET_IN_BITMAP, FOR_EACH_IMM_USE_STMT, FOR_EACH_SSA_DEF_OPERAND, ggc_alloc(), walk_stmt_info::gsi, gsi_for_stmt(), gsi_remove(), i, is_gimple_debug(), names, NULL_TREE, release_defs(), remove_phi_node(), ssa_name, SSA_NAME_DEF_STMT, SSA_NAME_VERSION, SSA_OP_DEF, and walk_stmt_info::stmt.

Referenced by tree_ssa_iv_optimize().

◆ reset_debug_uses()

◆ ssa_defined_default_def_p()

bool ssa_defined_default_def_p ( tree t)
Return true if T, as SSA_NAME, has an implicit default defined value.   


Referenced by get_constraint_for_ssa_var(), is_maybe_undefined(), and ssa_undefined_value_p().

◆ ssa_name_any_use_dominates_bb_p()

bool ssa_name_any_use_dominates_bb_p ( tree var,
basic_block bb )
Return TRUE iff there are any non-PHI uses of VAR that dominate the
end of BB.  If we return TRUE and BB is a loop header, then VAR we
be assumed to be defined within the loop, even if it is marked as

References CDI_DOMINATORS, dominated_by_p(), FOR_EACH_IMM_USE_FAST, ggc_alloc(), gimple_bb(), is_gimple_debug(), and USE_STMT.

Referenced by find_ssa_undef(), and mark_ssa_maybe_undefs().

◆ ssa_redirect_edge()

edge ssa_redirect_edge ( edge e,
basic_block dest )
Remove the corresponding arguments from the PHI nodes in E's
destination block and redirect it to DEST.  Return redirected edge.
The list of removed arguments is stored in a vector accessed
through edge_var_maps.   

References ggc_alloc(), gimple_phi_arg_def(), gimple_phi_arg_location(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), NULL_TREE, gphi_iterator::phi(), redirect_edge_succ_nodup(), redirect_edge_var_map_add(), and redirect_edge_var_map_clear().

Referenced by gimple_redirect_edge_and_branch(), gimple_try_redirect_by_replacing_jump(), redirect_eh_edge(), and vect_loop_versioning().

◆ ssa_undefined_value_p()

◆ target_for_debug_bind()

tree target_for_debug_bind ( tree var)
Given a tree for an expression for which we might want to emit
locations or values in debug information (generally a variable, but
we might deal with other kinds of trees in the future), return the
tree that should be used as the variable of a DEBUG_BIND STMT or
VAR_LOCATION INSN or NOTE.  Return NULL if VAR is not to be tracked.   


Referenced by dv_onepart_p(), expand_debug_expr(), expand_gimple_basic_block(), insert_init_debug_bind(), insert_phi_nodes_for(), maybe_register_def(), reset_debug_binding(), ipa_param_body_adjustments::reset_debug_stmts(), rewrite_stmt(), target_for_debug_bind(), use_type(), and vt_add_function_parameter().

◆ tree_ssa_strip_useless_type_conversions()

tree tree_ssa_strip_useless_type_conversions ( tree exp)
Strip conversions from EXP according to
tree_ssa_useless_type_conversion and return the resulting

References exp(), TREE_OPERAND, and tree_ssa_useless_type_conversion().

◆ tree_ssa_useless_type_conversion()

bool tree_ssa_useless_type_conversion ( tree expr)

◆ verify_def()

static bool verify_def ( basic_block bb,
basic_block * definition_block,
tree ssa_name,
gimple * stmt,
bool is_virtual )
Return true if the definition of SSA_NAME at block BB is malformed.

STMT is the statement where SSA_NAME is created.

DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
   version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
   it means that the block in that array slot contains the
   definition of SSA_NAME.

IS_VIRTUAL is true if SSA_NAME is created by a VDEF.   

References DECL_BY_REFERENCE, error(), ggc_alloc(), basic_block_def::index, print_generic_expr(), print_gimple_stmt(), ssa_name, SSA_NAME_DEF_STMT, SSA_NAME_VAR, SSA_NAME_VERSION, walk_stmt_info::stmt, TDF_VOPS, TREE_CODE, and verify_ssa_name().

Referenced by verify_ssa().

◆ verify_phi_args()

static bool verify_phi_args ( gphi * phi,
basic_block bb,
basic_block * definition_block )
Return true if any of the arguments for PHI node PHI at block BB is

DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
   version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
   it means that the block in that array slot contains the
   definition of SSA_NAME.   

References EDGE_COUNT, EDGE_PRED, error(), ggc_alloc(), gimple_phi_arg_imm_use_ptr(), gimple_phi_num_args(), gimple_phi_result(), handled_component_p(), i, is_gimple_min_invariant(), NULL, NULL_TREE, basic_block_def::preds, print_generic_stmt(), print_gimple_stmt(), SSA_NAME_VERSION, TDF_MEMSYMS, TDF_VOPS, TREE_ADDRESSABLE, TREE_CODE, TREE_OPERAND, USE_FROM_PTR, VAR_P, verify_ssa_name(), verify_use(), and virtual_operand_p().

Referenced by verify_ssa().

◆ verify_ssa()

◆ verify_ssa_name()

static bool verify_ssa_name ( tree ssa_name,
bool is_virtual )
Return true if SSA_NAME is malformed and mark it visited.

IS_VIRTUAL is true if this SSA_NAME was found inside a virtual

References cfun, error(), ggc_alloc(), gimple_nop_p(), gimple_vop(), NULL_TREE, ssa_name, SSA_NAME_DEF_STMT, SSA_NAME_IN_FREE_LIST, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, TREE_CODE, TREE_TYPE, and virtual_operand_p().

Referenced by verify_def(), verify_phi_args(), and verify_ssa().

◆ verify_use()

static bool verify_use ( basic_block bb,
basic_block def_bb,
use_operand_p use_p,
gimple * stmt,
bool check_abnormal,
bitmap names_defined_in_bb )
Return true if the use of SSA_NAME at statement STMT in block BB is

DEF_BB is the block where SSA_NAME was found to be created.

IDOM contains immediate dominator information for the flowgraph.

CHECK_ABNORMAL is true if the caller wants to check whether this use
   is flowing through an abnormal edge (only used when checking PHI

If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
  that are defined before STMT in basic block BB.   

References bitmap_bit_p, CDI_DOMINATORS, dominated_by_p(), error(), ggc_alloc(), gimple_nop_p(), basic_block_def::index, NULL, print_generic_expr(), print_gimple_stmt(), ssa_name, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, SSA_NAME_VERSION, walk_stmt_info::stmt, TDF_VOPS, TREE_VISITED, USE_FROM_PTR, and verify_imm_links().

Referenced by verify_phi_args(), and verify_ssa().

◆ verify_vssa()

bool verify_vssa ( basic_block bb,
tree current_vdef,
sbitmap visited )
Disable warnings about missing quoting in GCC diagnostics for
the verification errors.  Their format strings don't follow GCC
diagnostic conventions and the calls are ultimately followed by
one to internal_error.   
Verify virtual SSA form.   

References bitmap_set_bit, error(), FOR_EACH_EDGE, get_virtual_phi(), ggc_alloc(), gimple_phi_result(), gimple_vdef(), gimple_vuse(), walk_stmt_info::gsi, gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), basic_block_def::index, NULL, PHI_ARG_DEF_FROM_EDGE, print_generic_expr(), print_gimple_stmt(), si, walk_stmt_info::stmt, basic_block_def::succs, TDF_VOPS, TREE_CODE, verify_vssa(), virtual_operand_p(), and visited.

Referenced by verify_ssa(), and verify_vssa().

Variable Documentation

◆ edge_var_maps

hash_map<edge, auto_vec<edge_var_map> >* edge_var_maps
Miscellaneous SSA utility functions.
   Copyright (C) 2001-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
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
Pointer map of variable mappings, keyed by edge.   

Referenced by redirect_edge_var_map_add(), redirect_edge_var_map_clear(), redirect_edge_var_map_dup(), redirect_edge_var_map_empty(), and redirect_edge_var_map_vector().