PIPS
simdizer.c File Reference
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "resources.h"
#include "misc.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "pipsdbm.h"
#include "effects-generic.h"
#include "effects-convex.h"
#include "effects-simple.h"
#include "accel-util.h"
#include "ray_dte.h"
#include "sommet.h"
#include "sg.h"
#include "polyedre.h"
#include "sac.h"
#include "ricedg.h"
#include "control.h"
#include "callgraph.h"
+ Include dependency graph for simdizer.c:

Go to the source code of this file.

Data Structures

struct  simdizer_context
 

Macros

#define SWAP_ARGUMENTS(c)   do { call_arguments(c)=gen_nreverse(call_arguments(c)) ; return ;} while(0)
 
#define NOSWAP_ARGUMENTS(c)   return
 

Functions

static void init_statement_matches_map (list l)
 
static void free_statement_matches_map ()
 
static list get_statement_matches (statement s)
 
match get_statement_match_of_kind (statement s, opcodeClass kind)
 simdizer.c More...
 
static set get_statement_matching_types (statement s)
 
static bool conflict_is_a_real_conflict_p (conflict c, statement source, statement sink, size_t loop_level)
 this code is here because levels information seems inaccurate so it checks all the possible conflict between source and  sink that could have generated c and then instead of using references_may_conflict, it assumes we are in ssa form which should be ok thanks to scalar renaming, and symbolically computes the distance between each reference More...
 
static bool successor_only_has_rr_conflict_p (vertex v, successor su, size_t loop_level)
 
static void free_statement_equivalence_table ()
 
static set extract_non_conflicting_statements (statement s, list tail)
 
static set extract_matching_statements (statement s, set stats, set *matches)
 
static bool sac_statement_to_expressions_gather (expression e, list *l)
 
static list sac_statement_to_expressions (statement s)
 
static bool comparable_statements_on_distance_p (statement s0, statement s1)
 
static int compare_statements_on_ordering (const void *v0, const void *v1)
 
static void set_statement_origin (statement s)
 
static void reset_statement_origin ()
 
static int compare_statements_on_distance_to_origin (const void *ps0, const void *ps1)
 
static int compare_list_from_length (const void *v0, const void *v1)
 
static list order_isomorphic_statements_list (list ordered)
 
static list order_isomorphic_statements (set s)
 
static void init_statement_equivalence_table (list *l, graph dependence_graph, size_t loop_level)
 
static list simdize_simple_statements_pass2 (list seq, float *simdCost)
 
static void simdize_simple_statements (statement s, simdizer_context *sc)
 
static bool simd_simple_sequence_filter (statement s, __attribute__((unused)) simdizer_context *sc)
 
string sac_commenter (entity e)
 
static bool incr_counter (loop l, simdizer_context *sc)
 
static void decr_counter (loop l, simdizer_context *sc)
 
bool simdizer (char *mod_name)
 
static void do_simdizer_init (call c)
 
static void do_split_block_statements (statement s)
 
static void do_split_decl_block_statements (statement s)
 
bool simdizer_init (const char *module_name)
 

Variables

static hash_table matches = NULL
 
static hash_table equivalence_table = hash_table_undefined
 
static statement origin =NULL
 
statement sac_current_block = statement_undefined
 
instruction sac_real_current_instruction = instruction_undefined
 

Macro Definition Documentation

◆ NOSWAP_ARGUMENTS

#define NOSWAP_ARGUMENTS (   c)    return

◆ SWAP_ARGUMENTS

#define SWAP_ARGUMENTS (   c)    do { call_arguments(c)=gen_nreverse(call_arguments(c)) ; return ;} while(0)

Function Documentation

◆ comparable_statements_on_distance_p()

static bool comparable_statements_on_distance_p ( statement  s0,
statement  s1 
)
static

Definition at line 344 of file simdizer.c.

345 {
348  list iter=exp1;
349  FOREACH(EXPRESSION,e0,exp0)
350  {
351  expression e1 = EXPRESSION(CAR(iter));
352  expression distance = distance_between_expression(e1,e0);
353  intptr_t val=0;
354  if(!expression_undefined_p(distance))
355  {
356  (void)expression_integer_value(distance,&val);
357  free_expression(distance);
358  if(val) return true;
359  }
360  POP(iter);
361  if(ENDP(iter)) break;
362  }
363  return false;
364 }
void free_expression(expression p)
Definition: ri.c:853
#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
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined_p(x)
Definition: ri.h:1224
expression distance_between_expression(const expression exp0, const expression exp1)
computes the distance betwwen two expression
Definition: codegen.c:419
s1
Definition: set.c:247
static list sac_statement_to_expressions(statement s)
Definition: simdizer.c:320
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, distance_between_expression(), ENDP, EXPRESSION, expression_integer_value(), expression_undefined_p, FOREACH, free_expression(), intptr_t, POP, s1, and sac_statement_to_expressions().

Referenced by order_isomorphic_statements_list().

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

◆ compare_list_from_length()

static int compare_list_from_length ( const void *  v0,
const void *  v1 
)
static

Definition at line 469 of file simdizer.c.

470 {
471  const list l0=*(const list*)v0;
472  const list l1=*(const list*)v1;
473  size_t n0 = gen_length(l0);
474  size_t n1 = gen_length(l1);
475  return n0==n1 ? 0 : n0 > n1 ? 1 : -1;
476 }
size_t gen_length(const list l)
Definition: list.c:150

References gen_length().

Referenced by order_isomorphic_statements_list().

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

◆ compare_statements_on_distance_to_origin()

static int compare_statements_on_distance_to_origin ( const void *  ps0,
const void *  ps1 
)
static

Definition at line 415 of file simdizer.c.

415  {
416 
417  const statement s0 = *(const statement*)ps0;
418  const statement s1 = *(const statement*)ps1;
422  size_t dist0=0,
423  dist1=0;
424  static const int dinf=1000;
425 
426  list iter0 = exp0,iter1=exp1;
427  FOREACH(EXPRESSION,eo,expo)
428  {
429  expression e0 = ENDP(iter0)? expression_undefined:EXPRESSION(CAR(iter0)),
430  e1 = ENDP(iter1)? expression_undefined:EXPRESSION(CAR(iter1));
433  intptr_t val0=0, val1;
434  if(!expression_undefined_p(distance0))
435  {
436  if(expression_integer_value(distance0,&val0)) {
437  dist0+=val0*val0;
438  }
439  else dist0+=dinf*dinf;
440  free_expression(distance0);
441 
442  }
443  else if(expression_scalar_p(e0) && expression_scalar_p(e1))
444  dist0+=1;
445  else
446  dist0+=dinf*dinf;
447  if(!expression_undefined_p(distance1))
448  {
449  if(expression_integer_value(distance1,&val1)) {
450  dist1+=val1*val1;
451  }
452  else dist1+=dinf*dinf;
453  free_expression(distance1);
454 
455  }
456  else if(expression_scalar_p(e0) && expression_scalar_p(e1))
457  dist1+=1;
458  else
459  dist1+=dinf*dinf;
460  POP(iter0);
461  POP(iter1);
462  }
463  gen_free_list(expo);
464  gen_free_list(exp0);
465  gen_free_list(exp1);
466  return dist0>dist1? 1 : dist0 == dist1 ? 0 : -1;
467 }
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define expression_scalar_p(e)
#define expression_undefined
Definition: ri.h:1223
static statement origin
Definition: simdizer.c:411

