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

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

◆ cvc_insert()

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

References complex_variable_components, int_tree_map::to, and int_tree_map::uid.

Referenced by get_component_var().

◆ cvc_lookup()

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

References complex_variable_components, and int_tree_map::uid.

Referenced by get_component_var().

◆ expand_complex_addition()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

◆ update_parameter_components()

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

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