GCC Middle and Back End API Reference
tree-ssa-operands.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "timevar.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "stmt.h"
#include "print-tree.h"
#include "dumpfile.h"
Include dependency graph for tree-ssa-operands.cc:

Data Structures

class  operands_scanner

Macros

#define opf_use   0
#define opf_def   (1 << 0)
#define opf_no_vops   (1 << 1)
#define opf_non_addressable   (1 << 3)
#define opf_not_non_addressable   (1 << 4)
#define opf_address_taken   (1 << 5)
#define OP_SIZE_INIT   0
#define OP_SIZE_1   (1024 - sizeof (void *))
#define OP_SIZE_2   (1024 * 4 - sizeof (void *))
#define OP_SIZE_3   (1024 * 16 - sizeof (void *))

Functions

static struct ssa_operands * gimple_ssa_operands (const struct function *fun)
bool ssa_operands_active (struct function *fun)
static void create_vop_var (struct function *fn)
void init_ssa_operands (struct function *fn)
void fini_ssa_operands (struct function *fn)
static void * ssa_operand_alloc (struct function *fn, unsigned size)
static struct use_optype_d * alloc_use (struct function *fn)
static use_optype_p add_use_op (struct function *fn, gimple *stmt, tree *op, use_optype_p last)
static void mark_address_taken (tree ref)
DEBUG_FUNCTION bool verify_ssa_operands (struct function *fn, gimple *stmt)
void free_stmt_operands (struct function *fn, gimple *stmt)
void update_stmt_operands (struct function *fn, gimple *stmt)
void swap_ssa_operands (gimple *stmt, tree *exp0, tree *exp1)
DEBUG_FUNCTION bool verify_imm_links (FILE *f, tree var)
void dump_immediate_uses_for (FILE *file, tree var)
void dump_immediate_uses (FILE *file)
DEBUG_FUNCTION void debug_immediate_uses (void)
DEBUG_FUNCTION void debug_immediate_uses_for (tree var)
void unlink_stmt_vdef (gimple *stmt)
bool single_imm_use_1 (const ssa_use_operand_t *head, use_operand_p *use_p, gimple **stmt)
auto_vec< gimple *, 2 > gather_imm_use_stmts (tree ssavar)

Macro Definition Documentation

◆ OP_SIZE_1

#define OP_SIZE_1   (1024 - sizeof (void *))

Referenced by ssa_operand_alloc().

◆ OP_SIZE_2

#define OP_SIZE_2   (1024 * 4 - sizeof (void *))

Referenced by ssa_operand_alloc().

◆ OP_SIZE_3

#define OP_SIZE_3   (1024 * 16 - sizeof (void *))

Referenced by ssa_operand_alloc().

◆ OP_SIZE_INIT

#define OP_SIZE_INIT   0
These are the sizes of the operand memory buffer in bytes which gets
allocated each time more operands space is required.  The final value is
the amount that is allocated every time after that.
In 1k we can fit 25 use operands (or 63 def operands) on a host with
8 byte pointers, that would be 10 statements each with 1 def and 2
uses.   

Referenced by init_ssa_operands(), and ssa_operand_alloc().

◆ opf_address_taken

#define opf_address_taken   (1 << 5)
Operand is having its address taken.   

Referenced by operands_scanner::get_expr_operands().

◆ opf_def

#define opf_def   (1 << 0)

◆ opf_no_vops

#define opf_no_vops   (1 << 1)
No virtual operands should be created in the expression.  This is used
when traversing ADDR_EXPR nodes which have different semantics than
other expressions.  Inside an ADDR_EXPR node, the only operands that we
need to consider are indices into arrays.  For instance, &a.b[i] should
generate a USE of 'i' but it should not generate a VUSE for 'a' nor a
VUSE for 'b'.   

Referenced by operands_scanner::add_stmt_operand(), operands_scanner::add_virtual_operand(), operands_scanner::get_expr_operands(), operands_scanner::get_mem_ref_operands(), operands_scanner::get_tmr_operands(), and operands_scanner::parse_ssa_operands().

◆ opf_non_addressable

#define opf_non_addressable   (1 << 3)
Operand is in a place where address-taken does not imply addressable.   

Referenced by operands_scanner::get_expr_operands(), operands_scanner::get_mem_ref_operands(), and operands_scanner::get_tmr_operands().

◆ opf_not_non_addressable

#define opf_not_non_addressable   (1 << 4)

◆ opf_use

#define opf_use   0
SSA operands management for trees.
   Copyright (C) 2003-2026 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
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 contains the code required to manage the operands cache of the
SSA optimizer.  For every stmt, we maintain an operand cache in the stmt
annotation.  This cache contains operands that will be of interest to
optimizers and other passes wishing to manipulate the IL.

