GCC Middle and Back End API Reference
tree-complex.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
#include "tree-hasher.h"
#include "cfgloop.h"
#include "cfganal.h"
#include "gimple-fold.h"
#include "diagnostic-core.h"
#include "case-cfn-macros.h"
#include "builtins.h"
#include "optabs-tree.h"
#include "tree-ssa-dce.h"
Include dependency graph for tree-complex.cc:

Data Structures

class  complex_propagate
 

Macros

#define PAIR(a, b)
 

Typedefs

typedef int complex_lattice_t
 

Enumerations

enum  { UNINITIALIZED = 0 , ONLY_REAL = 1 , ONLY_IMAG = 2 , VARYING = 3 }
 

Functions

static tree cvc_lookup (unsigned int uid)
 
static void cvc_insert (unsigned int uid, tree to)
 
static int some_nonzerop (tree t)
 
static complex_lattice_t find_lattice_value_parts (tree real, tree imag)
 
static complex_lattice_t find_lattice_value (tree t)
 
static bool is_complex_reg (tree lhs)
 
static void init_parameter_lattice_values (void)
 
static bool init_dont_simulate_again (void)
 
static tree create_one_component_var (tree type, tree orig, const char *prefix, const char *suffix, enum tree_code code)
 
static tree get_component_var (tree var, bool imag_p)
 
static tree get_component_ssa_name (tree ssa_name, bool imag_p)
 
static gimple_seq set_component_ssa_name (tree ssa_name, bool imag_p, tree value)
 
static tree extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p, bool gimple_p, bool phiarg_p=false)
 
static void update_complex_components (gimple_stmt_iterator *gsi, gimple *stmt, tree r, tree i)
 
static void update_complex_components_on_edge (edge e, tree lhs, tree r, tree i)
 
static void update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
 
static void update_parameter_components (void)
 
static void update_phi_components (basic_block bb)
 
static void expand_complex_move (gimple_stmt_iterator *gsi, tree type)
 
static void expand_complex_addition (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai, tree br, tree bi, enum tree_code code, complex_lattice_t al, complex_lattice_t bl)
 
static tree expand_complex_libcall (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai, tree br, tree bi, enum tree_code code, bool inplace_p)
 
static void expand_complex_multiplication_components (gimple_seq *stmts, location_t loc, tree type, tree ar, tree ai, tree br, tree bi, tree *rr, tree *ri)
 
static void expand_complex_multiplication (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai, tree br, tree bi, complex_lattice_t al, complex_lattice_t bl)
 
static void expand_complex_div_straight (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai, tree br, tree bi, enum tree_code code)
 
static void expand_complex_div_wide (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai, tree br, tree bi, enum tree_code code)
 
static void expand_complex_division (gimple_stmt_iterator *gsi, tree type, tree ar, tree ai, tree br, tree bi, enum tree_code code, complex_lattice_t al, complex_lattice_t bl)
 
static void expand_complex_negation (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai)
 
static void expand_complex_paren (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai)
 
static void expand_complex_conjugate (gimple_stmt_iterator *gsi, tree inner_type, tree ar, tree ai)
 
static void expand_complex_comparison (gimple_stmt_iterator *gsi, tree ar, tree ai, tree br, tree bi, enum tree_code code)
 
static void expand_complex_asm (gimple_stmt_iterator *gsi)
 
static void gimple_expand_builtin_cabs (gimple_stmt_iterator *gsi, gimple *old_stmt)
 
static void expand_complex_operations_1 (gimple_stmt_iterator *gsi)
 
static unsigned int tree_lower_complex (void)
 
gimple_opt_passmake_pass_lower_complex (gcc::context *ctxt)
 
gimple_opt_passmake_pass_lower_complex_O0 (gcc::context *ctxt)
 

Variables

static vec< complex_lattice_tcomplex_lattice_values
 
static int_tree_htab_typecomplex_variable_components
 
static vec< treecomplex_ssa_name_components
 
static vec< gphi * > phis_to_revisit
 
static bitmap need_eh_cleanup
 
static bitmap dce_worklist
 

