PIPS
sequence_gcm_cse.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include "linear.h"
#include "genC.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "misc.h"
#include "properties.h"
#include "resources.h"
#include "pipsdbm.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "expressions.h"
#include "eole_private.h"
+ Include dependency graph for sequence_gcm_cse.c:

Go to the source code of this file.

Data Structures

struct  available_scalar_t
 performs Associative-Commutative Common Subexpression Elimination on sequences. More...
 

Macros

#define NO_SIMILARITY   (0)
 
#define MAX_SIMILARITY   (1000)
 

Typedefs

typedef struct available_scalar_tavailable_scalar_pt
 

Functions

static bool Is_Associative_Commutative (entity e)
 
static void push_nesting (statement s)
 Keep track of statement nesting. More...
 
static void pop_nesting (statement s)
 Pop the current statement from nesting list. More...
 
static int current_level (void)
 The nesting depth of the current statement. More...
 
static bool side_effects_p (expression e)
 There is a side effect if there is a W effect in the expression. More...
 
static bool interference_on (entity var, list les)
 Compute if an effect list Some effect in les interfere with var. More...
 
static bool moveable_to (list le, statement s)
 Whether sg with effects le can be moved up to s. More...
 
static int level_of (list le)
 Return the level of this expression, using the current nesting list. More...
 
static int expr_level_of (expression e)
 The level can be queried for a sub expression. More...
 
static statement statement_of_level (int level)
 or for a statement. More...
 
static bool currently_nested_p (void)
 Test if the current statement is not the top one: More...
 
static expression right_side_of_assign_statement (statement stat)
 
static bool entity_as_arguments (entity ent, statement stat)
 Verify if entity ent is an argument in the right expression of the assign statement stat. More...
 
static expression expr_left_side_of_assign_statement (statement stat)
 Return the expression in the left side of an assign statement. More...
 
static entity left_side_of_assign_statement (statement stat)
 Return the entity in left side of an assign statement. More...
 
static list insertion_statement_in_correct_position (statement news, list l)
 Insert statement s in the list of statement l. More...
 
static void insert_before_statement (statement news, statement s, bool last)
 Just for test static void dump_list_of_statement(list l) { fprintf(stderr, "\n===== Dump List: \n"); MAP(STATEMENT, ss, { print_statement(ss); }, l); fprintf(stderr, "\n END dumpt List!!! \n"); }. More...
 
static bool atomizable_sub_expression_p (expression e)
 Atomizable if some computation. More...
 
static gen_array_t group_expr_by_level (int nlevels, list le)
 of list of expressions More...
 
static void do_atomize_if_different_level (expression e, int level)
 Atomize sub expressions with. More...
 
static void atomize_call (call c, int level)
 
static void atomize_or_associate_for_level (expression e, int level)
 
static bool icm_atom_call_flt (call c)
 Don't go into I/O calls... More...
 
static void atomize_instruction (instruction i)
 Atomize an instruction with call. More...
 
static void atomize_test (test t)
 
static void atomize_whileloop (whileloop w)
 
static void atomize_or_associate (expression e)
 
static bool loop_flt (loop l)
 
static void loop_rwt (loop l)
 
static bool number_of_use_greater_1 (statement s)
 PDSon: I use the field 'comments' of statement for counting its number of use. More...
 
static void set_comment_of_statement (statement s, char *new_comment)
 Update the field 'comments' of a statement. More...
 
static statement update_number_of_use (entity ent, list lst_stat, int up_down)
 Update the number of use of statement defining 'ent' which is a member of list lst_stat with step up_down (up_down = 1 | 0 | -1). More...
 
static void increase_number_of_use_by_1 (entity ent, statement container)
 Increase number of use of variable ent by one. More...
 
static void remove_statement_redundant (statement s, list *inserted)
 Remove statement redundant inserted before statement s. More...
 
static bool cse_expression_flt (expression e, list *inserted)
 
static bool cse_call_flt (call c, __attribute__((unused)) list *inserted)
 Avoid visit the left side of assign statement. More...
 
static void insert_rwt (statement s)
 Insert the new statements created. More...
 
static bool prepare_icm (statement s)
 
void perform_icm_association (const char *name, statement s)
 Perform ICM and association on operators. More...
 
static void add_ref_ent (reference r)
 
static void add_call_ent (call c)
 
static list get_all_entities (expression e)
 
static bool try_reorder_expression_call (expression e, list availables)
 
static void reorder_pointer_expression (expression e)
 make sure expressions are ordered with pointer first More...
 
static void do_gather_all_expressions_perms (list sterns, list *perms)
 
static bool do_gather_all_expressions (expression e, list *gathered)
 
static void prune_singleton (list *l)
 
static bool expr_cse_flt (expression e, __attribute__((unused)) list *skip_list)
 whether to get in here, whether to atomize... More...
 
static bool expression_in_list_p (expression e, list seen)
 
static expression find_equal_expression_not_in_list (expression e, list avails, list seen)
 
static list common_expressions (list args, list avails)
 of expression More...
 
static list list_diff (list l1, list l2)
 of expression More...
 
static bool expression_eq_in_list_p (expression e, list l, expression *f)
 Define forward. More...
 
static int similarity (expression e, available_scalar_pt aspt)
 Find the commun sub-expression between e & aspt. More...
 
static available_scalar_pt best_similar_expression (expression e, int *best_quality)
 
static available_scalar_pt make_available_scalar (entity scalar, statement container, expression contents)
 
static bool call_unary_minus_p (expression e)
 
static void atom_cse_expression (expression e, list *skip_list)
 Remove some inpropriate ones... More...
 
static bool loop_stop (loop l, __attribute__((unused)) list *skip_list)
 
static bool test_stop (test t, __attribute__((unused)) list *skip_list)
 
static bool while_stop (whileloop wl, __attribute__((unused)) list *skip_list)
 
static bool cse_atom_call_flt (call c, list *skip_list)
 
static list atomize_cse_this_statement_expressions (statement s, list availables)
 side effects: use current_available and current_statement More...
 
static void prune_non_constant (list effects, list *perms)
 
void try_reorder_expressions (void *s, bool icm)
 
static bool seq_flt (sequence s)
 top down. More...
 
static bool call_flt (call c)
 handle all calls not in a sequence More...
 
void perform_ac_cse (__attribute__((unused)) const char *name, statement s)
 
bool common_subexpression_elimination (const char *module_name)
 Pipsmake phase: Common Subexpression Elimination. More...
 
bool icm (const char *module_name)
 Pipsmake phase: Invariant Code Motion. More...
 

Variables

static char * table_of_AC_operators []
 option: More...
 
static list nesting = NIL
 assumes: More...
 
static list current_available = NIL
 statement stack to current statement. More...
 
static statement current_statement = statement_undefined
 
static listw_effects
 PDSon: w_effect store all the variables modified in the sequence of statement. More...
 
static list seen = NIL
 

Macro Definition Documentation

◆ MAX_SIMILARITY

#define MAX_SIMILARITY   (1000)

Definition at line 1317 of file sequence_gcm_cse.c.

◆ NO_SIMILARITY

#define NO_SIMILARITY   (0)

Definition at line 1316 of file sequence_gcm_cse.c.

Typedef Documentation

◆ available_scalar_pt

Function Documentation

◆ add_call_ent()

static void add_call_ent ( call  c)
static

Definition at line 1094 of file sequence_gcm_cse.c.

1095 { seen = gen_once(call_function(c), seen); }
list gen_once(const void *vo, list l)
Prepend an item to a list only if it is not already in the list.
Definition: list.c:722
#define call_function(x)
Definition: ri.h:709
static list seen

References call_function, gen_once(), and seen.

Referenced by get_all_entities().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_ref_ent()

static void add_ref_ent ( reference  r)
static

Definition at line 1091 of file sequence_gcm_cse.c.

#define reference_variable(x)
Definition: ri.h:2326

References gen_once(), reference_variable, and seen.

Referenced by get_all_entities().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atom_cse_expression()

static void atom_cse_expression ( expression  e,
list skip_list 
)
static

Remove some inpropriate ones...

static void clean_current_availables(void) {

}

statement head = current_statement_head();

only left and right side of the subscript are splittable

extract every possible common subexpression

some common expression found.

identical, just make a reference to the scalar, whatever the stuff stored inside.

Set the statement to status REAL

partial common expression...

of expression

Case: in_common == aspt->contents

just substitute lo1, don't build a new aspt.

Set the statement to status REAL

now cse is a reference to the newly created scalar.

update both expressions...

in code

don't visit it later.

updates available contents

add the new scalar as an available CSE.

nothing

PDSon: Do not atomize:

  • simple reference (ex: a, x)
  • constant (ex: 2.6 , 5)
  • Unary minus (ex: -a , -5)

create a new atom...

At fisrt, this statement is set "virtual"

don't visit it later, just in case...

???

if there are variants in the expression it cannot be moved, and it is not available. Otherwise I should move it?

exp == e == <right expression of assignment> => Atomize this expression without using temporel variable; we use the left side variable of assignment in order to reduce the number of the variable temporel for the comprehensive of the code.

Definition at line 1616 of file sequence_gcm_cse.c.

