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


#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 *))


static struct ssa_operandsgimple_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_dalloc_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)

Macro Definition Documentation


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

Referenced by ssa_operand_alloc().


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

Referenced by ssa_operand_alloc().


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

Referenced by ssa_operand_alloc().


#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

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-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
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()

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

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

Referenced by operands_scanner::finalize_ssa_uses().

◆ alloc_use()

static struct use_optype_d * alloc_use ( struct function * fn)
Allocate a USE operand.   

References ssa_operands::free_uses, gimple_ssa_operands(), use_optype_d::next, and ssa_operand_alloc().

Referenced by add_use_op().

◆ create_vop_var()

static void create_vop_var ( struct function * fn)
Create the VOP variable, an artificial global variable to act as a
representative of all of the virtual operands FUD chain.   


Referenced by init_ssa_operands().

◆ debug_immediate_uses()

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

References dump_immediate_uses().

◆ debug_immediate_uses_for()

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

References dump_immediate_uses_for().

◆ dump_immediate_uses()

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

References cfun, dump_immediate_uses_for(), and FOR_EACH_SSA_NAME.

Referenced by debug_immediate_uses().

◆ dump_immediate_uses_for()

◆ fini_ssa_operands()

void fini_ssa_operands ( struct function * fn)

◆ free_stmt_operands()

void free_stmt_operands ( struct function * fn,
gimple * stmt )
Releases the operands of STMT back to their freelists, and clears
the stmt operand lists.   

References delink_imm_use(), ssa_operands::free_uses, gimple_has_mem_ops(), gimple_set_use_ops(), gimple_set_vdef(), gimple_set_vuse(), gimple_ssa_operands(), gimple_use_ops(), use_optype_d::next, NULL, NULL_TREE, and USE_OP_PTR.

Referenced by move_block_to_fn().

◆ gimple_ssa_operands()

static struct ssa_operands * gimple_ssa_operands ( const struct function * fun)

◆ init_ssa_operands()

◆ mark_address_taken()

static void mark_address_taken ( tree ref)
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,

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

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

◆ 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::next, NULL, single_use(), and USE_STMT.

Referenced by single_imm_use().

◆ ssa_operand_alloc()

◆ ssa_operands_active()

bool ssa_operands_active ( struct function * fun)

◆ 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, and USE_OP_PTR.

Referenced by linearize_expr_tree(), optimize_vec_cond_expr(), parloops_is_simple_reduction(), parloops_is_slp_reduction(), reorder_operands(), and repropagate_negates().

◆ unlink_stmt_vdef()

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


Referenced by strlen_pass::adjust_last_stmt(), adjust_simduid_builtins(), cleanup_empty_eh_move_lp(), cond_if_else_store_replacement_1(), cond_store_replacement(), delete_dead_or_redundant_assignment(), delete_dead_or_redundant_call(), 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_ic(), gimple_stringop_fixed_value(), gimplify_and_update_call_from_tree(), gsi_replace_with_seq_vops(), strlen_pass::handle_builtin_memset(), strlen_pass::handle_store(), 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_call(), sink_clobbers(), sink_common_stores_to_bb(), 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(), vect_remove_slp_scalar_calls(), vect_transform_loop(), and vectorizable_simd_clone_call().

◆ update_stmt_operands()

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

◆ 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 count, 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, ssa_use_operand_t::stmt, TDF_SLIM, TREE_CODE, ssa_use_operand_t::use, and USE_FROM_PTR.

Referenced by release_ssa_name_fn(), and verify_use().

◆ verify_ssa_operands()

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

References operands_scanner::verify_ssa_operands().

Referenced by verify_ssa().