The operand type are broken up into REAL and VIRTUAL operands.  The real
operands are represented as pointers into the stmt's operand tree.  Thus
any manipulation of the real operands will be reflected in the actual tree.
Virtual operands are represented solely in the cache, although the base
variable for the SSA_NAME may, or may not occur in the stmt's tree.
Manipulation of the virtual operands will not be reflected in the stmt tree.

The routines in this file are concerned with creating this operand cache
from a stmt tree.

The operand tree is the parsed by the various get_* routines which look
through the stmt tree for the occurrence of operands which may be of
interest, and calls are made to the append_* routines whenever one is
found.  There are 4 of these routines, each representing one of the
4 types of operands. Defs, Uses, Virtual Uses, and Virtual May Defs.

The append_* routines check for duplication, and simply keep a list of
unique objects for each operand type in the build_* extendable vectors.

Once the stmt tree is completely parsed, the finalize_ssa_operands()
routine is called, which proceeds to perform the finalization routine
on each of the 4 operand vectors which have been built up.

If the stmt had a previous operand cache, the finalization routines
attempt to match up the new operands with the old ones.  If it's a perfect
match, the old vector is simply reused.  If it isn't a perfect match, then
a new vector is created and the new operands are placed there.  For
virtual operands, if the previous cache had SSA_NAME version of a
variable, and that same variable occurs in the same operands cache, then
the new cache vector will also get the same SSA_NAME.

i.e., if a stmt had a VUSE of 'a_5', and 'a' occurs in the new
operand vector for VUSE, then the new vector will also be modified
such that it contains 'a_5' rather than 'a'.   
Flags to describe operand properties in helpers.   
By default, operands are loaded.   

Referenced by operands_scanner::get_expr_operands(), operands_scanner::get_mem_ref_operands(), operands_scanner::get_tmr_operands(), operands_scanner::maybe_add_call_vops(), and operands_scanner::parse_ssa_operands().

Function Documentation

◆ add_use_op()

use_optype_p add_use_op ( struct function * fn,
gimple * stmt,
tree * op,
use_optype_p last )
inlinestatic
Adds OP to the list of uses of statement STMT after LAST.   

References add_use_op(), alloc_use(), link_imm_use_stmt(), use_optype_d::next, NULL, and USE_OP_PTR.

Referenced by add_use_op(), and operands_scanner::finalize_ssa_uses().

◆ alloc_use()

struct use_optype_d * alloc_use ( struct function * fn)
inlinestatic

◆ create_vop_var()

void create_vop_var ( struct function * fn)
static

◆ debug_immediate_uses()

DEBUG_FUNCTION void debug_immediate_uses ( void )
Dump def-use edges on stderr.   

References debug_immediate_uses(), and dump_immediate_uses().

Referenced by debug_immediate_uses().

◆ debug_immediate_uses_for()

DEBUG_FUNCTION void debug_immediate_uses_for ( tree var)
Dump def-use edges on stderr.   

References debug_immediate_uses_for(), and dump_immediate_uses_for().

Referenced by debug_immediate_uses_for().

◆ dump_immediate_uses()

void dump_immediate_uses ( FILE * file)
Dump all the immediate uses to FILE.   

References cfun, dump_immediate_uses(), dump_immediate_uses_for(), and FOR_EACH_SSA_NAME.

Referenced by debug_immediate_uses(), and dump_immediate_uses().

◆ dump_immediate_uses_for()

◆ fini_ssa_operands()

◆ free_stmt_operands()

void free_stmt_operands ( struct function * fn,
gimple * stmt )

◆ gather_imm_use_stmts()

auto_vec< gimple *, 2 > gather_imm_use_stmts ( tree ssavar)
Gather all stmts SSAVAR is used on, eliminating duplicates.   
Use this to get a vector of all gimple stmts using SSAVAR without
duplicates.  It's cheaper than FOR_EACH_IMM_USE_STMT and has no
constraints on what you are allowed to do inside an iteration
over the vector.   

References FOR_EACH_IMM_USE_FAST, gather_imm_use_stmts(), gimple::ilf, and USE_STMT.

Referenced by forward_propagate_addr_expr(), and gather_imm_use_stmts().

◆ gimple_ssa_operands()

◆ init_ssa_operands()

◆ mark_address_taken()

void mark_address_taken ( tree ref)
static
Mark the base address of REF as having its address taken.
REF may be a single variable whose address has been taken or any
other valid GIMPLE memory reference (structure reference, array,
etc).   

References get_base_address(), mark_address_taken(), TREE_ADDRESSABLE, TREE_CODE, and VAR_P.

Referenced by operands_scanner::get_asm_stmt_operands(), operands_scanner::get_expr_operands(), and mark_address_taken().