Macro Definition Documentation

◆ PAIR

#define PAIR ( a,
b )
Value:
((a) << 2 | (b))
Ca const poly_int< N, Cb > & b
Definition poly-int.h:771
Ca & a
Definition poly-int.h:770

Referenced by expand_complex_addition(), expand_complex_division(), and expand_complex_multiplication().

Typedef Documentation

◆ complex_lattice_t

typedef int complex_lattice_t
The type complex_lattice_t holds combinations of the above
constants.   

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Lower complex number operations to scalar operations.
   Copyright (C) 2004-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 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/>.   
For each complex ssa name, a lattice value.  We're interested in finding
out whether a complex number is degenerate in some way, having only real
or only complex parts.   
Enumerator
UNINITIALIZED 
ONLY_REAL 
ONLY_IMAG 
VARYING 

Function Documentation

◆ create_one_component_var()

static tree create_one_component_var ( tree type,
tree orig,
const char * prefix,
const char * suffix,
enum tree_code code )
static

◆ cvc_insert()

static void cvc_insert ( unsigned int uid,
tree to )
static
Insert the pair UID, TO into the complex_variable_components hashtable.   

References complex_variable_components, hash_table< Descriptor, Lazy, Allocator >::find_slot_with_hash(), int_tree_map::to, and int_tree_map::uid.

Referenced by get_component_var().

◆ cvc_lookup()

static tree cvc_lookup ( unsigned int uid)
static
Lookup UID in the complex_variable_components hashtable and return the
associated tree.   

References complex_variable_components, hash_table< Descriptor, Lazy, Allocator >::find_with_hash(), and int_tree_map::uid.

Referenced by get_component_var().

◆ expand_complex_addition()

static void expand_complex_addition ( gimple_stmt_iterator * gsi,
tree inner_type,
tree ar,
tree ai,
tree br,
tree bi,
enum tree_code code,
complex_lattice_t al,
complex_lattice_t bl )
static
Expand complex addition to scalars:
       a + b = (ar + br) + i(ai + bi)
       a - b = (ar - br) + i(ai + bi)

References gcc_unreachable, gimple_build(), gimple_location(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), NULL, ONLY_IMAG, ONLY_REAL, operand_equal_p(), PAIR, update_complex_assignment(), and VARYING.

Referenced by expand_complex_operations_1().

◆ expand_complex_asm()

◆ expand_complex_comparison()

◆ expand_complex_conjugate()

static void expand_complex_conjugate ( gimple_stmt_iterator * gsi,
tree inner_type,
tree ar,
tree ai )
static
Expand complex conjugate to scalars:
       ~a = (ar) + i(-ai)

References gimple_build(), gimple_location(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), NULL, and update_complex_assignment().

Referenced by expand_complex_operations_1().

◆ expand_complex_div_straight()

static void expand_complex_div_straight ( gimple_stmt_iterator * gsi,
tree inner_type,
tree ar,
tree ai,
tree br,
tree bi,
enum tree_code code )
static
Keep this algorithm in sync with fold-const.cc:const_binop().

  Expand complex division to scalars, straightforward algorithm.
       a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
           t = br*br + bi*bi

References gimple_build(), gimple_location(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), NULL, and update_complex_assignment().

Referenced by expand_complex_division().

◆ expand_complex_div_wide()

◆ expand_complex_division()

◆ expand_complex_libcall()

static tree expand_complex_libcall ( gimple_stmt_iterator * gsi,
tree type,
tree ar,
tree ai,
tree br,
tree bi,
enum tree_code code,
bool inplace_p )
static
Expand a complex multiplication or division to a libcall to the c99
compliant routines.  TYPE is the complex type of the operation.
If INPLACE_P replace the statement at GSI with
the libcall and return NULL_TREE.  Else insert the call, assign its
result to an output variable and return that variable.  If INPLACE_P
is true then the statement being replaced should be an assignment
statement.   

References build1(), BUILT_IN_COMPLEX_DIV_MIN, builtin_decl_explicit(), cfun, FOR_EACH_EDGE, gcc_assert, gcc_unreachable, GET_MODE_CLASS, gimple_assign_lhs(), gimple_bb(), gimple_build_call(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gsi_insert_before(), gsi_replace(), GSI_SAME_STMT, gsi_start_bb(), gsi_stmt(), make_ssa_name(), NULL_TREE, split_edge(), SSA_NAME_DEF_STMT, stmt_can_throw_internal(), stmt_could_throw_p(), TREE_TYPE, TYPE_MODE, and update_complex_components().

Referenced by expand_complex_division(), and expand_complex_multiplication().

◆ expand_complex_move()

◆ expand_complex_multiplication()

◆ expand_complex_multiplication_components()

static void expand_complex_multiplication_components ( gimple_seq * stmts,
location_t loc,
tree type,
tree ar,
tree ai,
tree br,
tree bi,
tree * rr,
tree * ri )
static
Perform a complex multiplication on two complex constants A, B represented
by AR, AI, BR, BI of type TYPE.
The operation we want is: a * b = (ar*br - ai*bi) + i(ar*bi + br*ai).
Insert the GIMPLE statements into GSI.  Store the real and imaginary
components of the result into RR and RI.   

References gimple_build().

Referenced by expand_complex_multiplication().

◆ expand_complex_negation()

static void expand_complex_negation ( gimple_stmt_iterator * gsi,
tree inner_type,
tree ar,
tree ai )
static
Expand complex negation to scalars:
       -a = (-ar) + i(-ai)

References gimple_build(), gimple_location(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), NULL, and update_complex_assignment().

Referenced by expand_complex_operations_1().

◆ expand_complex_operations_1()

◆ expand_complex_paren()

static void expand_complex_paren ( gimple_stmt_iterator * gsi,
tree inner_type,
tree ar,
tree ai )
static
Expand complex paren to scalars:
       ((a)) = ((ar)) + i((ai))

References gimple_build(), gimple_location(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), NULL, and update_complex_assignment().

Referenced by expand_complex_operations_1().

◆ extract_component()

static tree extract_component ( gimple_stmt_iterator * gsi,
tree t,
bool imagpart_p,
bool gimple_p,
bool phiarg_p = false )
static
Extract the real or imaginary part of a complex variable or constant.
Make sure that it's a proper gimple_val and gimplify it if not.
Emit any new code before gsi.   

References build1(), force_gimple_operand_gsi(), gcc_assert, gcc_unreachable, get_component_ssa_name(), GSI_SAME_STMT, NULL, size_binop, SSA_NAME_DEF_STMT, TREE_CODE, TREE_IMAGPART, TREE_OPERAND, TREE_REALPART, TREE_TYPE, TYPE_SIZE, and unshare_expr().

Referenced by expand_complex_move(), expand_complex_operations_1(), gimple_expand_builtin_cabs(), tree_lower_complex(), and update_phi_components().

◆ find_lattice_value()

◆ find_lattice_value_parts()

static complex_lattice_t find_lattice_value_parts ( tree real,
tree imag )
static
Compute a lattice value from the components of a complex type REAL
and IMAG.   

References i, ONLY_IMAG, ONLY_REAL, r, some_nonzerop(), and UNINITIALIZED.

Referenced by find_lattice_value(), and complex_propagate::visit_stmt().

◆ get_component_ssa_name()

◆ get_component_var()

static tree get_component_var ( tree var,
bool imag_p )
static
Retrieve a value for a complex component of VAR.   

References create_one_component_var(), cvc_insert(), cvc_lookup(), DECL_UID, NULL, and TREE_TYPE.

Referenced by get_component_ssa_name(), and set_component_ssa_name().

◆ gimple_expand_builtin_cabs()

static void gimple_expand_builtin_cabs ( gimple_stmt_iterator * gsi,
gimple * old_stmt )
static
ARG is the argument to a cabs builtin call in GSI from the
original OLD_STMT.  Create a sequence of statements prior
to GSI that calculates sqrt(R*R + I*I), where R and
I are the real and imaginary components of ARG, respectively.   

References build_real_truncate(), dconst_sqrt2, extract_component(), gimple_bb(), gimple_build(), gimple_build_assign(), gimple_build_call(), gimple_call_arg(), gimple_call_lhs(), gimple_call_set_lhs(), gimple_location(), gimple_set_location(), gsi_insert_seq_before(), gsi_replace(), GSI_SAME_STMT, mathfn_built_in(), NULL, operand_equal_p(), optab_handler(), optimize_bb_for_speed_p(), real_zerop(), TREE_TYPE, and TYPE_MODE.

Referenced by expand_complex_operations_1().

◆ init_dont_simulate_again()

◆ init_parameter_lattice_values()

static void init_parameter_lattice_values ( void )
static
Mark the incoming parameters to the function as VARYING.   

References cfun, complex_lattice_values, DECL_ARGUMENTS, DECL_CHAIN, is_complex_reg(), NULL_TREE, ssa_default_def(), ssa_name, SSA_NAME_VERSION, and VARYING.

Referenced by tree_lower_complex().

◆ is_complex_reg()

static bool is_complex_reg ( tree lhs)
static
Determine if LHS is something for which we're interested in seeing
simulation results.   

References is_gimple_reg(), TREE_CODE, and TREE_TYPE.

Referenced by init_dont_simulate_again(), init_parameter_lattice_values(), and update_phi_components().

◆ make_pass_lower_complex()

gimple_opt_pass * make_pass_lower_complex ( gcc::context * ctxt)

◆ make_pass_lower_complex_O0()

gimple_opt_pass * make_pass_lower_complex_O0 ( gcc::context * ctxt)

◆ set_component_ssa_name()

◆ some_nonzerop()

static int some_nonzerop ( tree t)
static
Return true if T is not a zero constant.  In the case of real values,
we're only interested in +0.0.   

References dconst0, fixed_zerop(), integer_zerop(), real_identical(), TREE_CODE, TREE_REAL_CST, and zerop().

Referenced by find_lattice_value_parts().

◆ tree_lower_complex()

◆ update_complex_assignment()

◆ update_complex_components()

static void update_complex_components ( gimple_stmt_iterator * gsi,
gimple * stmt,
tree r,
tree i )
static
Update the complex components of the ssa name on the lhs of STMT.   

References gimple_get_lhs(), GSI_CONTINUE_LINKING, gsi_insert_seq_after(), i, r, and set_component_ssa_name().

Referenced by expand_complex_libcall(), expand_complex_move(), and update_complex_assignment().

◆ update_complex_components_on_edge()

static void update_complex_components_on_edge ( edge e,
tree lhs,
tree r,
tree i )
static

◆ update_parameter_components()

static void update_parameter_components ( void )
static
Generate code at the entry point of the function to initialize the
component variables for a complex parameter.   

References build1(), cfun, DECL_ARGUMENTS, DECL_CHAIN, ENTRY_BLOCK_PTR_FOR_FN, i, is_gimple_reg(), r, single_succ_edge(), ssa_default_def(), ssa_name, TREE_CODE, TREE_TYPE, and update_complex_components_on_edge().

Referenced by tree_lower_complex().

◆ update_phi_components()

static void update_phi_components ( basic_block bb)
static

Variable Documentation

◆ complex_lattice_values

◆ complex_ssa_name_components

vec<tree> complex_ssa_name_components
static
For each complex SSA_NAME, a pair of ssa names for the components.   

Referenced by get_component_ssa_name(), set_component_ssa_name(), and tree_lower_complex().

◆ complex_variable_components

int_tree_htab_type* complex_variable_components
static
For each complex variable, a pair of variables for the components exists in
the hashtable.   

Referenced by cvc_insert(), cvc_lookup(), and tree_lower_complex().

◆ dce_worklist

◆ need_eh_cleanup

◆ phis_to_revisit

vec<gphi *> phis_to_revisit
static
Vector of PHI triplets (original complex PHI and corresponding real and
imag PHIs if real and/or imag PHIs contain temporarily
non-SSA_NAME/non-invariant args that need to be replaced by SSA_NAMEs.   

Referenced by tree_lower_complex(), and update_phi_components().