GCC Middle and Back End API Reference
ipa_icf_gimple::func_checker Class Reference

#include <ipa-icf-gimple.h>

Inheritance diagram for ipa_icf_gimple::func_checker:
Collaboration diagram for ipa_icf_gimple::func_checker:

Public Types

enum  operand_access_type { OP_MEMORY , OP_NORMAL }
 
typedef hash_set< treeoperand_access_type_map
 

Public Member Functions

 func_checker ()
 
 func_checker (tree source_func_decl, tree target_func_decl, bool ignore_labels=false, bool tbaa=true, hash_set< symtab_node * > *ignored_source_nodes=NULL, hash_set< symtab_node * > *ignored_target_nodes=NULL)
 
virtual ~func_checker ()
 
void parse_labels (sem_bb *bb)
 
bool compare_bb (sem_bb *bb1, sem_bb *bb2)
 
bool compare_ssa_name (const_tree t1, const_tree t2)
 
bool compare_edge (edge e1, edge e2)
 
bool compare_gimple_call (gcall *s1, gcall *s2)
 
bool compare_gimple_assign (gimple *s1, gimple *s2)
 
bool compare_gimple_cond (gimple *s1, gimple *s2)
 
bool compare_gimple_label (const glabel *s1, const glabel *s2)
 
bool compare_gimple_switch (const gswitch *s1, const gswitch *s2)
 
bool compare_gimple_return (const greturn *s1, const greturn *s2)
 
bool compare_gimple_goto (gimple *s1, gimple *s2)
 
bool compare_gimple_resx (const gresx *s1, const gresx *s2)
 
bool compare_gimple_asm (const gasm *s1, const gasm *s2)
 
bool compare_decl (const_tree t1, const_tree t2)
 
bool safe_for_total_scalarization_p (tree t1, tree t2)
 
bool compare_operand (tree t1, tree t2, operand_access_type type)
 
bool compare_asm_inputs_outputs (tree t1, tree t2, operand_access_type_map *map)
 
bool compare_function_decl (tree t1, tree t2)
 
bool compare_variable_decl (const_tree t1, const_tree t2)
 
bool compare_loops (basic_block bb1, basic_block bb2)
 
bool operand_equal_p (const_tree, const_tree, unsigned int flags) final override
 
void hash_operand (const_tree, inchash::hash &, unsigned flags) final override
 
void hash_operand (const_tree, inchash::hash &, unsigned flags, operand_access_type access)
 

Static Public Member Functions

static bool compatible_polymorphic_types_p (tree t1, tree t2, bool compare_ptr)
 
static bool compatible_types_p (tree t1, tree t2)
 
static void classify_operands (const gimple *stmt, operand_access_type_map *map)
 
static operand_access_type get_operand_access_type (operand_access_type_map *map, tree)
 

Private Types

enum  ao_ref_diff {
  SEMANTICS = 1 , BASE_ALIAS_SET = 2 , REF_ALIAS_SET = 4 , ACCESS_PATH = 8 ,
  DEPENDENCE_CLIQUE = 16
}
 

Private Member Functions

int compare_ao_refs (ao_ref *ref1, ao_ref *ref2, bool lto_streaming_safe, bool tbaa)
 
void hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa, inchash::hash &hstate)
 
bool verify_hash_value (const_tree arg0, const_tree arg1, unsigned int flags, bool *ret)
 

Private Attributes

vec< int > m_source_ssa_names
 
vec< int > m_target_ssa_names
 
tree m_source_func_decl
 
tree m_target_func_decl
 
hash_set< symtab_node * > * m_ignored_source_nodes
 
hash_set< symtab_node * > * m_ignored_target_nodes
 
hash_map< edge, edgem_edge_map
 
hash_map< const_tree, const_treem_decl_map
 
hash_map< const_tree, int > m_label_bb_map
 
bool m_ignore_labels
 
bool m_tbaa
 
bool m_total_scalarization_limit_known_p
 