References CAR, distance_between_expression(), ENDP, EXPRESSION, expression_integer_value(), expression_scalar_p, expression_undefined, expression_undefined_p, FOREACH, free_expression(), gen_free_list(), intptr_t, origin, POP, s1, and sac_statement_to_expressions().

Referenced by order_isomorphic_statements_list().

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

◆ compare_statements_on_ordering()

static int compare_statements_on_ordering ( const void *  v0,
const void *  v1 
)
static

Definition at line 365 of file simdizer.c.

366 {
367  const statement s0 = *(const statement*)v0;
368  const statement s1 = *(const statement*)v1;
369  if (statement_ordering(s0) > statement_ordering(s1)) return 1;
370  if (statement_ordering(s0) < statement_ordering(s1)) return -1;
371  return 0;
372 }
#define statement_ordering(x)
Definition: ri.h:2454

References s1, and statement_ordering.

Referenced by init_statement_equivalence_table(), order_isomorphic_statements(), and order_isomorphic_statements_list().

+ Here is the caller graph for this function:

◆ conflict_is_a_real_conflict_p()

static bool conflict_is_a_real_conflict_p ( conflict  c,
statement  source,
statement  sink,
size_t  loop_level 
)
static

this code is here because levels information seems inaccurate so it checks all the possible conflict between source and  sink that could have generated c and then instead of using references_may_conflict, it assumes we are in ssa form which should be ok thanks to scalar renaming, and symbolically computes the distance between each reference

hack no longer needed , simple is beautiful

Definition at line 138 of file simdizer.c.

138  {
139  pips_assert("true", source==source && sink==sink);
140  cone co = conflict_cone(c);
141  if(!cone_undefined_p(co)) {
142  bool no_intra_loop_dep = true;
143  FOREACH(INT,i,cone_levels(co))
144  if(i == (int) loop_level +1 )
145  no_intra_loop_dep = false;
146 #if 0 /* hack no longer needed , simple is beautiful */
147  if(!no_intra_loop_dep) /* there seems to be an intra loop dep, verify this */ {
149  source_ref = effect_any_reference(conflict_source(c));
150  if(same_entity_p(reference_variable(sink_ref),reference_variable(source_ref))) {
151  list sink_effects = load_proper_rw_effects_list(sink),
152  source_effects = load_proper_rw_effects_list(source);
153  sink_effects = effect_read_p(conflict_sink(c))?
154  effects_read_effects(sink_effects):
155  effects_write_effects(sink_effects);
156  source_effects = effect_read_p(conflict_source(c))?
157  effects_read_effects(source_effects):
158  effects_write_effects(source_effects);
159  set sink_refs = set_make(set_pointer),
160  source_refs = set_make(set_pointer);
161 
162  FOREACH(EFFECT,eff,sink_effects)
164  set_add_element(sink_refs,sink_refs,effect_any_reference(eff));
165  FOREACH(EFFECT,eff,source_effects)
167  set_add_element(source_refs,source_refs,effect_any_reference(eff));
168  no_intra_loop_dep = true;
169  SET_FOREACH(reference,rsink,sink_refs) {
170  expression esink = reference_to_expression(rsink);
171  SET_FOREACH(reference,rsource,source_refs) {
172  expression esource = reference_to_expression(rsource);
173  expression d = distance_between_expression(esink,esource);
174  intptr_t val;
175  if(expression_undefined_p(d) ||
176  !expression_integer_value(d,&val) ||
177  val == 0) {
178  no_intra_loop_dep = false;
179  }
180  }
181  }
182  set_free(sink_refs);
183  set_free(source_refs);
184  gen_free_list(sink_effects);
185  gen_free_list(source_effects);
186  }
187  }
188 #endif
189  return !no_intra_loop_dep;
190  }
191  else
192  return true;
193 }
@ INT
Definition: atomic.c:48
#define conflict_sink(x)
Definition: dg.h:167
#define cone_levels(x)
Definition: dg.h:128
#define cone_undefined_p(x)
Definition: dg.h:105
#define conflict_source(x)
Definition: dg.h:165
#define conflict_cone(x)
Definition: dg.h:169
list effects_read_effects(list)
list load_proper_rw_effects_list(statement)
list effects_write_effects(list)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool effects_may_conflict_p(effect eff1, effect eff2)
Check if two effect may conflict @description Two effects may conflict if their abstract two location...
Definition: conflicts.c:162
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#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_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
expression reference_to_expression(reference r)
Definition: expression.c:196
#define reference_variable(x)
Definition: ri.h:2326
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References cone_levels, cone_undefined_p, conflict_cone, conflict_sink, conflict_source, distance_between_expression(), EFFECT, effect_any_reference, effect_read_p, effects_may_conflict_p(), effects_read_effects(), effects_write_effects(), expression_integer_value(), expression_undefined_p, FOREACH, gen_free_list(), INT, intptr_t, load_proper_rw_effects_list(), pips_assert, reference_to_expression(), reference_variable, same_entity_p(), set_add_element(), SET_FOREACH, set_free(), set_make(), and set_pointer.

Referenced by successor_only_has_rr_conflict_p().

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

◆ decr_counter()

static void decr_counter ( loop  l,
simdizer_context sc 
)
static

Definition at line 843 of file simdizer.c.

843  {
844  pips_assert("true", l==l);
845  sc->nb_enclosing_loops--;
846 }
size_t nb_enclosing_loops
Definition: simdizer.c:727

References simdizer_context::nb_enclosing_loops, and pips_assert.

Referenced by simdizer().

+ Here is the caller graph for this function:

◆ do_simdizer_init()

static void do_simdizer_init ( call  c)
static

constant first

then scalar

we finally end with two references

Definition at line 907 of file simdizer.c.