1617 {
1618  pips_debug(1,"considering expression:");
1619  ifdebug(1) print_expression(e);
1620  /* statement head = current_statement_head(); */
1621  syntax s = expression_syntax(e);
1622  int quality;
1623  available_scalar_pt aspt;
1624 
1625  /* only left and right side of the subscript are splittable */
1627  if(gen_find_eq(e,*skip_list)!=gen_chunk_undefined) return;
1628  if(gen_find_eq(e,*skip_list)!=gen_chunk_undefined) return;
1629 
1630  do { /* extract every possible common subexpression */
1631  aspt = best_similar_expression(e, &quality);
1632 
1633  if (aspt) /* some common expression found. */
1634  {
1635  expression unused;
1636  if(expression_eq_in_list_p(e, *(aspt->w_effects), &unused))
1637  return;
1638  switch (syntax_tag(s))
1639  {
1640  case is_syntax_reference:
1643  return;
1644  case is_syntax_call:
1645  {
1646  call c = syntax_call(s);
1647  if (quality==MAX_SIMILARITY)
1648  {
1649  /* identical, just make a reference to the scalar,
1650  whatever the stuff stored inside.
1651  */
1652 
1655 
1656  /* Set the statement to status REAL */
1658 
1659  return;
1660  }
1661  else /* partial common expression... */
1662  {
1663  available_scalar_pt naspt;
1664  syntax sa = expression_syntax(aspt->contents);
1665  entity op = call_function(c), scalar;
1666  expression cse, cse2;
1667  statement scse;
1668  list /* of expression */ in_common, linit, lo1, lo2, old;
1669 
1670  pips_assert("AC operator",
1671  Is_Associative_Commutative(op) && op==aspt->operator);
1672  pips_assert("contents is a call", syntax_call_p(sa));
1673  call ca = syntax_call(sa);
1674 
1675  linit = call_arguments(ca);
1676 
1677  /*
1678  there is a common part to build,
1679  and a CSE to substitute in both...
1680  */
1682  *(aspt->w_effects)),
1683  aspt->available_contents);
1684 
1685  /* Case: in_common == aspt->contents
1686  * =================================
1687  */
1688  if (gen_length(linit)==gen_length(in_common))
1689  {
1690  /* just substitute lo1, don't build a new aspt. */
1691  lo1 = list_diff(call_arguments(c), in_common);
1693  call_arguments(c) =
1694  gen_nconc(lo1,
1695  CONS(EXPRESSION,
1696  entity_to_expression(aspt->scalar), NIL));
1697 
1698  /* Set the statement to status REAL */
1700  }
1701  else
1702  {
1703  lo1 = list_diff(call_arguments(c), in_common);
1704  lo2 = list_diff(linit, in_common);
1705 
1707  in_common));
1709 
1710  /* now cse is a reference to the newly created scalar. */
1711  pips_assert("a reference...",
1714  (expression_syntax(cse)));
1715  cse2 = copy_expression(cse);
1716 
1717  /* update both expressions... */
1718  old = call_arguments(c); /* in code */
1719  if (gen_length(call_arguments(c))==gen_length(in_common))
1720  {
1723  }
1724  else
1725  {
1726  call_arguments(c) = CONS(EXPRESSION, cse, lo1);
1727  }
1728  gen_free_list(old);
1729 
1730  old = call_arguments(ca);
1731  call_arguments(ca) = CONS(EXPRESSION, cse2, lo2);
1732  gen_free_list(old);
1733 
1734  set_comment_of_statement(scse, strdup("1"));
1735  insert_before_statement(scse, aspt->container, false);
1736  increase_number_of_use_by_1(scalar, aspt->container);
1737 
1738  /* don't visit it later. */
1739  gen_recurse_stop(scse);
1740 
1741  /* updates available contents */
1742  aspt->depends = CONS(ENTITY, scalar, aspt->depends);
1743  old = aspt->available_contents;
1744  aspt->available_contents = CONS(EXPRESSION, cse,
1745  list_diff(old, in_common));
1746  gen_free_list(old);
1747 
1748  /* add the new scalar as an available CSE. */
1749  naspt = make_available_scalar(scalar,
1750  aspt->container,
1753  current_available = CONS(STRING, (char*)naspt, current_available);
1754  }
1755  }
1756  break;
1757  }
1758  case is_syntax_range:
1759  default:
1760  /* nothing */
1761  return;
1762  }
1763  }
1764  } while(aspt);
1765 
1766  /* PDSon: Do not atomize:
1767  * - simple reference (ex: a, x)
1768  * - constant (ex: 2.6 , 5)
1769  * - Unary minus (ex: -a , -5)
1770  */
1771  if (!(expression_scalar_p(e)||expression_pointer_p(e)) &&
1772  !expression_constant_p(e) &&
1773  !call_unary_minus_p(e))
1774  {
1775  expression exp = NULL;
1776  /*
1777  instruction ins = statement_instruction(current_statement);
1778  if (instruction_call_p(ins))
1779  {
1780  call c_assign = instruction_call(ins);
1781 
1782  if (ENTITY_ASSIGN_P(call_function(c_assign)))
1783  {
1784  exp = EXPRESSION(CAR(CDR(call_arguments(c_assign))));
1785  }
1786  }*/
1787 
1788  if (exp != e)
1789  {
1790  statement atom;
1791 
1792  /* create a new atom... */
1794  if(atom) {
1795  /* At fisrt, this statement is set "virtual" */
1798 
1799  /* don't visit it later, just in case... */
1801  {
1802  entity scalar;
1803  call ic;
1804  syntax s = expression_syntax(e);
1806  pips_assert("it is a reference", syntax_reference_p(s));
1807  pips_assert("instruction is an assign",
1808  instruction_call_p(i)); /* ??? */
1809 
1810  scalar = reference_variable(syntax_reference(s));
1811  ic = instruction_call(i);
1812 
1813  /* if there are variants in the expression it cannot be moved,
1814  and it is not available. Otherwise I should move it?
1815  */
1816  aspt = make_available_scalar(scalar,
1818  EXPRESSION(CAR(CDR(call_arguments(ic)))));
1819 
1821  }
1822  }
1823  }
1824  else
1825  /* exp == e == <right expression of assignment>
1826  * => Atomize this expression without using temporel variable;
1827  * we use the left side variable of assignment in order to reduce
1828  * the number of the variable temporel for the comprehensive of
1829  * the code.
1830  */
1831  {
1833  if(!entity_undefined_p(scalar))
1834  {
1835  expression rhs;
1836  statement assign;
1837  syntax ref;
1838 
1841 
1843 
1846  rhs);
1847  expression_syntax(e) = ref;
1848 
1849  set_comment_of_statement(assign,strdup("1"));
1851 
1852  aspt = make_available_scalar(scalar, current_statement, rhs);
1854  }
1855  }
1856  }
1857 }
call make_call(entity a1, list a2)
Definition: ri.c:269
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
syntax copy_syntax(syntax p)
SYNTAX.
Definition: ri.c:2442
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void free_arguments(cons *args)
Definition: arguments.c:218
statement atomize_this_expression(entity(*)(entity, basic), expression)
simple_atomize.c
#define STRING(x)
Definition: genC.h:87
#define gen_chunk_undefined
Definition: genC.h:74
if(!(yy_init))
Definition: genread_lex.c:1029
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
statement make_assign_statement(expression, expression)
Definition: statement.c:583
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
struct _newgen_struct_atom_ * atom
void normalize_all_expressions_of(void *obj)
Definition: normalize.c:668
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define expression_scalar_p(e)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool expression_pointer_p(expression e)
we get the type of the expression by calling expression_to_type() which allocates a new one.
Definition: expression.c:506
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
entity make_new_scalar_variable(entity, basic)
Definition: variable.c:741
#define normalized_undefined
Definition: ri.h:1745
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define expression_normalized(x)
Definition: ri.h:1249
#define syntax_call(x)
Definition: ri.h:2736
#define instruction_call_p(x)
Definition: ri.h:1527
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
#define syntax_subscript_p(x)
Definition: ri.h:2743
char * strdup()
static available_scalar_pt best_similar_expression(expression e, int *best_quality)
static bool call_unary_minus_p(expression e)
static void set_comment_of_statement(statement s, char *new_comment)
Update the field 'comments' of a statement.
static bool expression_eq_in_list_p(expression e, list l, expression *f)
Define forward.
static list common_expressions(list args, list avails)
of expression
static void insert_before_statement(statement news, statement s, bool last)
Just for test static void dump_list_of_statement(list l) { fprintf(stderr, "\n===== Dump List: \n"); ...
static list current_available
statement stack to current statement.
static void increase_number_of_use_by_1(entity ent, statement container)
Increase number of use of variable ent by one.
#define MAX_SIMILARITY
static list list_diff(list l1, list l2)
of expression
static bool Is_Associative_Commutative(entity e)
static statement current_statement
static entity left_side_of_assign_statement(statement stat)
Return the entity in left side of an assign statement.
static available_scalar_pt make_available_scalar(entity scalar, statement container, expression contents)
return(s1)
#define ifdebug(n)
Definition: sg.c:47
performs Associative-Commutative Common Subexpression Elimination on sequences.
list depends
NULL for references.
list * w_effects
part of which is available
expression contents
statement in which it appears (for atomization)
entity operator
the entity which holds the value? or partial?
statement container
W effects on these invalidates the scalar.
list available_contents
call or reference...
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References atomize_this_expression(), available_scalar_t::available_contents, best_similar_expression(), call_arguments, call_function, call_to_expression(), call_unary_minus_p(), CAR, CDR, common_expressions(), CONS, available_scalar_t::container, available_scalar_t::contents, copy_expression(), copy_syntax(), current_available, current_statement, available_scalar_t::depends, ENTITY, entity_to_expression(), entity_undefined_p, exp, EXPRESSION, expression_constant_p(), expression_eq_in_list_p(), expression_normalized, expression_pointer_p(), expression_scalar_p, expression_syntax, free_arguments(), gen_chunk_undefined, gen_find_eq(), gen_free_list(), gen_length(), gen_nconc(), gen_recurse_stop(), ifdebug, increase_number_of_use_by_1(), insert_before_statement(), instruction_call, instruction_call_p, Is_Associative_Commutative(), is_syntax_call, is_syntax_range, is_syntax_reference, left_side_of_assign_statement(), list_diff(), make_assign_statement(), make_available_scalar(), make_call(), make_expression(), make_new_scalar_variable(), make_reference(), make_syntax(), MAX_SIMILARITY, NIL, normalize_all_expressions_of(), normalized_undefined, available_scalar_t::operator, pips_assert, pips_debug, print_expression(), ref, reference_variable, available_scalar_t::scalar, set_comment_of_statement(), statement_instruction, strdup(), STRING, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, syntax_subscript_p, syntax_tag, and available_scalar_t::w_effects.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomizable_sub_expression_p()

static bool atomizable_sub_expression_p ( expression  e)
static

Atomizable if some computation.

Missing cases? user functions? I/O?

Definition at line 421 of file sequence_gcm_cse.c.

422 {
423  syntax s = expression_syntax(e);
424  switch (syntax_tag(s))
425  {
426  case is_syntax_range:
427  case is_syntax_reference:
428  return false;
429  case is_syntax_call:
430  {
431  entity called = call_function(syntax_call(s));
432  /* Missing cases? user functions? I/O? */
433  return !entity_constant_p(called) && !ENTITY_IMPLIEDDO_P(called);
434  }
435  default:
436  pips_internal_error("unexpected syntax tag: %d", syntax_tag(s));
437  return false;
438  }
439 }
#define pips_internal_error
Definition: misc-local.h:149
#define ENTITY_IMPLIEDDO_P(e)
#define entity_constant_p(e)

References call_function, entity_constant_p, ENTITY_IMPLIEDDO_P, expression_syntax, is_syntax_call, is_syntax_range, is_syntax_reference, pips_internal_error, syntax_call, and syntax_tag.

Referenced by do_atomize_if_different_level().

+ Here is the caller graph for this function:

◆ atomize_call()

static void atomize_call ( call  c,
int  level 
)
static

of expression

Definition at line 550 of file sequence_gcm_cse.c.

551 {
552  list /* of expression */ args;
553  int lenargs;
554 
555  args = call_arguments(c);
556  lenargs = gen_length(args);
557 
558  if (lenargs>=2)
559  {
560  FOREACH(EXPRESSION, sube, args)
562  }
563 }
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define level
static void do_atomize_if_different_level(expression e, int level)
Atomize sub expressions with.

References call_arguments, do_atomize_if_different_level(), EXPRESSION, FOREACH, gen_length(), and level.

Referenced by atomize_instruction(), and atomize_or_associate_for_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_cse_this_statement_expressions()

static list atomize_cse_this_statement_expressions ( statement  s,
list  availables 
)
static

side effects: use current_available and current_statement

of available_scalar_pt

scan expressions in s; atomize/cse them; update availables;

statement_domain, current_statement_filter, current_statement_rewrite,

don't go inside these...

do the job on the found expression.

free_current_statement_stack();

Update w_effects: add the variable modified by the current statement

Update contents

Update address: w_effects always points to the end of the list of variable modified which is filled after each statement

Definition at line 1907 of file sequence_gcm_cse.c.

1908 {
1909  current_available = availables;
1910  current_statement = s;
1911  list skip_list = NIL;
1912 
1913  /* scan expressions in s;
1914  atomize/cse them;
1915  update availables;
1916  */
1917  gen_context_multi_recurse(s,&skip_list,
1918  /* statement_domain, current_statement_filter,
1919  current_statement_rewrite, */
1920 
1921  /* don't go inside these... */
1926 
1927  /* . */
1929 
1930  /* do the job on the found expression. */
1932  NULL);
1933  gen_free_list(skip_list);
1934 
1935  /* free_current_statement_stack(); */
1936  availables = current_available;
1937 
1940 
1941  /* Update w_effects: add the variable modified by the current statement */
1942  if (assignment_statement_p(s))
1943  {
1944  /* Update contents */
1945  expression var_defined =
1947  *w_effects = CONS(EXPRESSION, var_defined, NIL);
1948 
1949  /* Update address: w_effects always points to the end of the list of
1950  * variable modified which is filled after each statement
1951  */
1952  w_effects = &CDR(*w_effects);
1953  }
1954 
1955  return availables;
1956 }
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
#define test_domain
newgen_entity_domain_defined
Definition: ri.h:418
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define statement_undefined
Definition: ri.h:2419
static bool while_stop(whileloop wl, __attribute__((unused)) list *skip_list)
static list * w_effects
PDSon: w_effect store all the variables modified in the sequence of statement.
static bool cse_atom_call_flt(call c, list *skip_list)
static expression expr_left_side_of_assign_statement(statement stat)
Return the expression in the left side of an assign statement.
static void atom_cse_expression(expression e, list *skip_list)
Remove some inpropriate ones...
static bool test_stop(test t, __attribute__((unused)) list *skip_list)
static bool loop_stop(loop l, __attribute__((unused)) list *skip_list)
static bool expr_cse_flt(expression e, __attribute__((unused)) list *skip_list)
whether to get in here, whether to atomize...

References assignment_statement_p(), atom_cse_expression(), call_domain, CDR, CONS, copy_expression(), cse_atom_call_flt(), current_available, current_statement, expr_cse_flt(), expr_left_side_of_assign_statement(), EXPRESSION, expression_domain, gen_context_multi_recurse(), gen_false(), gen_free_list(), gen_null(), loop_domain, loop_stop(), NIL, statement_undefined, test_domain, test_stop(), unstructured_domain, w_effects, while_stop(), and whileloop_domain.

Referenced by call_flt(), and seq_flt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_instruction()

static void atomize_instruction ( instruction  i)
static

Atomize an instruction with call.

Maybe I could consider moving the call as a whole?

Since we are at the top level statement, impossible to move something outside...

Should have been dealt by other means in the gen_multi_recurse() from gen_multi_recurse() before

stat_level_of(current_statement_head()));