unsigned HOST_WIDE_INT m_total_scalarization_limit
 

Detailed Description

A class aggregating all connections and semantic equivalents
for a given pair of semantic function candidates.   

Member Typedef Documentation

◆ operand_access_type_map

Member Enumeration Documentation

◆ ao_ref_diff

enum ao_compare::ao_ref_diff
inherited
Enumerator
SEMANTICS 
BASE_ALIAS_SET 
REF_ALIAS_SET 
ACCESS_PATH 
DEPENDENCE_CLIQUE 

◆ operand_access_type

Enumerator
OP_MEMORY 
OP_NORMAL 

Constructor & Destructor Documentation

◆ func_checker() [1/2]

ipa_icf_gimple::func_checker::func_checker ( )
inline

◆ func_checker() [2/2]

ipa_icf_gimple::func_checker::func_checker ( tree source_func_decl,
tree target_func_decl,
bool ignore_labels = false,
bool tbaa = true,
hash_set< symtab_node * > * ignored_source_nodes = NULL,
hash_set< symtab_node * > * ignored_target_nodes = NULL )
Initialize internal structures for a given SOURCE_FUNC_DECL and
TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
an option COMPARE_POLYMORPHIC is true. For special cases, one can
set IGNORE_LABELS to skip label comparison.
Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
of declarations that can be skipped.   

References DECL_STRUCT_FUNCTION, i, m_source_ssa_names, m_target_ssa_names, and SSANAMES.

◆ ~func_checker()

ipa_icf_gimple::func_checker::~func_checker ( )
virtual
Memory release routine.   

References m_source_ssa_names, and m_target_ssa_names.

Member Function Documentation

◆ classify_operands()

void ipa_icf_gimple::func_checker::classify_operands ( const gimple * stmt,
operand_access_type_map * map )
static

◆ compare_ao_refs()

◆ compare_asm_inputs_outputs()

bool ipa_icf_gimple::func_checker::compare_asm_inputs_outputs ( tree t1,
tree t2,
operand_access_type_map * map )

◆ compare_bb()

bool ipa_icf_gimple::func_checker::compare_bb ( sem_bb * bb1,
sem_bb * bb2 )
Basic block equivalence comparison function that returns true if
basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.

In general, a collection of equivalence dictionaries is built for types
like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
is utilized by every statement-by-statement comparison function.   

References as_a(), ipa_icf_gimple::sem_bb::bb, compare_gimple_asm(), compare_gimple_assign(), compare_gimple_call(), compare_gimple_cond(), compare_gimple_goto(), compare_gimple_label(), compare_gimple_resx(), compare_gimple_return(), compare_gimple_switch(), compare_loops(), DECL_STRUCT_FUNCTION, gimple_eh_dispatch_region(), gsi_end_p(), gsi_next_nondebug(), gsi_start_nondebug_bb(), gsi_stmt(), lookup_stmt_eh_lp_fn(), m_source_func_decl, m_target_func_decl, return_different_stmts, return_false, and return_false_with_msg.

Referenced by ipa_icf::sem_function::equals_private().

◆ compare_decl()

◆ compare_edge()

bool ipa_icf_gimple::func_checker::compare_edge ( edge e1,
edge e2 )

◆ compare_function_decl()

bool ipa_icf_gimple::func_checker::compare_function_decl ( tree t1,
tree t2 )

◆ compare_gimple_asm()

bool ipa_icf_gimple::func_checker::compare_gimple_asm ( const gasm * g1,
const gasm * g2 )
Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
For the beginning, the pass only supports equality for
'__asm__ __volatile__ ("", "", "", "memory")'.   

References classify_operands(), compare_asm_inputs_outputs(), gimple_asm_basic_p(), gimple_asm_clobber_op(), gimple_asm_inline_p(), gimple_asm_input_op(), gimple_asm_nclobbers(), gimple_asm_ninputs(), gimple_asm_nlabels(), gimple_asm_noutputs(), gimple_asm_output_op(), gimple_asm_string(), gimple_asm_volatile_p(), i, map, OEP_ONLY_CONST, operand_equal_p(), return_false_with_msg, and TREE_VALUE.

