GCC Middle and Back End API Reference
|
Typedefs | |
typedef int | complex_lattice_t |
Enumerations | |
enum | { UNINITIALIZED = 0, ONLY_REAL = 1, ONLY_IMAG = 2, VARYING = 3 } |
Variables | |
static vec< complex_lattice_t > | complex_lattice_values |
static int_tree_htab_type | complex_variable_components |
static vec< tree > | complex_ssa_name_components |
typedef int complex_lattice_t |
The type complex_lattice_t holds combinations of the above constants.
anonymous enum |
@verbatim
Lower complex number operations to scalar operations. Copyright (C) 2004-2013 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.
|
static |
Evaluate a PHI node against the complex lattice defined above.
This condition should be satisfied due to the initial filter set up in init_dont_simulate_again.
We've set up the lattice values such that IOR neatly models PHI meet.
References create_tmp_var(), and get_identifier().
|
static |
Evaluate statement STMT against the complex lattice defined above.
Skip anything but GIMPLE_ASSIGN and GIMPLE_CALL with a lhs.
These conditions should be satisfied due to the initial filter set up in init_dont_simulate_again.
We've set up the lattice values such that IOR neatly models addition.
Obviously, if either varies, so does the result.
Don't prematurely promote variables if we've not yet seen their inputs.
At this point both numbers have only one component. If the numbers are of opposite kind, the result is imaginary, otherwise the result is real. The add/subtract translates the real/imag from/to 0/1; the ^ performs the comparison.
Don't allow the lattice value to flip-flop indefinitely.
If nothing changed this round, let the propagator know.
|
static |
Create one backing variable for a complex component of ORIG.
References cvc_insert(), and cvc_lookup().
|
static |
Insert the pair UID, TO into the complex_variable_components hashtable.
Referenced by create_one_component_var().
|
static |
Lookup UID in the complex_variable_components hashtable and return the associated tree.
Referenced by create_one_component_var().
|
static |
@verbatim
Expand complex addition to scalars: a + b = (ar + br) + i(ai + bi) a - b = (ar - br) + i(ai + bi)
|
static |
Expand inline asm that sets some complex SSA_NAMEs.
|
static |
Expand complex comparison (EQ or NE only).
|
static |
@verbatim
Expand complex conjugate to scalars: ~a = (ar) + i(-ai)
References GSI_CONTINUE_LINKING, gsi_insert_seq_after(), and set_component_ssa_name().
|
static |
@verbatim
Keep this algorithm in sync with fold-const.c: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
|
static |
Keep this algorithm in sync with fold-const.c:const_binop(). Expand complex division to scalars, modified algorithm to minimize overflow with wide input ranges.
Examine |br| < |bi|, and branch.
Split the original block, and create the TRUE and FALSE blocks.
Wire the blocks together.
Update dominance info. Note that bb_join's data was updated by split_block.
In the TRUE branch, we compute ratio = br/bi; div = (br * ratio) + bi; tr = (ar * ratio) + ai; ti = (ai * ratio) - ar; tr = tr / div; ti = ti / div;
In the FALSE branch, we compute ratio = d/c; divisor = (d * ratio) + c; tr = (b * ratio) + a; ti = b - (a * ratio); tr = tr / div; ti = ti / div;
|
static |
Expand complex division to scalars.
straightforward implementation of complex divide acceptable.
FALLTHRU
wide ranges of inputs must work for complex divide.
|
static |
Expand a complex multiplication or division to a libcall to the c99 compliant routines.
References dconst1, gimplify_build1(), gimplify_build2(), ONLY_REAL, and VARYING.
|
static |
Expand a complex move to scalars.
The value is not assigned on the exception edges, so we need not concern ourselves there. We do need to update on the fallthru edge. Find it.
|
static |
@verbatim
Expand complex multiplication to scalars: a * b = (ar*br - ai*bi) + i(ar*bi + br*ai)
Avoid expanding redundant multiplication for the common case of squaring a complex number.
|
static |
@verbatim
Expand complex negation to scalars: -a = (-ar) + i(-ai)
|
static |
Process one statement. If we identify a complex operation, expand it.
Initial filter for operations we handle.
Note, both GIMPLE_ASSIGN and GIMPLE_COND may have an EQ_EXPR subcode, so we need to access the operands using gimple_op.
GIMPLE_COND may also fallthru here, but we do not need to do anything with it.
Extract the components of the two complex values. Make sure and handle the common case of the same value used twice specially.
GIMPLE_CALL can not get here.
|
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 gimple_get_lhs(), GSI_CONTINUE_LINKING, gsi_insert_seq_after(), and set_component_ssa_name().
|
static |
Compute a lattice value from gimple_val T.
|
static |
Compute a lattice value from the components of a complex type REAL and IMAG.
??? On occasion we could do better than mapping 0+0i to real, but we certainly don't want to leave it UNINITIALIZED, which eventually gets mapped to VARYING.
|
static |
With errors, normal optimization passes are not run. If we don't lower complex operations at all, rtl expansion will abort.
|
static |
Retrieve a value for a complex component of SSA_NAME.
Copy some properties from the original. In particular, whether it is used in an abnormal phi, and whether it's uninitialized.
Referenced by update_complex_assignment().
|
static |
Retrieve a value for a complex component of VAR.
Referenced by set_component_ssa_name().
|
static |
Initialize simulation state for each statement. Return false if we found no statements we want to simulate, and thus there's nothing for the entire pass to do.
Most control-altering statements must be initially simulated, else we won't cover the entire cfg.
The total store transformation performed during gimplification creates such uninitialized loads and we need to lower the statement to be able to fix things up.
|
static |
Mark the incoming parameters to the function as VARYING.
References gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), is_complex_reg(), and prop_set_simulate_again().
|
static |
Determine if LHS is something for which we're interested in seeing simulation results.
Referenced by init_parameter_lattice_values(), and update_complex_assignment().
gimple_opt_pass* make_pass_lower_complex | ( | ) |
gimple_opt_pass* make_pass_lower_complex_O0 | ( | ) |
|
static |
Set a value for a complex component of SSA_NAME, return a gimple_seq of stuff that needs doing.
We know the value must be zero, else there's a bug in our lattice analysis. But the value may well be a variable known to contain zero. We should be safe ignoring it.
If we've already assigned an SSA_NAME to this component, then this means that our walk of the basic blocks found a use before the set. This is fine. Now we should create an initialization for the value we created earlier.
If we've nothing assigned, and the value we're given is already stable, then install that as the value for this SSA_NAME. This preemptively copy-propagates the value, which avoids unnecessary memory allocation.
Replace an anonymous base value with the variable from cvc_lookup. This should result in better debug info.
Finally, we need to stabilize the result by installing the value into a new ssa name.
Do all the work to assign VALUE to COMP.
References get_component_var(), and replace_ssa_name_symbol().
Referenced by expand_complex_conjugate(), and extract_component().
|
static |
Return true if T is not a zero constant. In the case of real values, we're only interested in +0.0.
Operations with real or imaginary part of a complex number zero cannot be treated the same as operations with a real or imaginary operand if we care about the signs of zeros in the result.
|
static |
Entry point for complex operation lowering during optimization.
??? Ideally we'd traverse the blocks in breadth-first order.
|
static |
Update an assignment to a complex variable in place.
References get_component_ssa_name(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), and is_complex_reg().
|
static |
Update the complex components of the ssa name on the lhs of STMT.
|
static |
References cfun, is_gimple_reg(), and ssa_default_def().
|
static |
Generate code at the entry point of the function to initialize the component variables for a complex parameter.
|
static |
Generate code to set the component variables of a complex variable to match the PHI statements in block BB.
|
static |
For each complex SSA_NAME, a pair of ssa names for the components.
|
static |
For each complex variable, a pair of variables for the components exists in the hashtable.