Definition at line 668 of file sequence_gcm_cse.c.

669 {
670  if (!currently_nested_p())
671  /* Since we are at the top level statement, impossible to move
672  something outside... */
673  return;
674 
675  if (!instruction_call_p(i))
676  /* Should have been dealt by other means in the gen_multi_recurse()
677  from gen_multi_recurse() before */
678  return;
679 
680  /* stat_level_of(current_statement_head())); */
682 }
static int current_level(void)
The nesting depth of the current statement.
static void atomize_call(call c, int level)
static bool currently_nested_p(void)
Test if the current statement is not the top one:

References atomize_call(), current_level(), currently_nested_p(), instruction_call, and instruction_call_p.

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_or_associate()

static void atomize_or_associate ( expression  e)
static

Definition at line 696 of file sequence_gcm_cse.c.

697 {
699 }
static int expr_level_of(expression e)
The level can be queried for a sub expression.
static void atomize_or_associate_for_level(expression e, int level)

References atomize_or_associate_for_level(), and expr_level_of().

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_or_associate_for_level()

static void atomize_or_associate_for_level ( expression  e,
int  level 
)
static

of expression

Some depth, otherwise no ICM needed! should be fixed if root statement is pushed?

skip casts

Only do something with calls

something to icm

Reassociation + atomization maybe needed. code taken from JZ.

Note: the last level of an expression MUST NOT be moved! indeed, there may be a side effects in another part of the expr.

Insert expression in upward expression, eventually in e!

Fix last level if necessary.

Definition at line 566 of file sequence_gcm_cse.c.

567 {
568  syntax syn;
569  call c;
570  entity func;
571  list /* of expression */ args;
572  int lenargs;
573 
574  /* Some depth, otherwise no ICM needed!
575  * should be fixed if root statement is pushed?
576  */
577  if (!currently_nested_p()) return;
578 
579 
580  syn = expression_syntax(e);
581 
582  /* skip casts */
584 
585  /* Only do something with calls */
586  if (!syntax_call_p(syn))
587  return;
588 
589  pips_debug(1,"considering expression %s\n",expression_to_string(e));
590 
591  /* something to icm
592  */
593  c = syntax_call(syn);
594  func = call_function(c);
595  args = call_arguments(c);
596  lenargs = gen_length(args);
597 
598  if (Is_Associative_Commutative(func) && lenargs>2)
599  {
600  /* Reassociation + atomization maybe needed.
601  * code taken from JZ.
602  */
603  int i, nlevels = current_level();
604  gen_array_t groups = group_expr_by_level(nlevels, args);
605  list lenl;
606 
607  /* Note: the last level of an expression MUST NOT be moved!
608  * indeed, there may be a side effects in another part of the expr.
609  */
610  for (i=0; i<nlevels; i++)
611  {
612  list lei = (list) gen_array_item(groups, i);
613  if (lei!=list_undefined)
614  {
615  int j;
616  bool satom_inserted = false;
617  syntax satom = make_syntax_call(make_call(func, lei));
619  statement atom;
620 
621  /* Insert expression in upward expression, eventually in e!
622  */
623  for (j=i+1; j<=nlevels && !satom_inserted; j++)
624  {
625  list lej = (list) gen_array_item(groups, j);
626  if (lej!=list_undefined)
627  {
628  eatom = make_expression(satom, normalized_undefined);
629  lej = CONS(EXPRESSION, eatom, lej);
630  gen_array_addto(groups, j, lej);
631  satom_inserted = true;
632  }
633  }
634  if (!satom_inserted)
635  {
636  expression_syntax(e) = satom;
637  eatom = e;
638  }
639 
642  }
643  }
644 
645  /* Fix last level if necessary.
646  */
647  lenl = (list) gen_array_item(groups, nlevels);
648  if (lenl != list_undefined)
649  call_arguments(c) = lenl;
650  }
651  else
652  {
653  atomize_call(c, level);
654  }
655 }
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
void gen_array_addto(gen_array_t a, size_t i, void *what)
Definition: array.c:87
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
struct cons * list
Definition: newgen_types.h:106
string expression_to_string(expression e)
Definition: expression.c:77
#define syntax_cast(x)
Definition: ri.h:2739
#define cast_expression(x)
Definition: ri.h:747
#define expression_undefined
Definition: ri.h:1223
#define syntax_cast_p(x)
Definition: ri.h:2737
static gen_array_t group_expr_by_level(int nlevels, list le)
of list of expressions
static statement statement_of_level(int level)
or for a statement.

References atomize_call(), atomize_this_expression(), call_arguments, call_function, cast_expression, CONS, current_level(), currently_nested_p(), EXPRESSION, expression_syntax, expression_to_string(), expression_undefined, gen_array_addto(), gen_array_item(), gen_length(), group_expr_by_level(), insert_before_statement(), Is_Associative_Commutative(), level, list_undefined, make_call(), make_expression(), make_new_scalar_variable(), make_syntax_call(), normalized_undefined, pips_debug, statement_of_level(), syntax_call, syntax_call_p, syntax_cast, and syntax_cast_p.

Referenced by atomize_or_associate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_test()

static void atomize_test ( test  t)
static

Definition at line 684 of file sequence_gcm_cse.c.

685 {
686  if (!currently_nested_p()) return;
688 }
#define test_condition(x)
Definition: ri.h:2833

References current_level(), currently_nested_p(), do_atomize_if_different_level(), and test_condition.

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ atomize_whileloop()

static void atomize_whileloop ( whileloop  w)
static

Definition at line 690 of file sequence_gcm_cse.c.

691 {
692  if (!currently_nested_p()) return;
694 }
#define whileloop_condition(x)
Definition: ri.h:3160

References current_level(), currently_nested_p(), do_atomize_if_different_level(), and whileloop_condition.

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ best_similar_expression()

static available_scalar_pt best_similar_expression ( expression  e,
int best_quality 
)
static

Definition at line 1497 of file sequence_gcm_cse.c.

1498 {
1499  available_scalar_pt best = NULL;
1500  (*best_quality) = 0;
1501 
1503  {
1505  int quality = similarity(e, aspt);
1506  if (quality==MAX_SIMILARITY)
1507  {
1508  (*best_quality) = quality;
1509  return aspt;
1510  }
1511  if (quality>0 && (*best_quality)<quality)
1512  {
1513  best = aspt;
1514  (*best_quality) = quality;
1515  }
1516  }
1517 
1518  return best;
1519 }
static int similarity(expression e, available_scalar_pt aspt)
Find the commun sub-expression between e & aspt.
struct available_scalar_t * available_scalar_pt

References current_available, FOREACH, MAX_SIMILARITY, similarity(), and STRING.

Referenced by atom_cse_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ call_flt()

static bool call_flt ( call  c)
static

handle all calls not in a sequence

Definition at line 2022 of file sequence_gcm_cse.c.

2023 {
2025  pips_debug(1,"considering statement:\n");
2026  ifdebug(1) { print_statement(parent); }
2027  list availables = NIL;
2028  list *top_of_w_effects = w_effects = &CDR(gen_cons(NIL,NIL));
2029  availables = atomize_cse_this_statement_expressions(parent,availables);
2030  gen_full_free_list(*top_of_w_effects);
2031  return true;
2032 }
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void gen_full_free_list(list l)
Definition: genClib.c:1023
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
list gen_cons(const void *item, const list next)
Definition: list.c:888
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
static list atomize_cse_this_statement_expressions(statement s, list availables)
side effects: use current_available and current_statement

References atomize_cse_this_statement_expressions(), CDR, gen_cons(), gen_full_free_list(), gen_get_ancestor(), ifdebug, NIL, pips_debug, print_statement(), statement_domain, and w_effects.

Referenced by perform_ac_cse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ call_unary_minus_p()

static bool call_unary_minus_p ( expression  e)
static

Definition at line 1598 of file sequence_gcm_cse.c.

1599 {
1600  syntax s = expression_syntax(e);
1601  if(syntax_call_p(s))
1602  {
1603  call c = syntax_call(s);
1605  }
1606  return false;
1607 }
#define ENTITY_UNARY_MINUS_P(e)

References call_function, ENTITY_UNARY_MINUS_P, expression_syntax, syntax_call, and syntax_call_p.

Referenced by atom_cse_expression().

+ Here is the caller graph for this function:

◆ common_expressions()

static list common_expressions ( list  args,
list  avails 
)
static

of expression

Definition at line 1373 of file sequence_gcm_cse.c.

1374 {
1375  list already_seen = NIL;
1376 
1377  FOREACH(EXPRESSION, e, args)
1378  {
1379  expression n = find_equal_expression_not_in_list(e, avails, already_seen);
1380  if (n) already_seen = CONS(EXPRESSION, n, already_seen);
1381  }
1382 
1383  return already_seen;
1384 }
static expression find_equal_expression_not_in_list(expression e, list avails, list seen)

References CONS, EXPRESSION, find_equal_expression_not_in_list(), FOREACH, and NIL.

Referenced by atom_cse_expression(), and similarity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ common_subexpression_elimination()

bool common_subexpression_elimination ( const char *  module_name)

Pipsmake phase: Common Subexpression Elimination.

Parameters
[in]module_nameis the name of the module we want to apply the Common Subexpression Elimination on
Returns
true if everything goes fine.
Parameters
module_nameodule_name

Definition at line 2075 of file sequence_gcm_cse.c.

2076 {
2077  bool result;
2078  const char* os = get_string_property("EOLE_OPTIMIZATION_STRATEGY");
2079 
2080  // Optimize expressions with "CSE" optimization strategy
2081  set_string_property("EOLE_OPTIMIZATION_STRATEGY", "CSE");
2083 
2084  // Restore original optimization strategy
2085  set_string_property("EOLE_OPTIMIZATION_STRATEGY", os);
2086 
2087  return result;
2088 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool optimize_expressions(const char *)
pipsmake interface to apply expression optimization according to various strategy.
Definition: optimize.c:1391
char * get_string_property(const char *)
void set_string_property(const char *, const char *)

References get_string_property(), module_name(), optimize_expressions(), and set_string_property().

+ Here is the call graph for this function:

◆ cse_atom_call_flt()

static bool cse_atom_call_flt ( call  c,
list skip_list 
)
static

should avoid any W effect...

Update address: w_effects always points to the end of the list of variable modified which is filled after each statement

Definition at line 1879 of file sequence_gcm_cse.c.

1880 {
1881  entity called = call_function(c);
1882 
1883  /* should avoid any W effect... */
1884  if (ENTITY_ASSIGN_P(called))
1885  {
1886  expression lhs = binary_call_lhs(c);
1887  if(get_bool_property("COMMON_SUBEXPRESSION_ELIMINATION_SKIP_LHS")) gen_recurse_stop(lhs);
1888  else if(!syntax_subscript_p(expression_syntax(lhs)))
1889  {
1890  *skip_list=CONS(EXPRESSION,lhs,*skip_list);
1891  expression var_defined =
1892  copy_expression(lhs);
1893  *w_effects = CONS(EXPRESSION, var_defined, NIL);
1894 
1895  /* Update address: w_effects always points to the end of the list of
1896  * variable modified which is filled after each statement
1897  */
1898  w_effects = &CDR(*w_effects);
1899  }
1900  }
1901  return !(io_intrinsic_p(called) || ENTITY_IMPLIEDDO_P(called));
1902 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define ENTITY_ASSIGN_P(e)
#define binary_call_lhs(c)
bool io_intrinsic_p(entity e)
rue is a statement s is an io intrinsic
Definition: entity.c:1655

References binary_call_lhs, call_function, CDR, CONS, copy_expression(), ENTITY_ASSIGN_P, ENTITY_IMPLIEDDO_P, EXPRESSION, expression_syntax, gen_recurse_stop(), get_bool_property(), io_intrinsic_p(), NIL, syntax_subscript_p, and w_effects.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cse_call_flt()

static bool cse_call_flt ( call  c,
__attribute__((unused)) list inserted 
)
static

Avoid visit the left side of assign statement.

Go down!

Definition at line 931 of file sequence_gcm_cse.c.

932 {
934  {
935  expression lhs = binary_call_lhs(c);
936  if(get_bool_property("COMMON_SUBEXPRESSION_ELIMINATION_SKIP_LHS") || expression_scalar_p(lhs) || expression_pointer_p(lhs) )
937  gen_recurse_stop(lhs);
938  }
939  /* Go down! */
940  return true;
941 }

References binary_call_lhs, call_function, ENTITY_ASSIGN_P, expression_pointer_p(), expression_scalar_p, gen_recurse_stop(), and get_bool_property().

Referenced by remove_statement_redundant().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cse_expression_flt()

static bool cse_expression_flt ( expression  e,
list inserted 
)
static

Go down

This statement is a real one. But it maybe contains a variable temporal -> Continue remove redundant statement from this one

Remove its comment for pretty look: It is visited! Not do again!

Go up

This statement is already visited! Not do again! Go up

s is a redundant statement. Replace e by the right side of the assign statement s

Remove s from list

Continue go down the new expression

Nothing is done! Go up

Definition at line 865 of file sequence_gcm_cse.c.

866 {
867  pips_debug(2,"examining expression:");
868  ifdebug(2) { print_expression(e); }
869  entity scala;
870 
872  {
873  /* Go down */
874  return true;
875  }
876 
878  FOREACH(STATEMENT, s,*inserted)
879  {
881  if (scala == ent)
882  {
884  {
885  /* This statement is a real one. But it maybe contains a variable
886  * temporal -> Continue remove redundant statement from this one
887  */
888  remove_statement_redundant(s, inserted);
889 
890  /* Remove its comment for pretty look: It is visited! Not do again! */
892 
893  /* Go up */
894  return false;
895  }
897  {
898  /* This statement is already visited! Not do again! Go up */
899  return false;
900  }
901  else
902  {
903  pips_debug(1,"redundant statement purged:\n");
904  ifdebug(1) { print_statement(s); }
905  /* s is a redundant statement. Replace e by the right side of
906  * the assign statement s
907  */
910  expression_syntax(exp) = NULL;
911 
912  /* Remove s from list
913  */
914  gen_remove_once(inserted, s);
915 
916  free_statement(s);
917 
918  /* Continue go down the new expression */
919  return true;
920  }
921  }
922  }
923 
924  /* Nothing is done! Go up */
925  return false;
926 }
void free_statement(statement p)
Definition: ri.c:2189
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
#define string_undefined
Definition: newgen_types.h:40
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define statement_comments(x)
Definition: ri.h:2456
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
static void remove_statement_redundant(statement s, list *inserted)
Remove statement redundant inserted before statement s.
static expression right_side_of_assign_statement(statement stat)
static bool number_of_use_greater_1(statement s)
PDSon: I use the field 'comments' of statement for counting its number of use.

References exp, expression_syntax, FOREACH, free_statement(), gen_remove_once(), ifdebug, left_side_of_assign_statement(), number_of_use_greater_1(), pips_debug, print_expression(), print_statement(), reference_variable, remove_statement_redundant(), right_side_of_assign_statement(), set_comment_of_statement(), STATEMENT, statement_comments, string_undefined, string_undefined_p, syntax_reference, and syntax_reference_p.

Referenced by remove_statement_redundant().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ current_level()

static int current_level ( void  )
static

The nesting depth of the current statement.

Definition at line 145 of file sequence_gcm_cse.c.

146 {
147  return gen_length(nesting);
148 }
static list nesting
assumes:

References gen_length(), and nesting.

Referenced by atomize_instruction(), atomize_or_associate_for_level(), atomize_test(), atomize_whileloop(), currently_nested_p(), loop_rwt(), and statement_of_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ currently_nested_p()

static bool currently_nested_p ( void  )
static

Test if the current statement is not the top one:

Definition at line 274 of file sequence_gcm_cse.c.

275 {
276 #if defined(PUSH_BODY)
277  return current_level()>1;
278 #else
279  return current_level()>0;
280 #endif
281 }

References current_level().

Referenced by atomize_instruction(), atomize_or_associate_for_level(), atomize_test(), atomize_whileloop(), and loop_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_atomize_if_different_level()

static void do_atomize_if_different_level ( expression  e,
int  level 
)
static

Atomize sub expressions with.

  • lower level
  • not simple (references or constants)
  • no side effects.

Definition at line 530 of file sequence_gcm_cse.c.

531 {
532  int elevel = expr_level_of(e);
533 
534  pips_debug(1,"considering expression %s\n",expression_to_string(e));
535  if (elevel!=-1 &&
536  elevel<level &&
538  !side_effects_p(e))
539  {
540  pips_debug(1,"atomize \n");
542  if (atom)
544  }
545  else
546  pips_debug(1,"not atomize\n");
547 }
static bool atomizable_sub_expression_p(expression e)
Atomizable if some computation.
static bool side_effects_p(expression e)
There is a side effect if there is a W effect in the expression.

References atomizable_sub_expression_p(), atomize_this_expression(), expr_level_of(), expression_to_string(), insert_before_statement(), level, make_new_scalar_variable(), pips_debug, side_effects_p(), and statement_of_level().

Referenced by atomize_call(), atomize_test(), atomize_whileloop(), and loop_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_gather_all_expressions()

static bool do_gather_all_expressions ( expression  e,
list gathered 
)
static

Definition at line 1259 of file sequence_gcm_cse.c.

1259  {
1262  if(normalized_linear_p(n)) {
1263  Pvecteur pv = normalized_linear(n);
1264  list sterns=NIL;
1265  for(Pvecteur ipv = pv; !VECTEUR_NUL_P(ipv) ; ipv=vecteur_succ(ipv)) {
1267  if(TCST != vecteur_var(ipv)) {
1269  stern,
1271  }
1272  sterns=CONS(EXPRESSION,stern,sterns);
1273  }
1274  list perms = NIL;
1275  do_gather_all_expressions_perms(sterns,&perms);
1276  *gathered=gen_nconc(*gathered,perms);
1277  return false;
1278  }
1279  return true;
1280 }
#define NORMALIZE_EXPRESSION(e)
#define MULTIPLY_OPERATOR_NAME
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
#define normalized_linear_p(x)
Definition: ri.h:1779
#define normalized_linear(x)
Definition: ri.h:1781
static void do_gather_all_expressions_perms(list sterns, list *perms)
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define vecteur_succ(v)
#define VECTEUR_NUL_P(v)

References CONS, do_gather_all_expressions_perms(), entity_to_expression(), EXPRESSION, expression_normalized, gen_nconc(), int_to_expression(), make_op_exp(), MULTIPLY_OPERATOR_NAME, NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, TCST, VECTEUR_NUL_P, vecteur_succ, vecteur_val, and vecteur_var.

Referenced by try_reorder_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_gather_all_expressions_perms()

static void do_gather_all_expressions_perms ( list  sterns,
list perms 
)
static

Definition at line 1236 of file sequence_gcm_cse.c.

1236  {
1237  if(ENDP(sterns)) *perms=NIL;
1238  else {
1239  expression head = EXPRESSION(CAR(sterns));
1240  unnormalize_expression(head);
1241  NORMALIZE_EXPRESSION(head);
1242  POP(sterns);
1243  *perms = CONS(EXPRESSION,copy_expression(head),*perms);
1244  list nperms = NIL;
1245  do_gather_all_expressions_perms(sterns,&nperms);
1246  FOREACH(EXPRESSION,exp,nperms) {
1253  *perms=CONS(EXPRESSION,epv,*perms);
1254  }
1255  *perms=gen_nconc(*perms,nperms);
1256  }
1257 }
void convert_to_c_operators(void *)
Definition: optimize.c:1343
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
expression Pvecteur_to_expression(Pvecteur vect)
AP, sep 25th 95 : some usefull functions moved from static_controlize/utils.c.
Definition: expression.c:1825
static void reorder_pointer_expression(expression e)
make sure expressions are ordered with pointer first
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53

References CAR, CONS, convert_to_c_operators(), copy_expression(), ENDP, exp, EXPRESSION, expression_normalized, FOREACH, gen_nconc(), NIL, NORMALIZE_EXPRESSION, normalized_linear, POP, Pvecteur_to_expression(), reorder_pointer_expression(), unnormalize_expression(), and vect_add().

Referenced by do_gather_all_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ entity_as_arguments()

static bool entity_as_arguments ( entity  ent,
statement  stat 
)
static

Verify if entity ent is an argument in the right expression of the assign statement stat.

Argument is maybe a call to a constant

Definition at line 305 of file sequence_gcm_cse.c.

306 {
307  expression right_side;
308  call right_call;
309 
310  right_side = right_side_of_assign_statement(stat);
311 
312  pips_assert("Right expression is a call!",
313  syntax_call_p(expression_syntax(right_side)));
314  right_call = syntax_call(expression_syntax(right_side));
315 
316  FOREACH(EXPRESSION, e,call_arguments(right_call))
317  {
318  syntax s = expression_syntax(e);
319  /* Argument is maybe a call to a constant */
320  if (syntax_reference_p(s) &&
322  {
323  return true;
324  }
325  }
326 
327  return false;
328 }

References call_arguments, EXPRESSION, expression_syntax, FOREACH, pips_assert, reference_variable, right_side_of_assign_statement(), syntax_call, syntax_call_p, syntax_reference, and syntax_reference_p.

Referenced by insertion_statement_in_correct_position().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expr_cse_flt()

static bool expr_cse_flt ( expression  e,
__attribute__((unused)) list skip_list 
)
static

whether to get in here, whether to atomize...

Definition at line 1297 of file sequence_gcm_cse.c.

1298 {
1299  pips_debug(2,"considering expression:");
1300  ifdebug(2) print_expression(e);
1301  syntax s = expression_syntax(e);
1302  switch (syntax_tag(s))
1303  {
1304  case is_syntax_call:
1305  return !IO_CALL_P(expression_call(e));
1306  case is_syntax_reference:
1307  //return entity_scalar_p(reference_variable(syntax_reference(s)));
1308  case is_syntax_subscript:
1309  case is_syntax_cast:
1310  return true;
1311  default:
1312  return false;
1313  }
1314 }
#define IO_CALL_P(call)
call expression_call(expression e)
Definition: expression.c:445
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_subscript
Definition: ri.h:2696

References expression_call(), expression_syntax, ifdebug, IO_CALL_P, is_syntax_call, is_syntax_cast, is_syntax_reference, is_syntax_subscript, pips_debug, print_expression(), and syntax_tag.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expr_left_side_of_assign_statement()

static expression expr_left_side_of_assign_statement ( statement  stat)
static

Return the expression in the left side of an assign statement.

Definition at line 332 of file sequence_gcm_cse.c.

333 {
334  if (assignment_statement_p(stat))
335  {
337  return EXPRESSION(CAR(call_arguments(assign)));
338  }
339 
340  pips_internal_error("It is not an assign statement !");
341 
342  return NULL;
343 }

References assignment_statement_p(), call_arguments, CAR, EXPRESSION, instruction_call, pips_internal_error, and statement_instruction.

Referenced by atomize_cse_this_statement_expressions(), and left_side_of_assign_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expr_level_of()

static int expr_level_of ( expression  e)
static

The level can be queried for a sub expression.

try again !

assigns...

Definition at line 225 of file sequence_gcm_cse.c.

226 {
227  list le;
228  if (!bound_expr_prw_effects_p(e)) {
229  /* try again ! */
231  bool writes = false;
232  FOREACH(EFFECT,eff,le) {
233  if((writes=effect_write_p(eff))) break;
234  }
235  if(writes)
236  return -1; /* assigns... */
237  else {
238  int res = level_of(le);
239  gen_full_free_list(le);
240  return res;
241  }
242  }
243  else {
245  return level_of(le);
246  }
247 }
effects load_expr_prw_effects(expression)
bool bound_expr_prw_effects_p(expression)
list proper_effects_of_expression(expression)
#define effect_write_p(eff)
#define effects_effects(x)
Definition: effects.h:710
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
static int level_of(list le)
Return the level of this expression, using the current nesting list.

References bound_expr_prw_effects_p(), EFFECT, effect_write_p, effects_effects, FOREACH, gen_full_free_list(), level_of(), load_expr_prw_effects(), and proper_effects_of_expression().

Referenced by atomize_or_associate(), do_atomize_if_different_level(), and group_expr_by_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expression_eq_in_list_p()

static bool expression_eq_in_list_p ( expression  e,
list  l,
expression f 
)
static

Define forward.

Define forward

Definition at line 1558 of file sequence_gcm_cse.c.

1559 {
1560  FOREACH(EXPRESSION, et,l)
1561  {
1562  if (expression_equal_p(e, et))
1563  {
1564  *f = et;
1565  return true;
1566  }
1567  }
1568 
1569  return false;
1570 }
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347

References EXPRESSION, expression_equal_p(), f(), and FOREACH.

Referenced by atom_cse_expression(), list_diff(), and similarity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ expression_in_list_p()

static bool expression_in_list_p ( expression  e,
list  seen 
)
static

Definition at line 1358 of file sequence_gcm_cse.c.

1359 {
1360  MAP(EXPRESSION, f, if (e==f) return true, seen);
1361  return false;
1362 }
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226

References EXPRESSION, f(), MAP, and seen.

Referenced by find_equal_expression_not_in_list().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_equal_expression_not_in_list()

static expression find_equal_expression_not_in_list ( expression  e,
list  avails,
list  seen 
)
static

Definition at line 1364 of file sequence_gcm_cse.c.

1365 {
1366  FOREACH(EXPRESSION, f,avails)
1368  return f;
1369  return NULL;
1370 }
static bool expression_in_list_p(expression e, list seen)

References EXPRESSION, expression_equal_p(), expression_in_list_p(), f(), FOREACH, and seen.

Referenced by common_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_all_entities()

static list get_all_entities ( expression  e)
static

Definition at line 1097 of file sequence_gcm_cse.c.

1098 {
1099  list result;
1100  seen = NIL;
1101 
1105  NULL);
1106 
1107  result = seen;
1108  seen = NIL;
1109  return result;
1110 }
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
static void add_ref_ent(reference r)
static void add_call_ent(call c)

References add_call_ent(), add_ref_ent(), call_domain, gen_multi_recurse(), gen_true(), NIL, reference_domain, and seen.

Referenced by make_available_scalar().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ group_expr_by_level()

static gen_array_t group_expr_by_level ( int  nlevels,
list  le 
)
static

of list of expressions

initialize chunks.

put expressions in chunks.

Fix expressions by useful levels, with some operations.

Definition at line 442 of file sequence_gcm_cse.c.

443 {
444  gen_array_t result = gen_array_make(nlevels+1);
445  int i;
446  bool first_alone;
447 
448  /* initialize chunks. */
449  for (i=0; i<=nlevels; i++)
450  gen_array_addto(result, i, list_undefined);
451 
452  /* put expressions in chunks. */
453  FOREACH(EXPRESSION, e,le)
454  {
455  int elevel = expr_level_of(e);
456  list eatlevel;
457  pips_assert("coherent level", elevel>=0 && elevel<=nlevels);
458 
459  if (side_effects_p(e))
460  {
461  elevel = nlevels;
462  }
463 
464  eatlevel = (list) gen_array_item(result, elevel);
465  if (eatlevel == list_undefined)
466  {
467  eatlevel = CONS(EXPRESSION, e, NIL);
468  }
469  else
470  {
471  eatlevel = CONS(EXPRESSION, e, eatlevel);
472  }
473  gen_array_addto(result, elevel, eatlevel);
474  }
475 
476  /* Fix expressions by useful levels, with some operations.
477  */
478  first_alone = true;
479  for (i=0; i<nlevels && first_alone; i++)
480  {
481  list lei = (list) gen_array_item(result, i);
482  if (lei != list_undefined)
483  {
484  int lenlei = gen_length(lei);
485  if (lenlei == 1)
486  {
487  list next = (list) gen_array_item(result, i+1);
488  if (next == list_undefined)
489  next = lei;
490  else
491  next = gen_nconc(next, lei);
492  gen_array_addto(result, i+1, next);
493  gen_array_addto(result, i, list_undefined);
494  }
495  else
496  first_alone = false;
497  }
498  }
499 
500  return result;
501 }
gen_array_t gen_array_make(size_t size)
declarations...
Definition: array.c:40

References CONS, expr_level_of(), EXPRESSION, FOREACH, gen_array_addto(), gen_array_item(), gen_array_make(), gen_length(), gen_nconc(), list_undefined, NIL, pips_assert, and side_effects_p().

Referenced by atomize_or_associate_for_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ icm()

bool icm ( const char *  module_name)

Pipsmake phase: Invariant Code Motion.

Parameters
[in]module_nameis the name of the module we want to apply the Invariant Code Motion on
Returns
true if everything goes file.

Beware, invariant_code_motion phase already exists too but deal with loop invariant code motion...

Parameters
module_nameodule_name

Definition at line 2101 of file sequence_gcm_cse.c.

2102 {
2103  bool result;
2104  const char* os = get_string_property("EOLE_OPTIMIZATION_STRATEGY");
2105 
2106  // Optimize expressions with "ICM" optimization strategy
2107  set_string_property("EOLE_OPTIMIZATION_STRATEGY", "ICM");
2109 
2110  // Restore original optimization strategy
2111  set_string_property("EOLE_OPTIMIZATION_STRATEGY", os);
2112 
2113  return result;
2114 }

References get_string_property(), module_name(), optimize_expressions(), and set_string_property().

Referenced by try_reorder_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ icm_atom_call_flt()

static bool icm_atom_call_flt ( call  c)
static

Don't go into I/O calls...

Definition at line 658 of file sequence_gcm_cse.c.

659 {
660  entity called = call_function(c);
661  return !(io_intrinsic_p(called) || ENTITY_IMPLIEDDO_P(called));
662 }

References call_function, ENTITY_IMPLIEDDO_P, and io_intrinsic_p().

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ increase_number_of_use_by_1()

static void increase_number_of_use_by_1 ( entity  ent,
statement  container 
)
static

Increase number of use of variable ent by one.

Reduce by 1 number of use of variables contained by statement Updated

Definition at line 813 of file sequence_gcm_cse.c.

814 {
815  if (bound_inserted_p(container))
816  {
817  statement updated, sblock = load_inserted(container);
819  sequence seq;
820  int step;
822 
823  seq = instruction_sequence(i);
824 
825  step = +1;
826  if(assignment_statement_p(container))
827  {
828  if (ent == left_side_of_assign_statement(container))
829  {
830  step = 0;
831  }
832  }
833 
834  if (!(updated = update_number_of_use(ent, sequence_statements(seq), step)))
835  {
836  pips_internal_error("No statement defines '%s'", entity_name(ent));
837  }
838 
839  /* Reduce by 1 number of use of variables contained by statement Updated */
840  {
843  {
845  FOREACH(EXPRESSION, arg,args)
846  {
847  syntax syn = expression_syntax(arg);
848  if(syntax_reference_p(syn))
849  {
852  }
853  }
854  }
855  }
856  }
857  else
858  {
859  pips_internal_error("No statement inserted!");
860  }
861 }
bool entity_empty_label_p(entity e)
Definition: entity.c:666
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define statement_label(x)
Definition: ri.h:2450
#define entity_name(x)
Definition: ri.h:2790
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514
static statement update_number_of_use(entity ent, list lst_stat, int up_down)
Update the number of use of statement defining 'ent' which is a member of list lst_stat with step up_...

References assignment_statement_p(), call_arguments, entity_empty_label_p(), entity_name, exp, EXPRESSION, expression_syntax, FOREACH, instruction_sequence, instruction_sequence_p, left_side_of_assign_statement(), pips_assert, pips_internal_error, reference_variable, right_side_of_assign_statement(), sequence_statements, statement_instruction, statement_label, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, and update_number_of_use().

Referenced by atom_cse_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ insert_before_statement()

static void insert_before_statement ( statement  news,
statement  s,
bool  last 
)
static

Just for test static void dump_list_of_statement(list l) { fprintf(stderr, "\n===== Dump List: \n"); MAP(STATEMENT, ss, { print_statement(ss); }, l); fprintf(stderr, "\n END dumpt List!!! \n"); }.

Statements are stored in reverse order... this will have to be fixed latter on. see #1#.

Insert in the front of list

Insert just before the appropriate statement of list

Definition at line 383 of file sequence_gcm_cse.c.

384 {
386  if (!bound_inserted_p(s))
387  {
388  store_inserted(s, make_block_statement(CONS(STATEMENT, news, NIL)));
389  }
390  else
391  {
392  statement sb = load_inserted(s);
394 
396 
397  /* Statements are stored in reverse order...
398  this will have to be fixed latter on. see #1#.
399  */
400 
401  /* Insert in the front of list
402  * ===========================
403  */
404  if (last)
405  {
407  }
408  /* Insert just before the appropriate statement of list
409  * ====================================================
410  */
411  else
412  {
413  instruction_block(i) =
415  }
416  }
417 }
void cleanup_subscripts(void *)
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
#define statement_block_p(stat)
#define instruction_block(i)
static list insertion_statement_in_correct_position(statement news, list l)
Insert statement s in the list of statement l.
Definition: statement.c:4047
A gen_chunk is used to store every object.
Definition: genC.h:58

References cleanup_subscripts(), CONS, entity_empty_label_p(), insertion_statement_in_correct_position(), instruction_block, make_block_statement(), NIL, pips_assert, STATEMENT, statement_block_p, statement_instruction, and statement_label.

Referenced by atom_cse_expression(), atomize_or_associate_for_level(), and do_atomize_if_different_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ insert_rwt()

static void insert_rwt ( statement  s)
static

Insert the new statements created.

Reverse list of inserted statements (#1#)

Remove statements redundant

need some patching

Definition at line 957 of file sequence_gcm_cse.c.

958 {
959  if (bound_inserted_p(s))
960  {
961  statement sblock = load_inserted(s);
963  sequence seq;
964 
965  pips_assert("it is a sequence", instruction_sequence_p(i) && entity_empty_label_p(statement_label(sblock)));
966 
967  /* Reverse list of inserted statements (#1#) */
968  seq = instruction_sequence(i);
969 
970  /* Remove statements redundant */
972 
974  /* need some patching */
982 
984  }
985 }
instruction copy_instruction(instruction p)
INSTRUCTION.
Definition: ri.c:1115
void free_extensions(extensions p)
Definition: ri.c:950
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
entity entity_empty_label(void)
Definition: entity.c:1105
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
#define statement_extensions(x)
Definition: ri.h:2464
bool clone(const string)

References clone(), CONS, copy_instruction(), empty_extensions(), entity_empty_label(), entity_empty_label_p(), free_extensions(), gen_nreverse(), instruction_sequence, instruction_sequence_p, instruction_to_statement(), pips_assert, remove_statement_redundant(), sequence_statements, STATEMENT, statement_extensions, statement_instruction, statement_label, and update_statement_instruction().

Referenced by perform_ac_cse(), and perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ insertion_statement_in_correct_position()

static list insertion_statement_in_correct_position ( statement  news,
list  l 
)
static

Insert statement s in the list of statement l.

Definition at line 358 of file sequence_gcm_cse.c.

359 {
361  statement s = STATEMENT(CAR(l));
362 
363  if (entity_undefined_p(ent) || entity_as_arguments(ent, s) || ENDP(CDR(l)) )
364  {
365  return CONS(STATEMENT, s, CONS(STATEMENT, news, CDR(l)));
366  }
367  return CONS(STATEMENT, s,
369 }
static bool entity_as_arguments(entity ent, statement stat)
Verify if entity ent is an argument in the right expression of the assign statement stat.

References CAR, CDR, CONS, ENDP, entity_as_arguments(), entity_undefined_p, left_side_of_assign_statement(), and STATEMENT.

Referenced by insert_before_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ interference_on()

static bool interference_on ( entity  var,
list  les 
)
static

Compute if an effect list Some effect in les interfere with var.

Parameters
[in]varis the variable to test interference with the effects
[in]lesis the effect list to look for var
Returns
true if there may be a write effect on var

There is an interference only if there is a write effect:

If an effect can write anywhere, it may be also on var:

If we may have a write effect on var, mark a conflict:

Parameters
lesof effect

Definition at line 174 of file sequence_gcm_cse.c.

175 {
176  FOREACH(EFFECT, ef, les) {
177  /* There is an interference only if there is a write effect: */
178  if (effect_write_p(ef)) {
180  /* If an effect can write anywhere, it may be also on var: */
181  return true;
182 
184  /* If we may have a write effect on var, mark a conflict: */
185  return true;
186  }
187  }
188  return false;
189 }
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984

References EFFECT, effect_any_reference, effect_entity(), effect_write_p, entities_may_conflict_p(), entity_all_locations_p(), FOREACH, and reference_variable.

Referenced by moveable_to().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Is_Associative_Commutative()

static bool Is_Associative_Commutative ( entity  e)
static

Definition at line 81 of file sequence_gcm_cse.c.

82 {
83  const char* local_name = entity_local_name(e);
84  int i = 0;
85 
86  while (table_of_AC_operators[i])
87  {
89  pips_debug(3," %s is Associative Commutative \n", local_name);
90  return true;
91  }
92  i++;
93  }
94  pips_debug(3," %s is NOT Associative Commutative \n", local_name);
95  return false;
96 }
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
#define same_string_p(s1, s2)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
static char * table_of_AC_operators[]
option:

References entity_local_name(), local_name(), pips_debug, same_string_p, and table_of_AC_operators.

Referenced by atom_cse_expression(), atomize_or_associate_for_level(), make_available_scalar(), and similarity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ left_side_of_assign_statement()

static entity left_side_of_assign_statement ( statement  stat)
static

Return the entity in left side of an assign statement.

Definition at line 347 of file sequence_gcm_cse.c.

348 {
350  if( ! syntax_reference_p(expression_syntax(left_side)) )
351  return entity_undefined;
352  else
354 }
#define entity_undefined
Definition: ri.h:2761

References entity_undefined, expr_left_side_of_assign_statement(), expression_syntax, reference_variable, syntax_reference, and syntax_reference_p.

Referenced by atom_cse_expression(), cse_expression_flt(), increase_number_of_use_by_1(), insertion_statement_in_correct_position(), and update_number_of_use().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ level_of()

static int level_of ( list  le)
static

Return the level of this expression, using the current nesting list.

0: before any statement! n: outside nth loop. and so on.

of statement

Parameters
leof effects

Definition at line 208 of file sequence_gcm_cse.c.

209 {
210  list /* of statement */ up_nesting = gen_nreverse(gen_copy_seq(nesting));
211  int level = 0;
212  FOREACH(STATEMENT, s,up_nesting)
213  {
214  if (moveable_to(le, s))
215  break;
216  else
217  level++;
218  }
219  gen_free_list(up_nesting);
220  return level;
221 
222 }
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
static bool moveable_to(list le, statement s)
Whether sg with effects le can be moved up to s.

References FOREACH, gen_copy_seq(), gen_free_list(), gen_nreverse(), level, moveable_to(), nesting, and STATEMENT.

Referenced by expr_level_of().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ list_diff()

static list list_diff ( list  l1,
list  l2 
)
static

of expression

returns an allocated l1-l2 with expression_equal_p l2 included in l1.

of expression

Definition at line 1576 of file sequence_gcm_cse.c.

1577 {
1578  list diff = NIL, l2bis = gen_copy_seq(l2);
1579  expression found;
1580 
1581  FOREACH(EXPRESSION, e,l1)
1582  {
1583  if (expression_eq_in_list_p(e, l2bis, &found))
1584  {
1585  gen_remove(&l2bis, found);
1586  }
1587  else
1588  {
1589  diff = CONS(EXPRESSION, e, diff);
1590  }
1591  }
1592 
1593  if (l2bis) gen_free_list(l2bis);
1594 
1595  return diff;
1596 }
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685

References CONS, EXPRESSION, expression_eq_in_list_p(), FOREACH, gen_copy_seq(), gen_free_list(), gen_remove(), and NIL.

Referenced by atom_cse_expression(), and similarity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ loop_flt()

static bool loop_flt ( loop  l)
static

RK: Why ?

Definition at line 701 of file sequence_gcm_cse.c.

702 {
703  statement sofl = current_statement_head();
704  pips_assert("statement of loop",
706  /* RK: Why ? */
707  push_nesting(sofl);
708  return true;
709 }
#define instruction_loop(x)
Definition: ri.h:1520
static void push_nesting(statement s)
Keep track of statement nesting.

References instruction_loop, pips_assert, push_nesting(), and statement_instruction.

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ loop_rwt()

static void loop_rwt ( loop  l)
static

RK: Why ?

Deal with loop bound expressions

Nothing to do if we are in the top-level statement

Atomize the loop bound expressions:

Definition at line 711 of file sequence_gcm_cse.c.

712 {
713  range bounds;
714  int level;
715  statement sofl = current_statement_head();
716  /* RK: Why ? */
717  pop_nesting(sofl);
718 
719  /* Deal with loop bound expressions
720  */
721  if (!currently_nested_p())
722  /* Nothing to do if we are in the top-level statement */
723  return;
724  bounds = loop_range(l);
725  level = current_level();
726  /* Atomize the loop bound expressions: */
730 }
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
static void pop_nesting(statement s)
Pop the current statement from nesting list.

References current_level(), currently_nested_p(), do_atomize_if_different_level(), level, loop_range, pop_nesting(), range_increment, range_lower, and range_upper.

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ loop_stop()

static bool loop_stop ( loop  l,
__attribute__((unused)) list skip_list 
)
static

Definition at line 1859 of file sequence_gcm_cse.c.

1860 {
1862  return true;
1863 }
#define loop_body(x)
Definition: ri.h:1644

References gen_recurse_stop(), and loop_body.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ make_available_scalar()

static available_scalar_pt make_available_scalar ( entity  scalar,
statement  container,
expression  contents 
)
static

Definition at line 1521 of file sequence_gcm_cse.c.

1524 {
1525  pips_debug(2,"adding new scalar to pool:%s\nas a container for %s\n",
1526  entity_user_name(scalar),expression_to_string(contents));
1527  syntax s = expression_syntax(contents);
1528 
1529  available_scalar_pt aspt =
1531 
1532  aspt->scalar = scalar;
1533  aspt->container = container;
1534  aspt->contents = contents;
1535 
1536  aspt->depends = get_all_entities(contents);
1537 
1538  aspt->w_effects = w_effects;
1539 
1540  if (syntax_call_p(s))
1541  {
1542  call c = syntax_call(s);
1543  aspt->operator = call_function(c);
1546  else
1547  aspt->available_contents = NIL;
1548  }
1549  else
1550  {
1551  aspt->operator = NULL;
1552  aspt->available_contents = NIL;
1553  }
1554 
1555  return aspt;
1556 }
void * malloc(YYSIZE_T)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
static list get_all_entities(expression e)

References available_scalar_t::available_contents, call_arguments, call_function, available_scalar_t::container, available_scalar_t::contents, available_scalar_t::depends, entity_user_name(), expression_syntax, expression_to_string(), gen_copy_seq(), get_all_entities(), Is_Associative_Commutative(), malloc(), NIL, available_scalar_t::operator, pips_debug, available_scalar_t::scalar, syntax_call, syntax_call_p, w_effects, and available_scalar_t::w_effects.

Referenced by atom_cse_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ moveable_to()

static bool moveable_to ( list  le,
statement  s 
)
static

Whether sg with effects le can be moved up to s.

Parameters
leof effects

Definition at line 194 of file sequence_gcm_cse.c.

195 {
197  FOREACH(EFFECT, ef,le)
199  return false;
200  return true;
201 }
list load_cumulated_rw_effects_list(statement)
static bool interference_on(entity var, list les)
Compute if an effect list Some effect in les interfere with var.

References EFFECT, effect_any_reference, FOREACH, interference_on(), load_cumulated_rw_effects_list(), and reference_variable.

Referenced by level_of().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ number_of_use_greater_1()

static bool number_of_use_greater_1 ( statement  s)
static

PDSon: I use the field 'comments' of statement for counting its number of use.

Raison: The field 'comments' of new statement added is always empty! This function verifies if number of use is greater than 1 or not.

Definition at line 736 of file sequence_gcm_cse.c.

737 {
738  char* comment = statement_comments(s);
739  int number = 0;
740 
742  {
743  return false;
744  }
745 
746  sscanf((const char*)comment,"%d", &number);
747  return (number > 1);
748 }
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
bool empty_comments_p(const char *)
Definition: statement.c:107

References comment(), empty_comments_p(), and statement_comments.

Referenced by cse_expression_flt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ perform_ac_cse()

void perform_ac_cse ( __attribute__((unused)) const char *  name,
statement  s 
)

they have to be recomputed, because if ICM before.

set full (expr and statements) PROPER EFFECTS well, they are computed twice here... looks rather temporary.

make_current_statement_stack();

insert moved code in statement.

Remove the "inserted" mapping:

Definition at line 2034 of file sequence_gcm_cse.c.

2035 {
2036  /* they have to be recomputed, because if ICM before. */
2037 
2038  /* set full (expr and statements) PROPER EFFECTS
2039  well, they are computed twice here...
2040  looks rather temporary.
2041  */
2042  /*
2043  full_simple_proper_effects(name, s);
2044  simple_cumulated_effects(name, s);
2045  */
2046 
2047  /* make_current_statement_stack(); */
2048  init_inserted();
2049 
2053  0);
2054 
2055  /* insert moved code in statement. */
2058  /* Remove the "inserted" mapping: */
2059  close_inserted();
2060  /*
2061  close_expr_prw_effects();
2062  close_proper_rw_effects();
2063  close_rw_effects();
2064  */
2065 }
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346
static void insert_rwt(statement s)
Insert the new statements created.
static bool call_flt(call c)
handle all calls not in a sequence
static bool seq_flt(sequence s)
top down.

References call_domain, call_flt(), cleanup_subscripts(), gen_multi_recurse(), gen_null(), gen_true(), insert_rwt(), seq_flt(), sequence_domain, and statement_domain.

+ Here is the call graph for this function:

◆ perform_icm_association()

void perform_icm_association ( const char *  name,
statement  s 
)

Perform ICM and association on operators.

sequence_gcm_cse.c

This is kind of an atomization. many side effects: modifies the code, uses simple effects

Parameters
[in]namespecified the module name to work on
[in,out]sis the statement of the module

GET CUMULATED EFFECTS

SG: reorder expression so that the icm algorithm matches more cases

Set full (expr and statements) PROPER EFFECTS

Initialize the "inserted" mapping:

Create the stack to track current statement:

ATOMIZE and REASSOCIATE by level.

On each statement, we push the statement top-down on the current_statement stack, and when climbing bottom-up, we pull back the statement and verify it was the same on the stack. Nowadays we could use statement parent information directly from NewGen...

Atomize instructions with calls during bottom-up phase:

could also push while loops...

do not atomize index computations at the time...

skip IO calls

Insert moved code in statement at the right place:

Delete the stack used to track current statement:

no memory leaks?

some clean up

This only works in Fortran because of C local declarations. It's easier to let restructure_control() or flatten_code take care of it.

Parameters
nameame
sof the module of the module

Definition at line 1002 of file sequence_gcm_cse.c.

1004 {
1005  pips_assert("clean static structures on entry",
1006  (get_current_statement_stack() == stack_undefined) &&
1007  inserted_undefined_p() &&
1008  (nesting==NIL));
1009 
1010  /*
1011  simple_cumulated_effects(name, s);
1012  set_cumulated_rw_effects(get_rw_effects());
1013  */
1014 
1015  /* GET CUMULATED EFFECTS
1016  */
1018  db_get_memory_resource(DBR_CUMULATED_EFFECTS, name, true));
1019 
1020  /* SG: reorder expression so that the icm algorithm matches more cases */
1022 
1023  /* Set full (expr and statements) PROPER EFFECTS
1024  */
1025  full_simple_proper_effects(name, s);
1026 
1027  /* Initialize the "inserted" mapping: */
1028  init_inserted();
1029  /* Create the stack to track current statement: */
1030  make_current_statement_stack();
1031 
1032 #if defined(PUSH_BODY)
1033  push_nesting(s);
1034 #endif
1035 
1036  /* ATOMIZE and REASSOCIATE by level.
1037  */
1039  /* On each statement, we push the statement top-down
1040  on the current_statement stack, and when climbing
1041  bottom-up, we pull back the statement and verify it
1042  was the same on the stack. Nowadays we could use
1043  statement parent information directly from
1044  NewGen... */
1045  statement_domain, current_statement_filter, current_statement_rewrite,
1046  /* Atomize instructions with calls during bottom-up
1047  phase: */
1049  /* */
1053  /* could also push while loops... */
1055  /* do not atomize index computations at the time... */
1056  //reference_domain, gen_false, gen_null,
1057  call_domain, icm_atom_call_flt, gen_null, /* skip IO calls */
1058  NULL);
1059  /* Insert moved code in statement at the right place: */
1061 
1062 
1063 #if defined(PUSH_BODY)
1064  pop_nesting(s);
1065 #endif
1066 
1067  pips_assert("clean static structure on exit",
1068  (nesting==NIL) &&
1069  (current_statement_size()==0));
1070 
1071  /* Delete the stack used to track current statement: */
1072  free_current_statement_stack();
1073  close_inserted();
1074 
1076 
1077  close_expr_prw_effects(); /* no memory leaks? */
1079 
1080  /* some clean up */
1081  /* This only works in Fortran because of C local declarations. It's
1082  easier to let restructure_control() or flatten_code take care of
1083  it. */
1084  //flatten_sequences(s);
1085 }
void close_expr_prw_effects(void)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
void close_proper_rw_effects(void)
bool full_simple_proper_effects(const char *, statement)
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define stack_undefined
Definition: newgen_stack.h:55
#define instruction_domain
newgen_functional_domain_defined
Definition: ri.h:202
static void atomize_or_associate(expression e)
static void atomize_whileloop(whileloop w)
static void atomize_instruction(instruction i)
Atomize an instruction with call.
static bool prepare_icm(statement s)
static void loop_rwt(loop l)
static bool loop_flt(loop l)
static void atomize_test(test t)
static bool icm_atom_call_flt(call c)
Don't go into I/O calls...

References atomize_instruction(), atomize_or_associate(), atomize_test(), atomize_whileloop(), call_domain, close_expr_prw_effects(), close_proper_rw_effects(), db_get_memory_resource(), expression_domain, full_simple_proper_effects(), gen_multi_recurse(), gen_null(), gen_recurse, gen_true(), icm_atom_call_flt(), insert_rwt(), instruction_domain, loop_domain, loop_flt(), loop_rwt(), nesting, NIL, pips_assert, pop_nesting(), prepare_icm(), push_nesting(), reset_cumulated_rw_effects(), set_cumulated_rw_effects(), stack_undefined, statement_domain, test_domain, and whileloop_domain.

Referenced by optimize_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_nesting()

static void pop_nesting ( statement  s)
static

Pop the current statement from nesting list.

Definition at line 135 of file sequence_gcm_cse.c.

136 {
137  list old = nesting;
138  pips_assert("same ", nesting && (s == STATEMENT(CAR(nesting))));
139  nesting = CDR(nesting);
140  CDR(old) = NIL;
141  gen_free_list(old);
142 }

References CAR, CDR, gen_free_list(), nesting, NIL, pips_assert, and STATEMENT.

Referenced by loop_rwt(), and perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepare_icm()

static bool prepare_icm ( statement  s)
static

Definition at line 987 of file sequence_gcm_cse.c.

987  {
988  if(statement_loop_p(s)) {
989  try_reorder_expressions(s,true);
990  }
991  return true;
992 }
bool statement_loop_p(statement)
Definition: statement.c:349
void try_reorder_expressions(void *s, bool icm)

References statement_loop_p(), and try_reorder_expressions().

Referenced by perform_icm_association().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prune_non_constant()

static void prune_non_constant ( list  effects,
list perms 
)
static

Definition at line 1957 of file sequence_gcm_cse.c.

1957  {
1958  list out = NIL;
1959  FOREACH(EXPRESSION,exp,*perms) {
1961  bool conflict = false;
1962  SET_FOREACH(entity,e,re) {
1964  conflict=true;
1965  break;
1966  }
1967  }
1968  set_free(re);
1970  }
1971  gen_free_list(*perms);
1972  *perms=out;
1973 }
static FILE * out
Definition: alias_check.c:128
bool effects_write_variable_p(list, entity)
Definition: effects.c:1091
#define SET_FOREACH(type_name, the_item, the_set)
enumerate set elements in their internal order.
Definition: newgen_set.h:78
void set_free(set)
Definition: set.c:332
set get_referenced_entities(void *elem)
retrieves the set of entities used in elem beware that this entities may be formal parameters,...
Definition: entity.c:3063
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References CONS, effects_write_variable_p(), exp, EXPRESSION, FOREACH, gen_free_list(), get_referenced_entities(), NIL, out, SET_FOREACH, and set_free().

Referenced by try_reorder_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prune_singleton()

static void prune_singleton ( list l)
static

Definition at line 1282 of file sequence_gcm_cse.c.

1282  {
1283  list new = NIL;
1284  FOREACH(EXPRESSION,e0,*l) {
1285  FOREACH(EXPRESSION,e1,*l) {
1286  if(e0!=e1 && same_expression_p(e0,e1) ) {
1287  new=CONS(EXPRESSION,copy_expression(e0),new);
1288  break;
1289  }
1290  }
1291  }
1292  gen_full_free_list(*l);
1293  *l=new;
1294 }
bool same_expression_p(expression e1, expression e2)
this is slightly different from expression_equal_p, as it will return true for a+b vs b+a
Definition: expression.c:1426

References CONS, copy_expression(), EXPRESSION, FOREACH, gen_full_free_list(), NIL, and same_expression_p().

Referenced by try_reorder_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ push_nesting()

static void push_nesting ( statement  s)
static

Keep track of statement nesting.

Definition at line 129 of file sequence_gcm_cse.c.

130 {
131  nesting = CONS(STATEMENT, s, nesting);
132 }

References CONS, nesting, and STATEMENT.

Referenced by loop_flt(), and perform_icm_association().

+ Here is the caller graph for this function:

◆ remove_statement_redundant()

static void remove_statement_redundant ( statement  s,
list inserted 
)
static

Remove statement redundant inserted before statement s.

Definition at line 946 of file sequence_gcm_cse.c.

947 {
948  gen_context_multi_recurse(s, inserted,
951  NULL);
952 }
static bool cse_call_flt(call c, __attribute__((unused)) list *inserted)
Avoid visit the left side of assign statement.
static bool cse_expression_flt(expression e, list *inserted)

References call_domain, cse_call_flt(), cse_expression_flt(), expression_domain, gen_context_multi_recurse(), and gen_null().

Referenced by cse_expression_flt(), and insert_rwt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ reorder_pointer_expression()

static void reorder_pointer_expression ( expression  e)
static

make sure expressions are ordered with pointer first

Definition at line 1218 of file sequence_gcm_cse.c.

1218  {
1219  if(expression_call_p(e)) {
1220  call c = expression_call(e);
1221  if(commutative_call_p(c)) {
1222  expression lhs = binary_call_lhs(c),
1223  rhs = binary_call_rhs(c);
1224  basic brhs = basic_of_expression(rhs);
1225  if(basic_pointer_p(brhs)) {
1228  rhs,lhs);
1229  }
1230  }
1233  }
1234 }
#define make_expression_list(stats...)
#define binary_call_rhs(c)
bool commutative_call_p(call c)
Test if we are allowed to commute operations.
Definition: entity.c:2661
bool expression_call_p(expression e)
Definition: expression.c:415
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
#define basic_pointer_p(x)
Definition: ri.h:635

References basic_of_expression(), basic_pointer_p, binary_call_lhs, binary_call_rhs, call_arguments, commutative_call_p(), EXPRESSION, expression_call(), expression_call_p(), FOREACH, gen_free_list(), and make_expression_list.

Referenced by do_gather_all_expressions_perms().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ right_side_of_assign_statement()

static expression right_side_of_assign_statement ( statement  stat)
static

Definition at line 283 of file sequence_gcm_cse.c.

284 {
285  instruction i;
286  call assign;
287  expression right_side;
288 
289  i = statement_instruction(stat);
290 
291  pips_assert("Instruction is a call", instruction_call_p(i));
292  assign = instruction_call(i);
293 
294  pips_assert("Call is an assignment!",
295  ENTITY_ASSIGN_P(call_function(assign)));
296 
297  right_side = EXPRESSION(CAR(CDR(call_arguments(assign))));
298 
299  return right_side;
300 }

References call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, EXPRESSION, instruction_call, instruction_call_p, pips_assert, and statement_instruction.

Referenced by cse_expression_flt(), entity_as_arguments(), and increase_number_of_use_by_1().

+ Here is the caller graph for this function:

◆ seq_flt()

static bool seq_flt ( sequence  s)
static

top down.

At first, w_effects is empty list BUT not list points to NIL!!!

SG: not valid due to newgen check w_effects = &CDR(CONS(EXPRESSION, NIL, NIL));

top_of_w_effects points to the top of list, It is used to free memory later

SG we try to perform some reordering of linear expression to ease matching. To do so we (optimistically) gather similar expressions, and when pairs are found, they are kept for further matching. The pair gathering is store unaware, but the later process takes care of this. At worse we did some useless reordering.

Free top_of_w_effects and availables

Definition at line 1987 of file sequence_gcm_cse.c.

1988 {
1989  pips_debug(1,"considering statement:\n");
1990  ifdebug(1) {
1992  print_statement(ss);
1993  }
1994  list availables = NIL;
1995  list *top_of_w_effects;
1996 
1997  /* At first, w_effects is empty list BUT not list points to NIL!!!*/
1998  /* SG: not valid due to newgen check w_effects = &CDR(CONS(EXPRESSION, NIL, NIL));*/
1999  w_effects = &CDR(gen_cons(NIL,NIL));
2000 
2001  /* top_of_w_effects points to the top of list,
2002  * It is used to free memory later
2003  */
2004  top_of_w_effects = w_effects;
2005 
2006  /* SG we try to perform some reordering of linear expression to ease matching.
2007  * To do so we (optimistically) gather similar expressions, and when pairs are found, they are kept for further matching.
2008  * The pair gathering is store unaware, but the later process takes care of this. At worse we did some useless reordering.*/
2009  try_reorder_expressions(s,false);
2010 
2012  {
2013  availables = atomize_cse_this_statement_expressions(ss, availables);
2014  }
2015 
2016  /* Free top_of_w_effects and availables */
2017  gen_full_free_list(*top_of_w_effects);
2018  return true;
2019 }

References atomize_cse_this_statement_expressions(), CDR, FOREACH, gen_cons(), gen_full_free_list(), ifdebug, NIL, pips_debug, print_statement(), sequence_statements, STATEMENT, try_reorder_expressions(), and w_effects.

Referenced by perform_ac_cse().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_comment_of_statement()

static void set_comment_of_statement ( statement  s,
char *  new_comment 
)
static

Update the field 'comments' of a statement.

Definition at line 752 of file sequence_gcm_cse.c.

753 {
755  {
756  statement_comments(s) = new_comment;
757  }
758  else
759  {
761  statement_comments(s) = new_comment;
762  }
763 }
void free(void *)

References empty_comments_p(), free(), and statement_comments.

Referenced by atom_cse_expression(), cse_expression_flt(), and update_number_of_use().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ side_effects_p()

static bool side_effects_p ( expression  e)
static

There is a side effect if there is a W effect in the expression.

of effect

Definition at line 152 of file sequence_gcm_cse.c.

153 {
154  pips_debug(1,"considering expression %s\n",expression_to_string(e));
156  list /* of effect */ le = effects_effects(ef);
157  FOREACH(EFFECT, ef,le)
158  if (effect_write_p(ef)) {
159  pips_debug(1,"has side effects\n");
160  return true;
161  }
162  pips_debug(1,"does not have side effects\n");
163  return false;
164 }

References EFFECT, effect_write_p, effects_effects, expression_to_string(), FOREACH, load_expr_prw_effects(), and pips_debug.

Referenced by do_atomize_if_different_level(), and group_expr_by_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ similarity()

static int similarity ( expression  e,
available_scalar_pt  aspt 
)
static

Find the commun sub-expression between e & aspt.

Attention: Commun expression does't contain any expression in w_effects

same function...

similarity is the number of args in common. inversion is not tested at the time.

any call: must be equal

A variable is already modified !

Definition at line 1427 of file sequence_gcm_cse.c.

1428 {
1429  syntax s = expression_syntax(e), sa = expression_syntax(aspt->contents);
1430 
1431  /*
1432  fprintf(stderr, "similarity on %s\n", entity_name(aspt->scalar));
1433  print_expression(e);
1434  dump_aspt(aspt);
1435  */
1436 
1437  if (syntax_tag(s)!=syntax_tag(sa)) return NO_SIMILARITY;
1438 
1439  if (syntax_reference_p(s))
1440  {
1441  reference r = syntax_reference(s), ra = syntax_reference(sa);
1442  if (reference_equal_p(r, ra))
1443  {
1444  return MAX_SIMILARITY;
1445  }
1446  }
1447 
1448  if (syntax_call_p(s))
1449  {
1450  call c = syntax_call(s), ca = syntax_call(sa);
1451  entity cf = call_function(c);
1452  if (cf!=call_function(ca)) return NO_SIMILARITY;
1453 
1454  /* same function...
1455  */
1457  {
1458  /* similarity is the number of args in common.
1459  inversion is not tested at the time.
1460  */
1462  *(aspt->w_effects)),
1463  aspt->available_contents);
1464  size_t n = gen_length(com);
1465  gen_free_list(com);
1466  if (n<=1) return NO_SIMILARITY;
1467  return (n == gen_length(call_arguments(ca)) &&
1468  n == gen_length(call_arguments(c))) ? MAX_SIMILARITY: n;
1469  }
1470  else
1471  {
1472  /* any call: must be equal
1473  */
1474  list l = call_arguments(c), la = call_arguments(ca);
1475  pips_assert("same length", gen_length(l)==gen_length(la));
1476  for (; l; l = CDR(l), la = CDR(la))
1477  {
1478  expression el = EXPRESSION(CAR(l)), ela = EXPRESSION(CAR(la));
1479  if (!expression_equal_p(el, ela))
1480  {
1481  return NO_SIMILARITY;
1482  }
1483 
1484  if (expression_eq_in_list_p(el, *(aspt->w_effects), &el))
1485  {
1486  /* A variable is already modified ! */
1487  return NO_SIMILARITY;
1488  }
1489  }
1490  return MAX_SIMILARITY;
1491  }
1492  }
1493 
1494  return NO_SIMILARITY;
1495 }
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
#define NO_SIMILARITY

References available_scalar_t::available_contents, call_arguments, call_function, CAR, CDR, common_expressions(), available_scalar_t::contents, EXPRESSION, expression_eq_in_list_p(), expression_equal_p(), expression_syntax, gen_free_list(), gen_length(), Is_Associative_Commutative(), list_diff(), MAX_SIMILARITY, NO_SIMILARITY, pips_assert, reference_equal_p(), syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, syntax_tag, and available_scalar_t::w_effects.

Referenced by best_similar_expression().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ statement_of_level()

static statement statement_of_level ( int  level)
static

or for a statement.

Returns the statement of the specified level should returns current_statement_head() to avoid ICM directly.

Definition at line 261 of file sequence_gcm_cse.c.

262 {
263 #if !defined(NO_ICM)
264  int n = current_level()-1-level;
265 
266  if (n>=0)
267  return STATEMENT(gen_nth(n, nesting));
268  else
269 #endif
270  return current_statement_head();
271 }
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710

References current_level(), gen_nth(), level, nesting, and STATEMENT.

Referenced by atomize_or_associate_for_level(), and do_atomize_if_different_level().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ test_stop()

static bool test_stop ( test  t,
__attribute__((unused)) list skip_list 
)
static

Definition at line 1865 of file sequence_gcm_cse.c.

1866 {
1869  return true;
1870 }
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835

References gen_recurse_stop(), test_false, and test_true.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ try_reorder_expression_call()

static bool try_reorder_expression_call ( expression  e,
list  availables 
)
static

update normalized field, and make sure it is consistent

the idea is to split an expression into two linear parts, one that is already available and one that is not

Definition at line 1171 of file sequence_gcm_cse.c.

1171  {
1172  /* update normalized field, and make sure it is consistent */
1176  /* the idea is to split an expression into two linear parts, one that is already available and one that is not */
1177  if(normalized_linear_p(n)){
1178  Pvecteur pv =normalized_linear(n);
1179  int cplx =vect_size(pv);
1180  int bestcplx = INT_MAX;
1181  expression bestexp = expression_undefined;
1182  FOREACH(EXPRESSION,eavailable, availables){
1183  NORMALIZE_EXPRESSION(eavailable);
1184  normalized navailable = expression_normalized(eavailable);
1185  if(normalized_linear_p(navailable)) {
1186  Pvecteur pva = normalized_linear(navailable);
1187  Pvecteur diff = vect_substract(pv,pva);
1188  int dcplx = vect_size(diff);
1189  if(dcplx < cplx && dcplx < bestcplx) {
1190  bestexp = eavailable;
1191  bestcplx=dcplx;
1192  }
1193  vect_rm(diff);
1194  }
1195  }
1196  if(!expression_undefined_p(bestexp) && !same_expression_p(e,bestexp)) {
1199  make_call(
1203  copy_expression(e),
1204  copy_expression(bestexp)
1205  ),
1206  copy_expression(bestexp)
1207  )
1208  )
1209  )
1210  );
1211  return false;
1212  }
1213  }
1214  return true;
1215 }
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define MINUS_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
void update_expression_syntax(expression e, syntax s)
frees expression syntax of e and replace it by the new syntax s
Definition: expression.c:3564
#define expression_undefined_p(x)
Definition: ri.h:1224
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75

References copy_expression(), entity_intrinsic(), EXPRESSION, expression_normalized, expression_undefined, expression_undefined_p, FOREACH, make_call(), make_expression_list, make_op_exp(), make_syntax_call(), MINUS_OPERATOR_NAME, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, PLUS_C_OPERATOR_NAME, same_expression_p(), unnormalize_expression(), update_expression_syntax(), vect_rm(), vect_size(), and vect_substract().

Referenced by try_reorder_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ try_reorder_expressions()

void try_reorder_expressions ( void *  s,
bool  icm 
)
Parameters
icmcm

Definition at line 1975 of file sequence_gcm_cse.c.

1976  {
1977  list gathered = NIL;
1980  else prune_singleton(&gathered);
1981  gen_context_recurse(s, gathered,
1983  gen_full_free_list(gathered);
1984  }
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
static bool do_gather_all_expressions(expression e, list *gathered)
bool icm(const char *module_name)
Pipsmake phase: Invariant Code Motion.
static void prune_singleton(list *l)
static void prune_non_constant(list effects, list *perms)
static bool try_reorder_expression_call(expression e, list availables)

References do_gather_all_expressions(), expression_domain, gen_context_recurse, gen_full_free_list(), gen_null2(), icm(), load_cumulated_rw_effects_list(), NIL, prune_non_constant(), prune_singleton(), and try_reorder_expression_call().

Referenced by prepare_icm(), and seq_flt().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_number_of_use()

static statement update_number_of_use ( entity  ent,
list  lst_stat,
int  up_down 
)
static

Update the number of use of statement defining 'ent' which is a member of list lst_stat with step up_down (up_down = 1 | 0 | -1).

If ent is a variable of original code (ex: x, y), not new variable added (ex: F_0, F_1,..), there is not any statement in lst_stat defining ent. Return: statement updated

First time, no value

Update old value

Definition at line 771 of file sequence_gcm_cse.c.

772 {
773  FOREACH(STATEMENT, s,lst_stat)
774  {
775  entity left_side = left_side_of_assign_statement(s);
776  if(ent == left_side) // s defines ent
777  {
778  if (up_down == 0)
779  {
780  return s;
781  }
782 
783  /* First time, no value */
785  {
786  if (up_down == -1)
787  {
788  pips_internal_error("Number of use of '%s' < 0 !!!",
789  entity_name(ent));
790  }
792  }
793  /* Update old value */
794  else
795  {
796  char *new;
797  int number_use = 0;
798  char* comment = statement_comments(s);
799  sscanf((const char*)comment, "%d", &number_use);
800 
801  number_use += up_down;
802  new=int2a(number_use);
803  set_comment_of_statement(s, (new));
804  }
805  return s;
806  }
807  }
808 
809  return NULL;
810 }
char * int2a(int)
util.c
Definition: util.c:42

References comment(), empty_comments_p(), entity_name, FOREACH, int2a(), left_side_of_assign_statement(), pips_internal_error, set_comment_of_statement(), STATEMENT, statement_comments, and strdup().

Referenced by increase_number_of_use_by_1().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ while_stop()

static bool while_stop ( whileloop  wl,
__attribute__((unused)) list skip_list 
)
static

Definition at line 1872 of file sequence_gcm_cse.c.

1873 {
1875  return true;
1876 }
#define whileloop_body(x)
Definition: ri.h:3162

References gen_recurse_stop(), and whileloop_body.

Referenced by atomize_cse_this_statement_expressions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ current_available

list current_available = NIL
static

statement stack to current statement.

statements to be inserted as a sequence. For CSE

Definition at line 119 of file sequence_gcm_cse.c.

Referenced by atom_cse_expression(), atomize_cse_this_statement_expressions(), and best_similar_expression().

◆ current_statement

◆ nesting

list nesting = NIL
static

assumes:

  • cumulated effects (as a dependence abstraction).
  • proper effects for statements AND sub-expressions... current nesting of code, bottom-up order, to determine level.

Definition at line 108 of file sequence_gcm_cse.c.

Referenced by adg_path_possible_source(), current_level(), level_of(), perform_icm_association(), pop_nesting(), push_nesting(), and statement_of_level().

◆ seen

◆ table_of_AC_operators

char* table_of_AC_operators[]
static
Initial value:

option:

  • whether to push the procedure statement (default no).
  • whether to do ICM or not directly (default yes). #define PUSH_BODY #define NO_ICM List of associative and commutative n-ary operators

Definition at line 68 of file sequence_gcm_cse.c.

Referenced by Is_Associative_Commutative().

◆ w_effects

list* w_effects
static

PDSon: w_effect store all the variables modified in the sequence of statement.

Definition at line 125 of file sequence_gcm_cse.c.

Referenced by atomize_cse_this_statement_expressions(), call_flt(), cse_atom_call_flt(), make_available_scalar(), seq_flt(), and two_addresses_code_generator().