Referenced by compare_bb().

◆ compare_gimple_assign()

bool ipa_icf_gimple::func_checker::compare_gimple_assign ( gimple * s1,
gimple * s2 )
Verifies for given GIMPLEs S1 and S2 that
assignment statements are semantically equivalent.   

References classify_operands(), compare_operand(), compatible_types_p(), get_operand_access_type(), gimple_assign_rhs_code(), gimple_num_ops(), gimple_op(), gimple_store_p(), i, map, return_false_with_msg, and TREE_TYPE.

Referenced by compare_bb().

◆ compare_gimple_call()

◆ compare_gimple_cond()

bool ipa_icf_gimple::func_checker::compare_gimple_cond ( gimple * s1,
gimple * s2 )
Verifies for given GIMPLEs S1 and S2 that
condition statements are semantically equivalent.   

References compare_operand(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), and OP_NORMAL.

Referenced by compare_bb().

◆ compare_gimple_goto()

bool ipa_icf_gimple::func_checker::compare_gimple_goto ( gimple * g1,
gimple * g2 )
Verifies for given GIMPLEs S1 and S2 that
goto statements are semantically equivalent.   

References compare_operand(), gimple_goto_dest(), OP_NORMAL, and TREE_CODE.

Referenced by compare_bb().

◆ compare_gimple_label()

bool ipa_icf_gimple::func_checker::compare_gimple_label ( const glabel * g1,
const glabel * g2 )
Verifies for given GIMPLE_LABEL stmts S1 and S2 that
label statements are semantically equivalent.   

References FORCED_LABEL, gimple_label_label(), m_ignore_labels, and return_false_with_msg.

Referenced by compare_bb().

◆ compare_gimple_resx()

bool ipa_icf_gimple::func_checker::compare_gimple_resx ( const gresx * g1,
const gresx * g2 )
Verifies for given GIMPLE_RESX stmts S1 and S2 that
resx statements are semantically equivalent.   

References gimple_resx_region().

Referenced by compare_bb().

◆ compare_gimple_return()

bool ipa_icf_gimple::func_checker::compare_gimple_return ( const greturn * g1,
const greturn * g2 )
Verifies for given GIMPLE_RETURN stmts S1 and S2 that
return statements are semantically equivalent.   

References compare_operand(), get_operand_access_type(), gimple_return_retval(), map, and NULL.

Referenced by compare_bb().

◆ compare_gimple_switch()

bool ipa_icf_gimple::func_checker::compare_gimple_switch ( const gswitch * g1,
const gswitch * g2 )
Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
switch statements are semantically equivalent.   

References CASE_HIGH, CASE_LABEL, CASE_LOW, compare_operand(), gimple_switch_index(), gimple_switch_label(), gimple_switch_num_labels(), i, OP_NORMAL, return_false_with_msg, TREE_CODE, and tree_int_cst_equal().

Referenced by compare_bb().

◆ compare_loops()

◆ compare_operand()

◆ compare_ssa_name()

bool ipa_icf_gimple::func_checker::compare_ssa_name ( const_tree t1,
const_tree t2 )
Verifies that trees T1 and T2 are equivalent from perspective of ICF.   

References compare_operand(), gcc_assert, i1, i2, m_source_ssa_names, m_target_ssa_names, OP_NORMAL, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_VAR, SSA_NAME_VERSION, and TREE_CODE.

Referenced by operand_equal_p().

◆ compare_variable_decl()

bool ipa_icf_gimple::func_checker::compare_variable_decl ( const_tree t1,
const_tree t2 )

◆ compatible_polymorphic_types_p()