◆ single_imm_use_1()

bool single_imm_use_1 ( const ssa_use_operand_t * head,
use_operand_p * use_p,
gimple ** stmt )
Return true if the var whose chain of uses starts at PTR has a
single nondebug use.  Set USE_P and STMT to that single nondebug
use, if so, or to NULL otherwise.   

References is_gimple_debug(), ssa_use_operand_t::loc, ssa_use_operand_t::next, NULL, single_imm_use_1(), and USE_STMT.

Referenced by single_imm_use(), and single_imm_use_1().

◆ ssa_operand_alloc()

◆ ssa_operands_active()

◆ swap_ssa_operands()

void swap_ssa_operands ( gimple * stmt,
tree * exp0,
tree * exp1 )
Swap operands EXP0 and EXP1 in statement STMT.  No attempt is done
to test the validity of the swap operation.   

References gimple_use_ops(), use_optype_d::next, NULL, swap_ssa_operands(), and USE_OP_PTR.

Referenced by linearize_expr_tree(), parloops_is_simple_reduction(), reorder_operands(), repropagate_negates(), and swap_ssa_operands().

◆ unlink_stmt_vdef()

void unlink_stmt_vdef ( gimple * stmt)
Unlink STMTs virtual definition from the IL by propagating its use.   

References FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, gimple_vdef(), gimple_vuse(), SET_USE, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, and unlink_stmt_vdef().

Referenced by strlen_pass::adjust_last_stmt(), adjust_simduid_builtins(), cleanup_empty_eh_move_lp(), cond_if_else_store_replacement_1(), cond_store_replacement(), cond_store_replacement_limited(), delete_dead_or_redundant_assignment(), delete_dead_or_redundant_call(), do_simple_agr_dse(), eliminate_dom_walker::eliminate_cleanup(), eliminate_local_variables_stmt(), execute_omp_device_lower(), execute_update_addresses_taken(), expand_call_inline(), expand_ifn_va_arg_1(), operands_scanner::finalize_ssa_defs(), generate_loops_for_partition(), gimple_fold_builtin_memory_op(), gimple_fold_builtin_stdarg(), gimple_fold_partial_load_store(), gimple_ic(), gimple_stringop_fixed_value(), gimplify_and_update_call_from_tree(), gsi_replace_with_seq_vops(), strlen_pass::handle_assign(), strlen_pass::handle_builtin_memset(), strlen_pass::handle_store(), hoist_memory_references(), input_function(), maybe_remove_writeonly_store(), tree_loop_interchange::move_code_to_inner_loop(), optimize_clobbers(), dom_opt_dom_walker::optimize_stmt(), optimize_vector_load(), predicate_statements(), propagate_op_to_single_use(), propagate_with_phi(), remove_dead_stmt(), remove_indirect_clobbers(), remove_prop_source_from_use(), pcom_worker::remove_stmt(), vec_info::remove_stmt(), remove_unused_locals(), replace_call_with_value(), ipa_param_body_adjustments::reset_debug_stmts(), sanopt_optimize_walker(), simple_dce_from_worklist(), simplify_builtin_memcpy_memset(), sink_clobbers(), sink_common_stores_to_bb(), split_function(), sra_modify_assign(), sra_modify_constructor_assign(), sra_modify_deferred_init(), ubsan_expand_bounds_ifn(), ubsan_expand_null_ifn(), ubsan_expand_objsize_ifn(), ubsan_expand_ptr_ifn(), ubsan_expand_vptr_ifn(), loop_cand::undo_simple_reduction(), unlink_stmt_vdef(), vect_remove_slp_scalar_calls(), and vect_transform_loop().

◆ update_stmt_operands()

◆ verify_imm_links()

DEBUG_FUNCTION bool verify_imm_links ( FILE * f,
tree var )
Scan the immediate_use list for VAR making sure its linked properly.
Return TRUE if there is a problem and emit an error message to F.   

References error(), gcc_assert, gimple_modified_p(), ssa_use_operand_t::loc, ssa_use_operand_t::next, NULL, ssa_use_operand_t::prev, print_generic_expr(), print_gimple_stmt(), SSA_NAME_IMM_USE_NODE, TDF_SLIM, TREE_CODE, ssa_use_operand_t::use, USE_FROM_PTR, and verify_imm_links().

Referenced by release_ssa_name_fn(), verify_imm_links(), and verify_use().

◆ verify_ssa_operands()

DEBUG_FUNCTION bool verify_ssa_operands ( struct function * fn,
gimple * stmt )
Interface for external use.   

References operands_scanner::operands_scanner(), and verify_ssa_operands().

Referenced by verify_ssa(), and verify_ssa_operands().