908 {
909 #define SWAP_ARGUMENTS(c) do { call_arguments(c)=gen_nreverse(call_arguments(c)) ; return ;} while(0)
910 #define NOSWAP_ARGUMENTS(c) return
911  if(commutative_call_p(c))
912  {
913  pips_assert("commutative call are binary calls",gen_length(call_arguments(c))==2);
914  expression e0 = binary_call_lhs(c),
915  e1 = binary_call_rhs(c);
916  /* constant first */
919  /* then scalar */
922 
923  /* we finally end with two references */
925  {
926  expression distance = distance_between_expression(e0,e1);
927  intptr_t val;
928  if( !expression_undefined_p(distance) && expression_integer_value(distance,&val))
929  {
930  free_expression(distance);
931  if(val <= 0) NOSWAP_ARGUMENTS(c);
932  else SWAP_ARGUMENTS(c) ;
933  }
934  else
935  {
936  entity ent0 = expression_to_entity(e0);
937  entity ent1 = expression_to_entity(e1);
938  if(compare_entities(&ent0,&ent1)<=0) NOSWAP_ARGUMENTS(c);
939  else SWAP_ARGUMENTS(c) ;
940  }
941  }
942  else
943  {
944  string msg = words_to_string(Words_Call(c,0,true,true));
945  pips_user_warning("unable to decide how to commute %s\n",msg);
946  free(msg);
947  }
948  }
949 #undef SWAP_ARGUMENTS
950 #undef NOSWAP_ARGUMENTS
951 }
void free(void *)
#define pips_user_warning
Definition: misc-local.h:146
list Words_Call(call obj, int precedence, bool leftmost, bool is_a_subroutine)
Definition: misc.c:2597
#define binary_call_rhs(c)
#define binary_call_lhs(c)
bool commutative_call_p(call c)
Test if we are allowed to commute operations.
Definition: entity.c:2661
int compare_entities(const entity *pe1, const entity *pe2)
Comparison function for qsort.
Definition: entity.c:1328
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
bool extended_expression_constant_p(expression exp)
Returns true if the value of the expression does not depend syntactically on the current store.
Definition: expression.c:2461
#define call_arguments(x)
Definition: ri.h:711
bool expression_reference_or_field_p(expression e)
Definition: codegen.c:192
#define NOSWAP_ARGUMENTS(c)
#define SWAP_ARGUMENTS(c)
string words_to_string(cons *lw)
Definition: print.c:211

References binary_call_lhs, binary_call_rhs, call_arguments, commutative_call_p(), compare_entities(), distance_between_expression(), expression_integer_value(), expression_reference_or_field_p(), expression_scalar_p, expression_to_entity(), expression_undefined_p, extended_expression_constant_p(), free(), free_expression(), gen_length(), intptr_t, NOSWAP_ARGUMENTS, pips_assert, pips_user_warning, SWAP_ARGUMENTS, Words_Call(), and words_to_string().

Referenced by simdizer_init().

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

◆ do_split_block_statements()

static void do_split_block_statements ( statement  s)
static

Definition at line 953 of file simdizer.c.

953  {
954  if(statement_block_p(s)) {
955  list blocks = NIL;
956  list iter=statement_block(s);
957  while(!ENDP(iter)) {
958  list curr = NIL;
959  bool block_created = false;
960  do {
961  statement st = STATEMENT(CAR(iter));
962  POP(iter);
964  if(!ENDP(curr))
967  block_created=true;
968  }
969  else
970  curr=CONS(STATEMENT,st,curr);
971  } while(!ENDP(iter)&&!block_created);
972  if(!block_created) {
973  curr=gen_nreverse(curr);
975  }
976  }
980  }
981 }
static list blocks
lisp of loops
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
sequence statement_sequence(statement)
Get the sequence of a statement sequence.
Definition: statement.c:1328
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
#define statement_block_p(stat)
bool entity_empty_label_p(entity e)
Definition: entity.c:666
#define statement_label(x)
Definition: ri.h:2450
#define sequence_statements(x)
Definition: ri.h:2360
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413

References blocks, CAR, CONS, ENDP, entity_empty_label_p(), gen_free_list(), gen_nreverse(), make_block_statement(), NIL, POP, sequence_statements, STATEMENT, statement_block(), statement_block_p, statement_label, and statement_sequence().

Referenced by simdizer_init().

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

◆ do_split_decl_block_statements()

static void do_split_decl_block_statements ( statement  s)
static

is there a tail return ?

yes there is

is there a tail return ?

yes there is

not using insert_statement because it is too smart ! we want to keep a block

Definition at line 983 of file simdizer.c.

983  {
984  if(statement_block_p(s)) {
985  list iter,prev=NIL;
986  for(iter=statement_block(s);!ENDP(iter) && declaration_statement_p(STATEMENT(CAR(iter))); POP(iter) ) {
987  prev=iter;
988  }
989  if(!ENDP(iter) && !ENDP(prev) ) {
990  CDR(prev)=NIL;
991  statement tail = make_block_statement(iter);
992  /* is there a tail return ? */
993  list iter2,prev2=NIL;
994  for(iter2=iter;!ENDP(iter2) && !return_statement_p(STATEMENT(CAR(iter2))); POP(iter2) ) {
995  prev2=iter2;
996  }
997  if(!ENDP(iter2) && !ENDP(prev2) ) { /* yes there is */
998  CDR(prev2)=NIL;
999  statement rtail = make_block_statement(iter2);
1000  insert_statement_no_matter_what(STATEMENT(CAR(prev)),tail,false);
1001  insert_statement_no_matter_what(STATEMENT(CAR(prev)),rtail,false);
1002  }
1003  else {
1004  insert_statement_no_matter_what(STATEMENT(CAR(prev)),tail,false);
1005  }
1006  }
1007  else {
1008  /* is there a tail return ? */
1009  list iter2,prev2=NIL;
1010  for(iter2=iter=statement_block(s);!ENDP(iter2) && !return_statement_p(STATEMENT(CAR(iter2))); POP(iter2) ) {
1011  prev2=iter2;
1012  }
1013  if(!ENDP(iter2) && !ENDP(prev2) ) { /* yes there is */
1014  CDR(prev2)=NIL;
1015  statement rtail = make_block_statement(iter2);
1016  /* not using insert_statement because it is too smart ! we want to keep a block*/
1018  }
1019  }
1020  }
1021 }
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
list gen_append(list l1, const list l2)
Definition: list.c:471
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
void insert_statement_no_matter_what(statement, statement, bool)
Break the IR consistency or, at the very least, do not insert new declarations at the usual place,...
Definition: statement.c:2581
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
#define make_statement_list(stats...)
easy list constructor

References CAR, CDR, declaration_statement_p(), ENDP, gen_append(), insert_statement_no_matter_what(), make_block_statement(), make_statement_list, NIL, POP, return_statement_p(), STATEMENT, statement_block(), and statement_block_p.

Referenced by simdizer_init().

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

◆ extract_matching_statements()

static set extract_matching_statements ( statement  s,
set  stats,
set matches 
)
static

Definition at line 279 of file simdizer.c.

280 {
281  pips_assert("true", s==s);
283  SET_FOREACH(statement,st,stats)
284  {
286  set tmp = set_make(set_pointer);
287  set_intersection(tmp,*matches,smt);
288  if(set_empty_p(tmp))
289  {
290  set_free(tmp);
291  }
292  else {
294  if( simd_check_argType()){
295  *matches=tmp;
296  set_add_element(out,out,st);
297  }
298  else {
299  ifdebug(3){
300  pips_debug(3,"following statement does not have good arg type\n");
301  print_statement(st);
302  }
303  }
304  }
305  set_free(smt);
306  }
307  return out;
308 }
static FILE * out
Definition: alias_check.c:128
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
bool set_empty_p(const set)
tell whether set s is empty.
Definition: set.c:367
set set_intersection(set, const set, const set)
Definition: set.c:229
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
bool simd_check_argType(void)
Definition: treematch.c:87
void simd_fill_curArgType(statement)
Definition: treematch.c:82
#define ifdebug(n)
Definition: sg.c:47
static set get_statement_matching_types(statement s)
Definition: simdizer.c:119
static hash_table matches
Definition: simdizer.c:60

References get_statement_matching_types(), ifdebug, matches, out, pips_assert, pips_debug, print_statement(), set_add_element(), set_empty_p(), SET_FOREACH, set_free(), set_intersection(), set_make(), set_pointer, simd_check_argType(), and simd_fill_curArgType().

Referenced by simdize_simple_statements_pass2().

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

◆ extract_non_conflicting_statements()

static set extract_non_conflicting_statements ( statement  s,
list  tail 
)
static

Definition at line 257 of file simdizer.c.

258 {
260  pips_assert("table is correct",equivalences!= HASH_UNDEFINED_VALUE);
261 
264 
265  set stail = set_make(set_pointer);
266  set_assign_list(stail,tail);
267 
268  set_intersection(eq,eq,stail);
269  set_free(stail);
270  ifdebug(3) {
271  pips_debug(3,"non conficting statement with\n");
272  print_statement(s);
274  print_statement(st);
275  }
276 
277  return eq;
278 }
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
struct cons * list
Definition: newgen_types.h:106
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
static hash_table equivalence_table
Definition: simdizer.c:129

References eq, equivalence_table, hash_get(), HASH_UNDEFINED_VALUE, ifdebug, pips_assert, pips_debug, print_statement(), set_assign_list(), SET_FOREACH, set_free(), set_intersection(), set_make(), and set_pointer.

Referenced by simdize_simple_statements_pass2().

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

◆ free_statement_equivalence_table()

static void free_statement_equivalence_table ( )
static

leak spotted !

Definition at line 250 of file simdizer.c.

251 {
253  hash_table_free(equivalence_table);/* leak spotted !*/
255 }
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49

References equivalence_table, hash_table_free(), hash_table_undefined, hash_table_undefined_p, and pips_assert.

Referenced by simdize_simple_statements().

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

◆ free_statement_matches_map()

static void free_statement_matches_map ( )
static

Definition at line 81 of file simdizer.c.

82 {
84 }

References hash_table_free(), and matches.

Referenced by simdize_simple_statements().

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

◆ get_statement_match_of_kind()

match get_statement_match_of_kind ( statement  s,
opcodeClass  kind 
)

simdizer.c

Parameters
kindind

Definition at line 101 of file simdizer.c.

102 {
104 
105  for( ; l!=NIL; l=CDR(l))
106  {
107  match m = MATCH(CAR(l));
108  if (match_type(m) == kind)
109  return m;
110  }
111 
112  return match_undefined;
113 }
#define MATCH(x)
MATCH.
Definition: sac_private.h:221
#define match_type(x)
Definition: sac_private.h:251
#define match_undefined
Definition: sac_private.h:227
static list get_statement_matches(statement s)
Definition: simdizer.c:90

References CAR, CDR, get_statement_matches(), MATCH, match_type, match_undefined, and NIL.

Referenced by make_simd_statements().

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

◆ get_statement_matches()

static list get_statement_matches ( statement  s)
static

Definition at line 90 of file simdizer.c.

91 {
93  return m;
94 }
list hash_get_default_empty_list(const hash_table h, const void *k)
Like hash_get() but returns an empty list instead of HASH_UNDEFINED_VALUE when a key is not found.
Definition: hash.c:475

References hash_get_default_empty_list(), and matches.

Referenced by get_statement_match_of_kind(), and get_statement_matching_types().

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

◆ get_statement_matching_types()

static set get_statement_matching_types ( statement  s)
static

Definition at line 119 of file simdizer.c.

120 {
122 
125 
126  return out;
127 }

References FOREACH, get_statement_matches(), MATCH, match_type, out, set_add_element(), set_make(), and set_pointer.

Referenced by extract_matching_statements(), and simdize_simple_statements_pass2().

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

◆ incr_counter()

static bool incr_counter ( loop  l,
simdizer_context sc 
)
static

Definition at line 838 of file simdizer.c.

838  {
839  pips_assert("true", l==l);
840  sc->nb_enclosing_loops++;
841  return true;
842 }

References simdizer_context::nb_enclosing_loops, and pips_assert.

Referenced by simdizer().

+ Here is the caller graph for this function:

◆ init_statement_equivalence_table()

static void init_statement_equivalence_table ( list l,
graph  dependence_graph,
size_t  loop_level 
)
static

for faster access

first extract corresponding vertices

then count the references between each other

do not take into account backward references, or R-R conflicts

now recursievly retreive the head of each vertex with no reference on them and reorder initial statement list

fill the head

found nothing, assume we are in the tail

remove those vertex from the head and decrease references elsewhere

do not take into account backward references and ignored statements

Definition at line 519 of file simdizer.c.

520 {
523 
524  /* for faster access */
525  set statements = set_make(set_pointer);
526  set_assign_list(statements,*l);
528 
529  /* first extract corresponding vertices */
531  {
532  statement s = vertex_to_statement(a_vertex);
533  if(set_belong_p(statements,s))
534  hash_put(counters,a_vertex,(void*)0);
535  }
536  /* then count the references between each other */
537  for(void *k,*v,*iter=NULL; (iter=hash_table_scan(counters,iter,&k,&v));)
538  {
540  {
541  /* do not take into account backward references, or R-R conflicts */
543  !successor_only_has_rr_conflict_p((vertex)k,su,loop_level) )
544  {
545  void* counter = hash_get(counters,successor_vertex(su));
546  if(counter != HASH_UNDEFINED_VALUE)
547  {
548  intptr_t value = (intptr_t)counter;
549  ++value;
550  pips_debug(4,"counter now is %td for\n",value);
552  pips_debug(4,"referenced by\n");
554  hash_update(counters,successor_vertex(su),(void*)value);
555  }
556  }
557  }
558  }
559 
560  /* now recursievly retreive the head of each vertex with no reference on them
561  * and reorder initial statement list */
562  list new_l = NIL;
563  while(!hash_table_empty_p(counters))
564  {
565  set head = set_make(set_pointer);
566  /* fill the head */
567  HASH_MAP(k,v,if((intptr_t)v == 0) set_add_element(head,head,k), counters);
568  /* found nothing, assume we are in the tail */
569  if(set_empty_p(head))
570  {
571  list equivalence_list = NIL;
572  HASH_MAP(k,v,equivalence_list=CONS(STATEMENT,vertex_to_statement((vertex)k),equivalence_list),counters);
573  HASH_MAP(k,v, hash_put(equivalence_table,vertex_to_statement((vertex)k),equivalence_list), counters);
574  hash_table_clear(counters);
575  new_l = gen_nconc(new_l, equivalence_list);
576  }
577  /* remove those vertex from the head and decrease references elsewhere */
578  else
579  {
580  list equivalence_list = NIL;
581  { SET_FOREACH(vertex,v,head) equivalence_list=CONS(STATEMENT,vertex_to_statement(v),equivalence_list); }
583 
584  SET_FOREACH(vertex,v,head) {
586  void* counter = hash_get(counters,successor_vertex(su));
587  /* do not take into account backward references and ignored statements */
589  {
590  intptr_t value = (intptr_t)counter;
591  --value;
592  pips_assert("not missed something",value>=0);
593  hash_update(counters,successor_vertex(su),(void*)value);
594  }
595  }
597  pips_internal_error("failed");
599  hash_del(counters,v);
600  }
601  new_l = gen_nconc(new_l, equivalence_list);
602 
603  }
604  set_free(head);
605  }
606  hash_table_free(counters);
607  gen_free_list(*l);
608  *l = new_l;
609 }
static graph dependence_graph
Definition: delay.c:93
#define successor_vertex(x)
Definition: graph.h:118
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439
void * hash_table_scan(hash_table htp, void *hentryp_arg, void **pkey, void **pval)
Definition: hash.c:844
void hash_table_clear(hash_table htp)
Clears all entries of a hash table HTP.
Definition: hash.c:305
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
#define pips_internal_error
Definition: misc-local.h:149
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_DEFAULT_SIZE
Definition: newgen_hash.h:26
#define hash_table_empty_p(htp)
Definition: newgen_hash.h:58
bool set_belong_p(const set, const void *)
Definition: set.c:194
static list referenced
returns the list of referenced variables
Definition: utils.c:60
struct _newgen_struct_value_ * value
Definition: ri.h:455
int vertex_ordering(vertex)
Definition: util.c:51
static int compare_statements_on_ordering(const void *v0, const void *v1)
Definition: simdizer.c:365
static bool successor_only_has_rr_conflict_p(vertex v, successor su, size_t loop_level)
Definition: simdizer.c:195

References compare_statements_on_ordering(), CONS, dependence_graph, equivalence_table, FOREACH, gen_copy_seq(), gen_free_list(), gen_nconc(), gen_sort_list(), graph_vertices, HASH_DEFAULT_SIZE, hash_del(), hash_get(), HASH_MAP, hash_pointer, hash_put(), hash_table_clear(), hash_table_empty_p, hash_table_free(), hash_table_make(), hash_table_scan(), hash_table_undefined_p, HASH_UNDEFINED_VALUE, hash_update(), ifdebug, intptr_t, NIL, pips_assert, pips_debug, pips_internal_error, print_statement(), set_add_element(), set_assign_list(), set_belong_p(), set_empty_p(), SET_FOREACH, set_free(), set_make(), set_pointer, STATEMENT, SUCCESSOR, successor_only_has_rr_conflict_p(), successor_vertex, VERTEX, vertex_ordering(), vertex_successors, and vertex_to_statement().

Referenced by simdize_simple_statements().

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

◆ init_statement_matches_map()

static void init_statement_matches_map ( list  l)
static

Definition at line 66 of file simdizer.c.

67 {
69  FOREACH(STATEMENT, s,l)
70  {
72 
73  if (match != NIL)
74  hash_put(matches, (void *)s, (void *)match);
75  }
76 }
list match_statement(statement)
return a list of matching statements
Definition: treematch.c:237

References FOREACH, hash_pointer, hash_put(), hash_table_make(), match_statement(), matches, NIL, and STATEMENT.

Referenced by simdize_simple_statements().

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

◆ order_isomorphic_statements()

static list order_isomorphic_statements ( set  s)
static

Definition at line 508 of file simdizer.c.

508  {
510  return order_isomorphic_statements_list(ordered);
511 }
list set_to_sorted_list(const set, gen_cmp_func_t)
Definition: set.c:447
static list order_isomorphic_statements_list(list ordered)
Definition: simdizer.c:478

References compare_statements_on_ordering(), order_isomorphic_statements_list(), and set_to_sorted_list().

Referenced by simdize_simple_statements_pass2().

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

◆ order_isomorphic_statements_list()

static list order_isomorphic_statements_list ( list  ordered)
static

Definition at line 478 of file simdizer.c.

479 {
481  list heads = NIL;
482  while(!ENDP(ordered)) {
483  statement head = STATEMENT(CAR(ordered));
484  list firsts = CONS(STATEMENT,head,NIL);
485  list lasts = NIL;
486  FOREACH(STATEMENT,st,CDR(ordered))
487  {
489  firsts=CONS(STATEMENT,st,firsts);
490  else
491  lasts=CONS(STATEMENT,st,lasts);
492  }
493  gen_free_list(ordered);
494  set_statement_origin(head);
498  heads=CONS(LIST,firsts,heads);
499  ordered=lasts;
500  }
502  list out = NIL;
503  FOREACH(LIST,l,heads)
504  out=gen_nconc(l,out);
505  gen_free_list(heads);
506  return out;
507 }
#define LIST(x)
Definition: genC.h:93
static void reset_statement_origin()
Definition: simdizer.c:413
static void set_statement_origin(statement s)
Definition: simdizer.c:412
static int compare_statements_on_distance_to_origin(const void *ps0, const void *ps1)
Definition: simdizer.c:415
static int compare_list_from_length(const void *v0, const void *v1)
Definition: simdizer.c:469
static bool comparable_statements_on_distance_p(statement s0, statement s1)
Definition: simdizer.c:344

References CAR, CDR, comparable_statements_on_distance_p(), compare_list_from_length(), compare_statements_on_distance_to_origin(), compare_statements_on_ordering(), CONS, ENDP, FOREACH, gen_free_list(), gen_nconc(), gen_sort_list(), LIST, NIL, out, reset_statement_origin(), set_statement_origin(), and STATEMENT.

Referenced by order_isomorphic_statements(), and simdize_simple_statements_pass2().

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

◆ reset_statement_origin()

static void reset_statement_origin ( )
static

Definition at line 413 of file simdizer.c.

413 {origin=NULL;}

References origin.

Referenced by order_isomorphic_statements_list().

+ Here is the caller graph for this function:

◆ sac_commenter()

string sac_commenter ( entity  e)

Definition at line 821 of file simdizer.c.

822 {
823  if(sac_aligned_entity_p(e))
824  {
825  return strdup("SAC generated temporary array");
826  }
827  else if(simd_vector_entity_p(e))
828  {
829  string s,g = basic_to_string(entity_basic(e));
830  asprintf(&s,"PIPS:SAC generated %s vector(s)", g);
831  free(g);
832  return s;
833  }
834  else
835  return strdup("PIPS:SAC generated variable");
836 }
#define asprintf
Definition: misc-local.h:225
string basic_to_string(basic)
Definition: type.c:87
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
bool simd_vector_entity_p(entity e)
Definition: codegen.c:197
bool sac_aligned_entity_p(entity e)
Definition: codegen.c:646
char * strdup()

References asprintf, basic_to_string(), entity_basic(), free(), sac_aligned_entity_p(), simd_vector_entity_p(), and strdup().

Referenced by simdizer().

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

◆ sac_statement_to_expressions()

static list sac_statement_to_expressions ( statement  s)
static

Definition at line 320 of file simdizer.c.

321 {
322  list out = NIL;
324  return out;
325 }
#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
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
static bool sac_statement_to_expressions_gather(expression e, list *l)
Definition: simdizer.c:310

References expression_domain, gen_context_recurse, gen_null2(), NIL, out, and sac_statement_to_expressions_gather().

Referenced by comparable_statements_on_distance_p(), and compare_statements_on_distance_to_origin().

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

◆ sac_statement_to_expressions_gather()

static bool sac_statement_to_expressions_gather ( expression  e,
list l 
)
static

Definition at line 310 of file simdizer.c.

311 {
313  {
314  *l=CONS(EXPRESSION,e,*l);
315  return false;
316  }
317  return true;
318 }

References CONS, EXPRESSION, and expression_reference_or_field_p().

Referenced by sac_statement_to_expressions().

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

◆ set_statement_origin()

static void set_statement_origin ( statement  s)
static

Definition at line 412 of file simdizer.c.

412 {origin=s;}

References origin.

Referenced by order_isomorphic_statements_list().

+ Here is the caller graph for this function:

◆ simd_simple_sequence_filter()

static bool simd_simple_sequence_filter ( statement  s,
__attribute__((unused)) simdizer_context sc 
)
static

Definition at line 816 of file simdizer.c.

817 {
818  return ! ( instruction_call_p( statement_instruction(s) ) ) ;
819 }
#define instruction_call_p(x)
Definition: ri.h:1527
#define statement_instruction(x)
Definition: ri.h:2458

References instruction_call_p, and statement_instruction.

Referenced by simdizer().

+ Here is the caller graph for this function:

◆ simdize_simple_statements()

static void simdize_simple_statements ( statement  s,
simdizer_context sc 
)
static

not much we can do with a single statement, or with "complex" statements (ie, with tests/loops/...)

we cannot handle anything but sequence of calls

process already existing statements

Definition at line 740 of file simdizer.c.

741 {
742  /* not much we can do with a single statement, or with
743  * "complex" statements (ie, with tests/loops/...)
744  */
745  if (statement_block_p(s))
746  {
747  graph dependence_graph = sc->dg;
749  /* we cannot handle anything but sequence of calls */
750  list iter = statement_block(s);
753 
754  list new_seq = NIL;
755  while(!ENDP(iter))
756  {
757  list seq = NIL;
758  for(;!ENDP(iter);POP(iter))
759  {
760  statement st = STATEMENT(CAR(iter));
763  else {
764  if(statement_call_p(st))
765  seq=CONS(STATEMENT,st,seq);
766 
767  if(!statement_call_p(st)||ENDP(CDR(iter)))
768  {
769  /* process already existing statements */
770  if(!ENDP(seq))
771  {
772  seq=gen_nreverse(seq);
773 
776 
777  float saveSimdCost = 0;
778  list simdseq = simdize_simple_statements_pass2(seq, &saveSimdCost);
779 
780  pips_debug(2,"opcode cost1 %f\n", saveSimdCost);
781 
782  if((saveSimdCost >= 0.0))
783  {
784  new_seq=gen_append(new_seq,seq);
785  gen_free_list(simdseq);
786  }
787  else
788  {
789  new_seq=gen_append(new_seq,simdseq);
790  gen_free_list(seq);
791  sc->result |= true;
792  }
793 
796  seq=NIL;
797 
798  }
799  if(!statement_call_p(st))
800  new_seq=gen_append(new_seq,CONS(STATEMENT,st,NIL));
801  }
802  }
803 
804  }
805  }
807  gen_append(statement_block(s),new_seq);
808  }
809 }
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
bool statement_call_p(statement)
Definition: statement.c:364
#define instruction_sequence(x)
Definition: ri.h:1514
static list simdize_simple_statements_pass2(list seq, float *simdCost)
Definition: simdizer.c:611
static void free_statement_equivalence_table()
Definition: simdizer.c:250
static void free_statement_matches_map()
Definition: simdizer.c:81
statement sac_current_block
Definition: simdizer.c:722
static void init_statement_equivalence_table(list *l, graph dependence_graph, size_t loop_level)
Definition: simdizer.c:519
static void init_statement_matches_map(list l)
Definition: simdizer.c:66
instruction sac_real_current_instruction
Definition: simdizer.c:723

References CAR, CDR, CONS, declaration_statement_p(), dependence_graph, simdizer_context::dg, ENDP, free_statement_equivalence_table(), free_statement_matches_map(), gen_append(), gen_free_list(), gen_nreverse(), init_statement_equivalence_table(), init_statement_matches_map(), insert_statement_no_matter_what(), instruction_sequence, make_instruction_block(), simdizer_context::nb_enclosing_loops, NIL, pips_debug, POP, simdizer_context::result, sac_current_block, sac_real_current_instruction, sequence_statements, simdize_simple_statements_pass2(), STATEMENT, statement_block(), statement_block_p, statement_call_p(), and statement_instruction.

Referenced by simdizer().

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

◆ simdize_simple_statements_pass2()

static list simdize_simple_statements_pass2 ( list  seq,
float *  simdCost 
)
static

Traverse to list to group isomorphic statements

if this is not a recognized statement (ie, no match), skip it

try to find all the compatible isomorphic statements after the current statement

if the matches for statement sj and for the group have a non-empty intersection, and the move is legal (ie, does not break dependency chain) then we can add the statement sj to the group.

filter out already visited statements

Free the list of statements info

Set the new list as the statements' instructions

Definition at line 611 of file simdizer.c.

612 {
613  list newseq=NIL;
614 
615  //argument info dependencies are local to each sequence -> RESET
617 
618  set visited = set_make(set_pointer);
619 
620  /* Traverse to list to group isomorphic statements */
621  for(list i = seq;!ENDP(i);POP(i))
622  {
623  statement si = STATEMENT(CAR(i));
624  if(!set_belong_p(visited,si))
625  {
626  set_add_element(visited,visited,si);
627  ifdebug(3){
628  pips_debug(3,"trying to match statement\n");
629  print_statement(si);
630  }
631 
632  /* if this is not a recognized statement (ie, no match), skip it */
633  set group_matches = get_statement_matching_types(si);
634  if (set_empty_p(group_matches) )
635  {
636  pips_debug(3,"no match found\n");
638  newseq = CONS(STATEMENT,si,newseq);
639  continue;
640  }
641  else
642  {
643  ifdebug(3) {
644  pips_debug(3,"matching opcode found:\n");
645  SET_FOREACH(opcodeClass,oc,group_matches)
646  pips_debug(3,"%s\n",opcodeClass_name(oc));
647  }
648  }
649 
651  ifdebug(3) {
652  pips_debug(3,"examining following statments:\n");
653  print_statements(CDR(i));
654  }
655 
656  /* try to find all the compatible isomorphic statements after the
657  * current statement
658  */
659  /* if the matches for statement sj and for the group have a non-empty
660  * intersection, and the move is legal (ie, does not break dependency
661  * chain) then we can add the statement sj to the group.
662  */
663  set non_conflicting = extract_non_conflicting_statements(si,CDR(i));
664  /* filter out already visited statements */
665  set_difference(non_conflicting,non_conflicting,visited);
666  set isomorphics = extract_matching_statements(si,non_conflicting,&group_matches);
667  if(set_empty_p(isomorphics))
668  {
669  ifdebug(3){
670  pips_debug(3,"following statement cannot be moved\n");
671  print_statement(si);
672  }
674  newseq = CONS(STATEMENT,si,newseq);
675  }
676  else
677  {
678  set_add_element(isomorphics,isomorphics,si);
679  ifdebug(3){
680  pips_debug(3,"following statements matches!\n");
681  SET_FOREACH(statement,sj,isomorphics)
682  print_statement(sj);
683  }
684  list iso_stats = order_isomorphic_statements(isomorphics);
685  set_free(isomorphics);
686  for(list iso_iter=iso_stats;!ENDP(iso_iter);)
687  {
688  simdstatement ss = make_simd_statements(group_matches, iso_iter);
690  {
692  newseq = CONS(STATEMENT,si,newseq);
693  POP(iso_iter);
694  break;
695  }
696  else
697  {
698  newseq=gen_append(generate_simd_code(ss,simdCost),newseq);
699  for(intptr_t i= opcode_vectorSize(simdstatement_opcode(ss));i!=0;i--)
700  {
701  set_add_element(visited,visited,STATEMENT(CAR(iso_iter)));
702  POP(iso_iter);
703  }
704  iso_iter=order_isomorphic_statements_list(iso_iter);
705  }
706  }
707  set_free(group_matches);
708  //gen_free_list(iso_stats);
709  }
711  }
712  }
714  newseq=gen_nreverse(newseq);
715 
716  /* Free the list of statements info */
717 
718  /* Set the new list as the statements' instructions */
719  return newseq;
720 }
set set_difference(set, const set, const set)
Definition: set.c:256
void print_statements(list)
Definition: statement.c:103
simdstatement make_simd_statements(set opkinds, list statements)
Definition: codegen.c:1193
list generate_simd_code(simdstatement ssi, float *simdCost)
Definition: codegen.c:1325
void init_vector_to_expressions()
codegen.c
Definition: codegen.c:59
void invalidate_expressions_in_statement(statement s)
Definition: codegen.c:162
void reset_vector_to_expressions()
Definition: codegen.c:64
void simd_reset_finalArgType(void)
Definition: treematch.c:61
void simd_fill_finalArgType(statement)
Definition: treematch.c:77
#define opcode_vectorSize(x)
Definition: sac_private.h:291
#define simdstatement_opcode(x)
Definition: sac_private.h:491
#define simdstatement_undefined_p(x)
Definition: sac_private.h:466
#define opcodeClass_name(x)
Definition: sac_private.h:534
static set extract_non_conflicting_statements(statement s, list tail)
Definition: simdizer.c:257
static list order_isomorphic_statements(set s)
Definition: simdizer.c:508
static set extract_matching_statements(statement s, set stats, set *matches)
Definition: simdizer.c:279

References CAR, CDR, CONS, ENDP, extract_matching_statements(), extract_non_conflicting_statements(), gen_append(), gen_nreverse(), generate_simd_code(), get_statement_matching_types(), ifdebug, init_vector_to_expressions(), intptr_t, invalidate_expressions_in_statement(), make_simd_statements(), NIL, opcode_vectorSize, opcodeClass_name, order_isomorphic_statements(), order_isomorphic_statements_list(), pips_debug, POP, print_statement(), print_statements(), reset_vector_to_expressions(), set_add_element(), set_belong_p(), set_difference(), set_empty_p(), SET_FOREACH, set_free(), set_make(), set_pointer, simd_fill_finalArgType(), simd_reset_finalArgType(), simdstatement_opcode, simdstatement_undefined_p, and STATEMENT.

Referenced by simdize_simple_statements().

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

◆ simdizer()

bool simdizer ( char *  mod_name)

get the resources

Now do the job

Reorder the module, because new statements have been added

update/release resources

Parameters
mod_nameod_name

Definition at line 854 of file simdizer.c.

855 {
856  /* get the resources */
857  statement mod_stmt = (statement)
858  db_get_memory_resource(DBR_CODE, mod_name, true);
859 
860  set_current_module_statement(mod_stmt);
862  set_ordering_to_statement(mod_stmt);
863  simdizer_context sc = { .dg = (graph) db_get_memory_resource(DBR_DG, mod_name, true),
864  .nb_enclosing_loops = 0,
865  .result = false };
866  set_simd_treematch((matchTree)db_get_memory_resource(DBR_SIMD_TREEMATCH,"",true));
867  set_simd_operator_mappings(db_get_memory_resource(DBR_SIMD_OPERATOR_MAPPINGS,"",true));
868  statement_effects se = (statement_effects)db_get_memory_resource(DBR_PROPER_EFFECTS,mod_name,true);
869  remove_preferences(se);
873 
874  debug_on("SIMDIZER_DEBUG_LEVEL");
875 
876  /* Now do the job */
880  NULL);
881 
882  pips_assert("Statement is consistent after SIMDIZER",
883  statement_consistent_p(mod_stmt));
884 
885  /* Reorder the module, because new statements have been added */
886  clean_up_sequences(mod_stmt);
887  module_reorder(mod_stmt);
888  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
889  DB_PUT_MEMORY_RESOURCE(DBR_CALLEES, mod_name, compute_callees(mod_stmt));
890  //DB_PUT_MEMORY_RESOURCE(DBR_DG, mod_name, dependence_graph);
891 
892  /* update/release resources */
900 
901  debug_off();
902 
903  return sc.result;
904 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
void remove_preferences(void *)
delay.c
Definition: delay.c:89
callees compute_callees(const statement stat)
Recompute the callees of a module statement.
Definition: callgraph.c:355
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
struct _newgen_struct_statement_effects_ * statement_effects
Definition: effects.h:210
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
void set_conflict_testing_properties()
conflicts.c
Definition: conflicts.c:68
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
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 DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
void pop_generated_variable_commenter(void)
Definition: statement.c:2623
void push_generated_variable_commenter(string(*)(entity))
Definition: statement.c:2616
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
void reset_simd_operator_mappings()
Definition: operatorid.c:48
void set_simd_operator_mappings(void *m)
operatorid.c
Definition: operatorid.c:43
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
void reset_simd_treematch(void)
Definition: treematch.c:52
void set_simd_treematch(matchTree)
treematch.c
Definition: treematch.c:46
static void simdize_simple_statements(statement s, simdizer_context *sc)
Definition: simdizer.c:740
static bool incr_counter(loop l, simdizer_context *sc)
Definition: simdizer.c:838
static void decr_counter(loop l, simdizer_context *sc)
Definition: simdizer.c:843
static bool simd_simple_sequence_filter(statement s, __attribute__((unused)) simdizer_context *sc)
Definition: simdizer.c:816
string sac_commenter(entity e)
Definition: simdizer.c:821

References clean_up_sequences(), compute_callees(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, decr_counter(), simdizer_context::dg, gen_context_multi_recurse(), incr_counter(), loop_domain, module_name_to_entity(), module_reorder(), pips_assert, pop_generated_variable_commenter(), push_generated_variable_commenter(), remove_preferences(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), reset_proper_rw_effects(), reset_simd_operator_mappings(), reset_simd_treematch(), simdizer_context::result, sac_commenter(), set_conflict_testing_properties(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), set_proper_rw_effects(), set_simd_operator_mappings(), set_simd_treematch(), simd_simple_sequence_filter(), simdize_simple_statements(), statement_consistent_p(), and statement_domain.

+ Here is the call graph for this function:

◆ simdizer_init()

bool simdizer_init ( const char *  module_name)

get the resources

normalize blocks

then split blocks containing declarations statement

then split blocks containing labeled statement

sort commutative operators

reset

Parameters
module_nameodule_name

Definition at line 1023 of file simdizer.c.

1024 {
1025  /* get the resources */
1028 
1029  /* normalize blocks */
1031 
1032  /* then split blocks containing declarations statement */
1034 
1035  /* then split blocks containing labeled statement */
1037 
1038  /* sort commutative operators */
1040 
1043 
1044  /* reset */
1047 
1048  return true;
1049 
1050 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
static void do_split_decl_block_statements(statement s)
Definition: simdizer.c:983
static void do_simdizer_init(call c)
Definition: simdizer.c:907
static void do_split_block_statements(statement s)
Definition: simdizer.c:953

References call_domain, clean_up_sequences(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, do_simdizer_init(), do_split_block_statements(), do_split_decl_block_statements(), gen_recurse, gen_true(), get_current_module_statement(), module_name(), module_name_to_entity(), module_reorder(), reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), and statement_domain.

+ Here is the call graph for this function:

◆ successor_only_has_rr_conflict_p()

static bool successor_only_has_rr_conflict_p ( vertex  v,
successor  su,
size_t  loop_level 
)
static

regions tell us there is a conflict. check if the dependence is loop carried or not

Definition at line 195 of file simdizer.c.

196 {
197  bool all_rr = true;
199  {
202  )
203  {
204  pips_debug(3,
205  "conflict skipped between %s and %s\n",
208  }
209  else {
210 #if 0
212  if(ENDP(inter)) // why is this conflict generated ?!?
213  {
214  pips_debug(3,
215  "conflict skipped between %s and %s\n",
218  continue;
219  }
220  gen_full_free_list(inter);
221 #endif
222  /* regions tell us there is a conflict.
223  * check if the dependence is loop carried or not
224  * */
226 
227  if(!all_rr) {
228  pips_debug(3,"conflict found :\n");
229  ifdebug(3) {
232  }
233  }
234  else {
235  pips_debug(3,
236  "conflict not relevant between:\n");
237  ifdebug(3) {
240  }
241  }
242  }
243  }
244  return all_rr;
245 }
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
list region_intersection(region reg1, region reg2)
Intersection :
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define successor_arc_label(x)
Definition: graph.h:116
string reference_to_string(reference r)
Definition: expression.c:87
#define print_region(x)
Definition: print.c:343
static bool conflict_is_a_real_conflict_p(conflict c, statement source, statement sink, size_t loop_level)
this code is here because levels information seems inaccurate so it checks all the possible conflict ...
Definition: simdizer.c:138

References CONFLICT, conflict_is_a_real_conflict_p(), conflict_sink, conflict_source, dg_arc_label_conflicts, effect_any_reference, effect_read_p, ENDP, FOREACH, gen_full_free_list(), ifdebug, pips_debug, print_region, reference_to_string(), region_intersection(), successor_arc_label, successor_vertex, and vertex_to_statement().

Referenced by init_statement_equivalence_table().

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

Variable Documentation

◆ equivalence_table

◆ matches

◆ origin

◆ sac_current_block

statement sac_current_block = statement_undefined

Definition at line 722 of file simdizer.c.

Referenced by make_new_simd_vector_with_prefix(), and simdize_simple_statements().

◆ sac_real_current_instruction

instruction sac_real_current_instruction = instruction_undefined

Definition at line 723 of file simdizer.c.

Referenced by make_loadsave_statement(), and simdize_simple_statements().