bool ipa_icf_gimple::func_checker::compatible_polymorphic_types_p ( tree t1,
tree t2,
bool compare_ptr )
static
Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
analysis.  COMPARE_PTR indicates if types of pointers needs to be
considered.   

References compare_ptr(), compatible_polymorphic_types_p(), contains_polymorphic_type_p(), gcc_assert, POINTER_TYPE_P, return_false_with_msg, TREE_CODE, TREE_TYPE, and types_must_be_same_for_odr().

Referenced by compatible_polymorphic_types_p(), and ipa_icf::sem_function::equals_wpa().

◆ compatible_types_p()

bool ipa_icf_gimple::func_checker::compatible_types_p ( tree t1,
tree t2 )
static

◆ get_operand_access_type()

func_checker::operand_access_type ipa_icf_gimple::func_checker::get_operand_access_type ( operand_access_type_map * map,
tree t )
static

◆ hash_ao_ref()

◆ hash_operand() [1/2]

void ipa_icf_gimple::func_checker::hash_operand ( const_tree ,
inchash::hash & ,
unsigned flags )
finaloverridevirtual
Generate a hash value for an expression.  This can be used iteratively
by passing a previous result as the HSTATE argument.   

Reimplemented from operand_compare.

Referenced by ipa_icf::sem_function::hash_stmt(), ipa_icf::sem_function::init(), and ipa_icf::sem_variable::init().

◆ hash_operand() [2/2]

void ipa_icf_gimple::func_checker::hash_operand ( const_tree ,
inchash::hash & ,
unsigned flags,
operand_access_type access )

◆ operand_equal_p()

bool ipa_icf_gimple::func_checker::operand_equal_p ( const_tree arg0,
const_tree arg1,
unsigned int flags )
finaloverridevirtual
Return nonzero if two operands (typically of the same tree node)
are necessarily equal. FLAGS modifies behavior as follows:

If OEP_ONLY_CONST is set, only return nonzero for constants.
This function tests whether the operands are indistinguishable;
it does not test whether they are equal using C's == operation.
The distinction is important for IEEE floating point, because
(1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
(2) two NaNs may be indistinguishable, but NaN!=NaN.

If OEP_ONLY_CONST is unset, a VAR_DECL is considered equal to itself
even though it may hold multiple values during a function.
This is because a GCC tree node guarantees that nothing else is
executed between the evaluation of its "operands" (which may often
be evaluated in arbitrary order).  Hence if the operands themselves
don't side-effect, the VAR_DECLs, PARM_DECLs etc... must hold the
same value in each operand/subexpression.  Hence leaving OEP_ONLY_CONST
unset means assuming isochronic (or instantaneous) tree equivalence.
Unless comparing arbitrary expression trees, such as from different
statements, this flag can usually be left unset.

If OEP_PURE_SAME is set, then pure functions with identical arguments
are considered the same.  It is used when the caller has other ways
to ensure that global memory is unchanged in between.

If OEP_ADDRESS_OF is set, we are actually comparing addresses of objects,
not values of expressions.

If OEP_LEXICOGRAPHIC is set, then also handle expressions with side-effects
such as MODIFY_EXPR, RETURN_EXPR, as well as STATEMENT_LISTs.

If OEP_BITWISE is set, then require the values to be bitwise identical
rather than simply numerically equal.  Do not take advantage of things
like math-related flags or undefined behavior; only return true for
values that are provably bitwise identical in all circumstances.

If OEP_ASSUME_WRAPV is set, then require the values to be bitwise identical
under two's compliment arithmetic (ignoring any possible Undefined Behaviour)
rather than just numerically equivalent.  The compared expressions must
however perform the same operations but may do intermediate computations in
differing signs.  Because this comparison ignores any possible UB it cannot
be used blindly without ensuring that the context you are using it in itself
doesn't guarantee that there will be no UB.  Conditional expressions are
excluded from this relaxation.

When OEP_ASSUME_WRAPV is used operand_compare::hash_operand may return
differing hashes even for cases where operand_compare::operand_equal_p
compares equal.

Unless OEP_MATCH_SIDE_EFFECTS is set, the function returns false on
any operand with side effect.  This is unnecesarily conservative in the
case we know that arg0 and arg1 are in disjoint code paths (such as in
?: operator).  In addition OEP_MATCH_SIDE_EFFECTS is used when comparing
addresses with TREE_CONSTANT flag set so we know that &var == &var
even if var is volatile.   

Reimplemented from operand_compare.

References compare_decl(), compare_ssa_name(), compare_variable_decl(), hash_map< KeyId, Value, Traits >::get(), m_label_bb_map, NULL, operand_compare::operand_equal_p(), r, return_false, return_with_debug, TREE_CLOBBER_P, TREE_CODE, and operand_compare::verify_hash_value().

Referenced by compare_decl(), compare_gimple_asm(), and compare_operand().

◆ parse_labels()

void ipa_icf_gimple::func_checker::parse_labels ( sem_bb * bb)
Function visits all gimple labels and creates corresponding
mapping between basic blocks and labels.   

References ipa_icf_gimple::sem_bb::bb, dyn_cast(), gcc_assert, gimple_label_label(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), basic_block_def::index, m_label_bb_map, hash_map< KeyId, Value, Traits >::put(), and TREE_CODE.

Referenced by ipa_icf::sem_function::equals_private().

◆ safe_for_total_scalarization_p()

bool ipa_icf_gimple::func_checker::safe_for_total_scalarization_p ( tree t1,
tree t2 )
Return true if either T1 and T2 cannot be totally scalarized or if doing
so would result in copying the same memory.  Otherwise return false.   

References AGGREGATE_TYPE_P, DECL_STRUCT_FUNCTION, gcc_assert, m_target_func_decl, m_total_scalarization_limit, m_total_scalarization_limit_known_p, pop_cfun(), push_cfun(), sra_get_max_scalarization_size(), sra_total_scalarization_would_copy_same_data_p(), tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, and TYPE_SIZE.

Referenced by compare_operand().

◆ verify_hash_value()

Field Documentation

◆ m_decl_map

hash_map<const_tree, const_tree> ipa_icf_gimple::func_checker::m_decl_map
private

Referenced by compare_decl().

◆ m_edge_map

hash_map<edge, edge> ipa_icf_gimple::func_checker::m_edge_map
private

Referenced by compare_edge().

◆ m_ignore_labels

bool ipa_icf_gimple::func_checker::m_ignore_labels
private

Referenced by compare_gimple_label().

◆ m_ignored_source_nodes

hash_set<symtab_node *>* ipa_icf_gimple::func_checker::m_ignored_source_nodes
private

◆ m_ignored_target_nodes

hash_set<symtab_node *>* ipa_icf_gimple::func_checker::m_ignored_target_nodes
private

◆ m_label_bb_map

hash_map<const_tree, int> ipa_icf_gimple::func_checker::m_label_bb_map
private

Referenced by operand_equal_p(), and parse_labels().

◆ m_source_func_decl

tree ipa_icf_gimple::func_checker::m_source_func_decl
private

◆ m_source_ssa_names

vec<int> ipa_icf_gimple::func_checker::m_source_ssa_names
private

◆ m_target_func_decl

tree ipa_icf_gimple::func_checker::m_target_func_decl
private

◆ m_target_ssa_names

vec<int> ipa_icf_gimple::func_checker::m_target_ssa_names
private

◆ m_tbaa

bool ipa_icf_gimple::func_checker::m_tbaa
private

Referenced by compare_operand().

◆ m_total_scalarization_limit

unsigned HOST_WIDE_INT ipa_icf_gimple::func_checker::m_total_scalarization_limit
private

◆ m_total_scalarization_limit_known_p

bool ipa_icf_gimple::func_checker::m_total_scalarization_limit_known_p
private

The documentation for this class was generated from the following files: