PIPS
codegen.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 "effects-generic.h"
#include "text-util.h"
#include "effects-simple.h"
#include "sac.h"
#include "patterns.h"
#include "properties.h"
#include <ctype.h>
#include <stdlib.h>
+ Include dependency graph for codegen.c:

Go to the source code of this file.

Macros

#define MAX_PACK   16
 
#define VECTOR_POSTFIX   "vec"
 
#define SAC_ALIGNED_VECTOR_NAME   "pdata"
 

Functions

void init_vector_to_expressions ()
 codegen.c More...
 
void reset_vector_to_expressions ()
 
static entity do_expressions_to_vector (list expressions)
 
static void update_vector_to_expressions (entity e, list exps)
 
static void make_permutations_indexes (list exp_final, list exp_loaded, int *perms)
 This function will create the permutations indexes that will allow the creation of exp_final from exp_loaded with a shuffle. More...
 
static entity try_all_permutations (list expressions, list remainder, list exp_org, statement *shuffle, int *perms)
 
static entity expressions_to_vector (list expressions, statement *shuffle)
 
void invalidate_expressions_in_statement (statement s)
 
bool expression_reference_or_field_p (expression e)
 
bool simd_vector_entity_p (entity e)
 
static bool simd_vector_expression_p (expression e)
 expression is an simd vector if it is a reference array containing VECTOR_POSTFIX in its name More...
 
static enum basic_utype get_basic_from_opcode (opcode oc, int argNum)
 
int get_subwordSize_from_opcode (opcode oc, int argNum)
 
opcode generate_opcode (string name, list types, float cost)
 auto-guess vector size More...
 
static opcode get_optimal_opcode (opcodeClass kind, int argc, list *args)
 Computes the optimal opcode for simdizing 'argc' statements of the 'kind' operation, applied to the 'args' arguments it is a greedy matching, so it supposes the list of args is in the best order for us. More...
 
static expression sreference_offset (reference r)
 computes the offset between an entity and its reference More...
 
static expression offset_of_struct (entity e)
 
static expression distance_between_entity (const entity e0, const entity e1)
 
expression distance_between_expression (const expression exp0, const expression exp1)
 computes the distance betwwen two expression More...
 
static bool consecutive_expression_p (expression e0, int lastOffset, expression e1)
 
static string get_simd_vector_type (list lExp)
 
static string get_vect_name_from_data (int argc, list exps)
 
static void replace_subscript (expression e)
 
static statement make_exec_statement_from_name (string ename, list args)
 
static statement make_exec_statement_from_opcode (opcode oc, list args)
 
static basic get_typedefed_array (const char *type_name, basic b, list dims)
 
bool sac_aligned_entity_p (entity e)
 
static bool sac_aligned_expression_p (expression e)
 
static entity make_new_simd_vector_with_prefix (int itemSize, int nbItems, enum basic_utype basicTag, const char *vname)
 
static entity make_new_simd_vector (int itemSize, int nbItems, enum basic_utype basicTag)
 
static bool loadstore_type_conversion_string (int argc, list args, string *lsType, bool isLoad)
 This function change the "load/store type" to XX_TO_XX if a conversion is needed. More...
 
static statement make_loadsave_statement (int argc, list args, bool isLoad)
 
statement make_shuffle_statement (entity *from, list expressions, int *perms)
 
static statement make_load_statement (int argc, list args)
 
static statement make_save_statement (int argc, list args)
 
static simdstatement make_simd_statement (opcodeClass kind, opcode oc, list *args)
 
simdstatement make_simd_statements (set opkinds, list statements)
 
static statement generate_exec_statement (simdstatement ss)
 
static statement generate_load_statement (simdstatement si, int line)
 
static statement generate_save_statement (simdstatement si)
 
list generate_simd_code (simdstatement ssi, float *simdCost)
 

Variables

static float gSimdCost
 
static hash_table vector_to_expressions = hash_table_undefined
 

Macro Definition Documentation

◆ MAX_PACK

#define MAX_PACK   16

Definition at line 52 of file codegen.c.

◆ SAC_ALIGNED_VECTOR_NAME

#define SAC_ALIGNED_VECTOR_NAME   "pdata"

Definition at line 645 of file codegen.c.

◆ VECTOR_POSTFIX

#define VECTOR_POSTFIX   "vec"

Definition at line 53 of file codegen.c.

Function Documentation

◆ consecutive_expression_p()

static bool consecutive_expression_p ( expression  e0,
int  lastOffset,
expression  e1 
)
static

Definition at line 463 of file codegen.c.

464 {
465  bool result=false;
466  basic b = basic_of_expression(e0);
467  int ref_offset = SizeOfElements(b);
468  free_basic(b);
469  expression distance = distance_between_expression(e0,e1);
470  if( !expression_undefined_p(distance) )
471  {
472  intptr_t idistance;
473  NORMALIZE_EXPRESSION(distance);
474  if((result=expression_integer_value(distance,&idistance)))
475  {
476  pips_debug(3,"distance between %s and %s is %"PRIdPTR"\n",
478  expression_to_string(e1),idistance);
479  result= idistance == ref_offset+ref_offset*lastOffset;
480  }
481  else {
482  pips_debug(3,"distance between %s and %s is too complexd\n",
484  }
485  free_expression(distance);
486  }
487  return result;
488 }
void free_expression(expression p)
Definition: ri.c:853
void free_basic(basic p)
Definition: ri.c:107
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
string expression_to_string(expression e)
Definition: expression.c:77
#define NORMALIZE_EXPRESSION(e)
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
_int SizeOfElements(basic)
This function returns the length in bytes of the Fortran or C type represented by a basic,...
Definition: size.c:297
#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
#define intptr_t
Definition: stdint.in.h:294

References basic_of_expression(), distance_between_expression(), expression_integer_value(), expression_to_string(), expression_undefined_p, free_basic(), free_expression(), intptr_t, NORMALIZE_EXPRESSION, pips_debug, and SizeOfElements().

Referenced by make_loadsave_statement().

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

◆ distance_between_entity()

static expression distance_between_entity ( const entity  e0,
const entity  e1 
)
static

Definition at line 404 of file codegen.c.

405 {
406  if(same_entity_p(e0,e1))
407  return int_to_expression(0);
408  else if( entity_field_p(e0) && entity_field_p(e1) && same_struct_entity_p(e0,e1) )
410  else
411  return expression_undefined;
412 }
#define MINUS_OPERATOR_NAME
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool same_struct_entity_p(const entity e0, const entity e1)
Definition: entity.c:1012
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
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 expression_undefined
Definition: ri.h:1223
static expression offset_of_struct(entity e)
Definition: codegen.c:386

References entity_field_p(), expression_undefined, int_to_expression(), make_op_exp(), MINUS_OPERATOR_NAME, offset_of_struct(), same_entity_p(), and same_struct_entity_p().

Referenced by distance_between_expression().

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

◆ distance_between_expression()

expression distance_between_expression ( const expression  exp0,
const expression  exp1 
)

computes the distance betwwen two expression

Returns
expression_undefined if not comparable, an expression of the distance otherwise

reference with different variables have an infinite distance

Parameters
exp0xp0
exp1xp1

Definition at line 419 of file codegen.c.

420 {
421  bool eval_sizeof = get_bool_property("EVAL_SIZEOF");
422  set_bool_property("EVAL_SIZEOF",true);
425  {
426  reference r0 = expression_reference(exp0),
427  r1 = expression_reference(exp1);
428 
429  /* reference with different variables have an infinite distance */
430  entity e0 = reference_variable(r0),
431  e1 = reference_variable(r1);
432  expression edistance = distance_between_entity(e0,e1);
433  if(!expression_undefined_p(edistance))
434  {
435  basic b = basic_of_reference(r0);
436  expression offset0 = sreference_offset(r0),
437  offset1 = sreference_offset(r1);
438  expression distance = make_op_exp(MINUS_OPERATOR_NAME,offset1,offset0);
440  distance,int_to_expression(SizeOfElements(b)));
441  free_basic(b);
442  result= make_op_exp(PLUS_OPERATOR_NAME,distance,edistance);
443  }
444  }
445  else if (expression_field_p(exp0) && expression_field_p(exp1))
446  {
448  str1 = binary_call_lhs(expression_call(exp1));
449  expression lhs_distance = distance_between_expression(str0,str1);
451  if(!expression_undefined_p(lhs_distance) && !expression_undefined_p(rhs_distance))
452  result = make_op_exp(MINUS_OPERATOR_NAME,lhs_distance,rhs_distance);
453  }
454  set_bool_property("EVAL_SIZEOF",eval_sizeof);
455  //maxima_simplify(&result);
456  simplify_expression(&result);
457  return result;
458 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void set_bool_property(const char *, bool)
#define binary_call_rhs(c)
#define PLUS_OPERATOR_NAME
#define binary_call_lhs(c)
#define MULTIPLY_OPERATOR_NAME
bool simplify_expression(expression *pexp)
use polynomials to simplify an expression in some cases this operation can change the basic of the ex...
Definition: expression.c:3770
bool expression_field_p(expression e)
The expression is of kind "s.a", where "s" is a struct and a "a" field.
Definition: expression.c:491
call expression_call(expression e)
Definition: expression.c:445
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
basic basic_of_reference(reference)
Retrieves the basic of a reference in a newly allocated basic object.
Definition: type.c:1459
#define reference_variable(x)
Definition: ri.h:2326
static expression sreference_offset(reference r)
computes the offset between an entity and its reference
Definition: codegen.c:373
static expression distance_between_entity(const entity e0, const entity e1)
Definition: codegen.c:404

References basic_of_reference(), binary_call_lhs, binary_call_rhs, distance_between_entity(), expression_call(), expression_field_p(), expression_reference(), expression_reference_p(), expression_undefined, expression_undefined_p, free_basic(), get_bool_property(), int_to_expression(), make_op_exp(), MINUS_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, PLUS_OPERATOR_NAME, reference_variable, set_bool_property(), simplify_expression(), SizeOfElements(), and sreference_offset().

Referenced by comparable_statements_on_distance_p(), compare_statements_on_distance_to_origin(), conflict_is_a_real_conflict_p(), consecutive_expression_p(), and do_simdizer_init().

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

◆ do_expressions_to_vector()

static entity do_expressions_to_vector ( list  expressions)
static

Definition at line 71 of file codegen.c.

71  {
72  void * hiter = NULL;
73  entity key;
74  list value;
75  while( (hiter = hash_table_scan(vector_to_expressions,hiter,(void**)&key,(void**)&value) ))
76  {
78  return key;
79  }
80  return entity_undefined;
81 }
bool gen_equals(const list l0, const list l1, gen_eq_func_t equals)
compares two lists using the functor given in parameters returns true if for all n,...
Definition: list.c:192
void * hash_table_scan(hash_table htp, void *hentryp_arg, void **pkey, void **pval)
Definition: hash.c:844
bool(* gen_eq_func_t)(const void *, const void *)
Definition: newgen_types.h:115
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
struct _newgen_struct_value_ * value
Definition: ri.h:455
#define entity_undefined
Definition: ri.h:2761
static hash_table vector_to_expressions
Definition: codegen.c:58
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References entity_undefined, expression_equal_p(), gen_equals(), hash_table_scan(), and vector_to_expressions.

Referenced by expressions_to_vector(), and try_all_permutations().

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

◆ expression_reference_or_field_p()

bool expression_reference_or_field_p ( expression  e)

Definition at line 192 of file codegen.c.

193 {
195 }

References expression_field_p(), and expression_reference_p().

Referenced by do_simdizer_init(), get_optimal_opcode(), and sac_statement_to_expressions_gather().

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

◆ expressions_to_vector()

static entity expressions_to_vector ( list  expressions,
statement shuffle 
)
static

try all possible permutations, well only invert from now on

give up if there are two may permutations to try out

Definition at line 146 of file codegen.c.

147 {
148  /* try all possible permutations, well only invert from now on */
149  entity out = do_expressions_to_vector(expressions);
150  size_t nb_expressions = gen_length(expressions);
151  if(!entity_undefined_p(out)) return out;
152  /* give up if there are two may permutations to try out */
153  else if(nb_expressions <= 8 ) {
154  int perm [1+nb_expressions];
155  perm[nb_expressions]=0;
156  return try_all_permutations(NIL,expressions,expressions,shuffle,perm);
157  }
158  else
159  return entity_undefined;
160 }
static FILE * out
Definition: alias_check.c:128
#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 entity_undefined_p(x)
Definition: ri.h:2762
static entity do_expressions_to_vector(list expressions)
Definition: codegen.c:71
static entity try_all_permutations(list expressions, list remainder, list exp_org, statement *shuffle, int *perms)
Definition: codegen.c:121
void shuffle(int n, float r[n], float r3[n], float r2[n], float a[n], float b[n])
Definition: shuffle.c:9

References do_expressions_to_vector(), entity_undefined, entity_undefined_p, gen_length(), NIL, out, shuffle(), and try_all_permutations().

Referenced by generate_load_statement().

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

◆ generate_exec_statement()

static statement generate_exec_statement ( simdstatement  ss)
static

Definition at line 1249 of file codegen.c.

1250 {
1251  list args = NIL;
1252  int i;
1253 
1254  for(i = 0; i < simdstatement_nbArgs(ss); i++)
1255  {
1256  args = CONS(EXPRESSION,
1258  args);
1259  }
1260 
1262 
1264 }
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
static float gSimdCost
Definition: codegen.c:56
static statement make_exec_statement_from_opcode(opcode oc, list args)
Definition: codegen.c:624
#define simdstatement_nbArgs(x)
Definition: sac_private.h:493
#define simdstatement_opcode(x)
Definition: sac_private.h:491
#define simdstatement_vectors(x)
Definition: sac_private.h:495
#define opcode_cost(x)
Definition: sac_private.h:295

References CONS, entity_to_expression(), EXPRESSION, gSimdCost, make_exec_statement_from_opcode(), NIL, opcode_cost, simdstatement_nbArgs, simdstatement_opcode, and simdstatement_vectors.

Referenced by generate_simd_code().

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

◆ generate_load_statement()

static statement generate_load_statement ( simdstatement  si,
int  line 
)
static

Definition at line 1267 of file codegen.c.

1268 {
1269  list args = NIL;
1271  {
1272  //Build the arguments list
1273  for(int i = opcode_vectorSize(simdstatement_opcode(si))-1;
1274  i >= 0;
1275  i--)
1276  {
1277  args = CONS(EXPRESSION,
1279  args);
1280  }
1283  if(!entity_undefined_p(vector)){
1285  return shuffle;
1286  }
1287  else {
1288  args = CONS(EXPRESSION,
1290  args);
1291 
1292  //Make a load statement
1293  return make_load_statement(
1295  args);
1296  }
1297  }
1298 }
static Value offset
Definition: translation.c:283
#define statement_undefined
Definition: ri.h:2419
static entity expressions_to_vector(list expressions, statement *shuffle)
Definition: codegen.c:146
static statement make_load_statement(int argc, list args)
Definition: codegen.c:1112
#define opcode_vectorSize(x)
Definition: sac_private.h:291
#define simdstatement_arguments(x)
Definition: sac_private.h:497
static int line
FLEX_SCANNER.
Definition: scanner.c:852
test de chernikovaa
struct vector vector
test de chernikovaa

References CONS, entity_to_expression(), entity_undefined_p, EXPRESSION, expressions_to_vector(), line, make_load_statement(), NIL, offset, opcode_vectorSize, shuffle(), simdstatement_arguments, simdstatement_opcode, simdstatement_vectors, and statement_undefined.

Referenced by generate_simd_code().

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

◆ generate_opcode()

opcode generate_opcode ( string  name,
list  types,
float  cost 
)

auto-guess vector size

Parameters
nameame
typesypes
costost

Definition at line 276 of file codegen.c.

277 {
278  intptr_t elem_size=0,vector_size = get_int_property("SAC_SIMD_REGISTER_WIDTH");
279  opcode oc = make_opcode(name,vector_size,types,cost);
280  int n = gen_length(types);
281  for(int i=0; i<n;i++)
282  {
283  int curr = get_subwordSize_from_opcode(oc,i);
284  if(curr > elem_size) elem_size=curr;
285  }
286  opcode_vectorSize(oc)/=elem_size;
287  if( opcode_vectorSize(oc) * elem_size !=get_int_property("SAC_SIMD_REGISTER_WIDTH"))
288  pips_user_warning("SAC_SIMD_REGISTER_WIDTH and description of %s leads "
289  "to partially filled register\n", name);
290  return oc;
291 }
int get_int_property(const string)
opcode make_opcode(string a1, intptr_t a2, list a3, float a4)
Definition: sac_private.c:195
#define pips_user_warning
Definition: misc-local.h:146
int get_subwordSize_from_opcode(opcode oc, int argNum)
Definition: codegen.c:246

References gen_length(), get_int_property(), get_subwordSize_from_opcode(), intptr_t, make_opcode(), opcode_vectorSize, and pips_user_warning.

+ Here is the call graph for this function:

◆ generate_save_statement()

static statement generate_save_statement ( simdstatement  si)
static

Definition at line 1300 of file codegen.c.

1301 {
1302  list args = NIL;
1303  int i;
1305  (simdstatement_nbArgs(si)-1);
1306 
1307  for(i = opcode_vectorSize(simdstatement_opcode(si))-1;
1308  i >= 0;
1309  i--)
1310  {
1311  args = CONS(EXPRESSION,
1312  (
1313  simdstatement_arguments(si)[i + offset]),
1314  args);
1315  }
1316 
1317  args = CONS(EXPRESSION,
1319  args);
1320 
1322 }
static statement make_save_statement(int argc, list args)
Definition: codegen.c:1117

References CONS, entity_to_expression(), EXPRESSION, make_save_statement(), NIL, offset, opcode_vectorSize, simdstatement_arguments, simdstatement_nbArgs, simdstatement_opcode, and simdstatement_vectors.

Referenced by generate_simd_code().

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

◆ generate_simd_code()

list generate_simd_code ( simdstatement  ssi,
float *  simdCost 
)

this is the classical generation process: several load, an exec and a store

the order is reversed, but we use it

Parameters
ssisi
simdCostimdCost

Definition at line 1325 of file codegen.c.

1326 {
1327  gSimdCost = 0;
1328 
1329  pips_debug(3,"generate_simd_code 1\n");
1330 
1331  /* this is the classical generation process:
1332  * several load, an exec and a store
1333  */
1334  //First, the load statement(s)
1335  list loads=NIL;
1336  for(int i = 0; i < simdstatement_nbArgs(ssi)-1; i++)
1337  {
1338  statement s = generate_load_statement(ssi, i);
1339  if (! statement_undefined_p(s))
1340  loads = CONS(STATEMENT, s, loads);
1341  }
1342 
1343  //Then, the exec statement
1345 
1346  //Finally, the save statement (always generated. It is up to
1347  //latter phases (USE-DEF elimination....) to remove it, if needed
1349 
1350  list out = NIL;
1351  out=CONS(STATEMENT,save,CONS(STATEMENT,exec,loads));
1352  *simdCost += gSimdCost;
1353  pips_debug(3,"generate_simd_code 2 that costs %lf\n",gSimdCost);
1354  /* the order is reversed, but we use it */
1355  return out;
1356 }
float_t save[SIZE][SIZE]
Definition: jacobi.c:9
#define statement_undefined_p(x)
Definition: ri.h:2420
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
static statement generate_load_statement(simdstatement si, int line)
Definition: codegen.c:1267
static statement generate_exec_statement(simdstatement ss)
Definition: codegen.c:1249
static statement generate_save_statement(simdstatement si)
Definition: codegen.c:1300

References CONS, generate_exec_statement(), generate_load_statement(), generate_save_statement(), gSimdCost, NIL, out, pips_debug, save, simdstatement_nbArgs, STATEMENT, and statement_undefined_p.

Referenced by simdize_simple_statements_pass2().

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

◆ get_basic_from_opcode()

static enum basic_utype get_basic_from_opcode ( opcode  oc,
int  argNum 
)
static

Definition at line 210 of file codegen.c.

222 {
223  int type = INT(gen_nth(argNum, opcode_argType(oc)));
224 
225  switch(type)
226  {
227  case QI_REF_TOK:
228  case HI_REF_TOK:
229  case SI_REF_TOK:
230  case DI_REF_TOK:
231  return is_basic_int;
232  case SF_REF_TOK:
233  case DF_REF_TOK:
234  return is_basic_float;
235  case SC_REF_TOK:
236  case DC_REF_TOK:
237  return is_basic_complex;
238  default:
239  pips_internal_error("subword size unknown.");
240  }
241 
242  return is_basic_int;
243 }
@ DC_REF_TOK
SC_REF_TOK
Definition: patterns.h:66
@ SC_REF_TOK
DF_REF_TOK
Definition: patterns.h:65
@ HI_REF_TOK
QI_REF_TOK
Definition: patterns.h:60
@ DI_REF_TOK
SI_REF_TOK
Definition: patterns.h:62
@ SI_REF_TOK
HI_REF_TOK
Definition: patterns.h:61
@ QI_REF_TOK
REFERENCE_TOK
Definition: patterns.h:59
@ SF_REF_TOK
DI_REF_TOK
Definition: patterns.h:63
@ DF_REF_TOK
SF_REF_TOK
Definition: patterns.h:64
@ INT
Definition: atomic.c:48
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define pips_internal_error
Definition: misc-local.h:149
@ is_basic_float
Definition: ri.h:572
@ is_basic_int
Definition: ri.h:571
@ is_basic_complex
Definition: ri.h:575
#define opcode_argType(x)
Definition: sac_private.h:293

References expression_syntax, reference_variable, simd_vector_entity_p(), syntax_reference, and syntax_reference_p.

Referenced by get_optimal_opcode(), and make_simd_statement().

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

◆ get_optimal_opcode()

static opcode get_optimal_opcode ( opcodeClass  kind,
int  argc,
list args 
)
static

Computes the optimal opcode for simdizing 'argc' statements of the 'kind' operation, applied to the 'args' arguments it is a greedy matching, so it supposes the list of args is in the best order for us.

Based on the available implementations of the operation, decide how many statements to pack together

& !(bas_pattern == is_basic_float && basic_int_p(bas))

allow the promotion of an int to a float

Definition at line 297 of file codegen.c.

298 {
299  int i;
300  opcode best;
301  /* Based on the available implementations of the operation, decide
302  * how many statements to pack together
303  */
304  best = opcode_undefined;
306  {
307  bool bTagDiff = false;
308  int mwidth = 0;
309 
310  for(i = 0; i < argc; i++)
311  {
312  int count = 0;
313  //int width = mwidth=0;
314  int width = 0;
315  mwidth=0;
316 
317  FOREACH(EXPRESSION,arg,args[i])
318  {
319 
321  {
322  count++;
323  continue;
324  }
325 
326  basic bas = basic_of_expression(arg);
327  enum basic_utype bas_pattern = get_basic_from_opcode(oc, count);
328 
329  if(!basic_overloaded_p(bas) && bas_pattern!=basic_tag(bas)
330  /*&& !(bas_pattern == is_basic_float && basic_int_p(bas))*/) /* allow the promotion of an int
331  to a float */
332 
333  {
334  bTagDiff = true;
335  free_basic(bas);
336  break;
337  }
338 
339  width = SizeOfElements(bas);
340  if(width>mwidth)mwidth=width;
341  free_basic(bas);
342 
343  if(width > get_subwordSize_from_opcode(oc, count))
344  {
345  bTagDiff = true;
346  break;
347  }
348 
349  count++;
350 
351  }
352  }
353 
354  if ( (!bTagDiff) &&
355  (opcode_vectorSize(oc) <= argc) &&
356  (opcode_vectorSize(oc)*mwidth*8 == get_int_property("SAC_SIMD_REGISTER_WIDTH"))) {
357  best = oc;
358  }
359  }
360 
361  return best;
362 }
static int count
Definition: SDG.c:519
#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
basic_utype
Definition: ri.h:570
#define basic_tag(x)
Definition: ri.h:613
#define basic_overloaded_p(x)
Definition: ri.h:623
bool expression_reference_or_field_p(expression e)
Definition: codegen.c:192
static enum basic_utype get_basic_from_opcode(opcode oc, int argNum)
Definition: codegen.c:221
#define opcode_undefined
Definition: sac_private.h:263
#define opcodeClass_opcodes(x)
Definition: sac_private.h:538
#define OPCODE(x)
OPCODE.
Definition: sac_private.h:257

References basic_of_expression(), basic_overloaded_p, basic_tag, count, EXPRESSION, expression_reference_or_field_p(), FOREACH, free_basic(), get_basic_from_opcode(), get_int_property(), get_subwordSize_from_opcode(), OPCODE, opcode_undefined, opcode_vectorSize, opcodeClass_opcodes, and SizeOfElements().

Referenced by make_simd_statements().

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

◆ get_simd_vector_type()

static string get_simd_vector_type ( list  lExp)
static

switch to upper cases...

Definition at line 494 of file codegen.c.

495 {
496  string result = NULL;
497 
498  FOREACH(EXPRESSION, exp,lExp)
499  {
502  exp))));
503 
504  if(type_variable_p(t))
505  {
507  pips_assert("searching in a sac vector",basic_typedef_p(bas));
508 
509  result = strdup(entity_name(basic_typedef(bas)));
510  /* switch to upper cases... */
511  result=strupper(result,result);
512 
513  break;
514 
515  }
516  }
517 
518  return result;
519 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
string strupper(string, const char *)
Definition: string.c:213
#define syntax_reference(x)
Definition: ri.h:2730
#define basic_typedef_p(x)
Definition: ri.h:641
#define type_variable(x)
Definition: ri.h:2949
#define basic_typedef(x)
Definition: ri.h:643
#define entity_name(x)
Definition: ri.h:2790
#define entity_type(x)
Definition: ri.h:2792
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
char * strdup()
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References basic_typedef, basic_typedef_p, entity_name, entity_type, exp, EXPRESSION, expression_syntax, FOREACH, pips_assert, reference_variable, strdup(), strupper(), syntax_reference, type_variable, type_variable_p, and variable_basic.

Referenced by loadstore_type_conversion_string(), and make_loadsave_statement().

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

◆ get_subwordSize_from_opcode()

int get_subwordSize_from_opcode ( opcode  oc,
int  argNum 
)
Parameters
occ
argNumrgNum

Definition at line 246 of file codegen.c.

247 {
248  int type = INT(gen_nth(argNum, opcode_argType(oc)));
249 
250  switch(type)
251  {
252  case QI_REF_TOK:
253  return 8;
254  case HI_REF_TOK:
255  return 16;
256  case SI_REF_TOK:
257  return 32;
258  case DI_REF_TOK:
259  return 64;
260  case SF_REF_TOK:
261  return 32;
262  case DF_REF_TOK:
263  return 64;
264  case SC_REF_TOK:
265  return 64;
266  case DC_REF_TOK:
267  return 128;
268  default:
269  pips_internal_error("subword size unknown.");
270  }
271 
272  return 8;
273 }

References DC_REF_TOK, DF_REF_TOK, DI_REF_TOK, gen_nth(), HI_REF_TOK, INT, opcode_argType, pips_internal_error, QI_REF_TOK, SC_REF_TOK, SF_REF_TOK, and SI_REF_TOK.

Referenced by compute_parallelism_factor(), generate_opcode(), get_optimal_opcode(), and make_simd_statement().

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

◆ get_typedefed_array()

static basic get_typedefed_array ( const char *  type_name,
basic  b,
list  dims 
)
static

Definition at line 629 of file codegen.c.

629  {
630  entity e = FindEntity(TOP_LEVEL_MODULE_NAME,type_name);
631  if(entity_undefined_p(e)) {
635  b,
636  dims,NIL
637  )
638  );
641  }
642  return make_basic_typedef(e);
643 }
basic make_basic_typedef(entity _field_)
Definition: ri.c:185
value make_value_unknown(void)
Definition: ri.c:2847
type make_type_variable(variable _field_)
Definition: ri.c:2715
storage make_storage_rom(void)
Definition: ri.c:2285
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
#define entity_storage(x)
Definition: ri.h:2794
#define entity_initial(x)
Definition: ri.h:2796

References entity_initial, entity_storage, entity_type, entity_undefined_p, FindEntity(), FindOrCreateEntity(), make_basic_typedef(), make_storage_rom(), make_type_variable(), make_value_unknown(), make_variable(), NIL, and TOP_LEVEL_MODULE_NAME.

Referenced by make_loadsave_statement(), and make_new_simd_vector_with_prefix().

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

◆ get_vect_name_from_data()

static string get_vect_name_from_data ( int  argc,
list  exps 
)
static

switch to upper cases...

Definition at line 524 of file codegen.c.

525 {
526  char prefix[5];
527  string result;
528  int itemSize;
529 
530  basic bas = basic_of_expressions(exps,true);
531 
532  prefix[0] = 'v';
533  prefix[1] = '0'+argc;
534 
535  switch(basic_tag(bas))
536  {
537  case is_basic_int:
538  prefix[3] = 'i';
539  break;
540 
541  case is_basic_float:
542  prefix[3] = 'f';
543  break;
544 
545  case is_basic_logical:
546  prefix[3] = 'i';
547  break;
548  case is_basic_complex:
549  prefix[3] = 'c';
550  break;
551 
552  default:
553  free_basic(bas);
554  return strdup("");
555  break;
556  }
557  itemSize=8*SizeOfElements(bas);
558  free_basic(bas);
559 
560  switch(itemSize)
561  {
562  case 8: prefix[2] = 'q'; break;
563  case 16: prefix[2] = 'h'; break;
564  case 32: prefix[2] = 's'; break;
565  case 64: prefix[2] = 'd'; break;
566  default:pips_internal_error("case not handled");
567  }
568 
569  prefix[4] = 0;
570 
571  result = strdup(prefix);
572 
573  /* switch to upper cases... */
574  result=strupper(result,result);
575 
576  return result;
577 }
static const char * prefix
basic basic_of_expressions(list, bool)
Definition: type.c:2040
@ is_basic_logical
Definition: ri.h:573

References basic_of_expressions(), basic_tag, free_basic(), is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, pips_internal_error, prefix, SizeOfElements(), strdup(), and strupper().

Referenced by loadstore_type_conversion_string(), make_loadsave_statement(), and make_shuffle_statement().

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

◆ init_vector_to_expressions()

void init_vector_to_expressions ( void  )

codegen.c

Definition at line 59 of file codegen.c.

60 {
63 }
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_pointer
Definition: newgen_hash.h:32
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50
#define HASH_DEFAULT_SIZE
Definition: newgen_hash.h:26

References HASH_DEFAULT_SIZE, hash_pointer, hash_table_make(), hash_table_undefined_p, pips_assert, and vector_to_expressions.

Referenced by simdize_simple_statements_pass2().

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

◆ invalidate_expressions_in_statement()

void invalidate_expressions_in_statement ( statement  s)

Definition at line 162 of file codegen.c.

163 {
165  void * hiter = NULL;
166  entity key;
167  list value;
168  list purge = NIL;
169  while( (hiter = hash_table_scan(vector_to_expressions,hiter,(void**)&key,(void**)&value) ))
170  {
171  bool invalidate=false;
173  {
175  {
176  FOREACH(EFFECT,eff,effects)
178  {
180  break;
181  }
182  }
183  if(invalidate) break;
184  }
185  if(invalidate) purge=CONS(ENTITY,key,purge);
186  }
187  FOREACH(ENTITY,e,purge)
189  gen_free_list(purge);
190 }
list load_proper_rw_effects_list(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
void gen_full_free_list(list l)
Definition: genClib.c:1023
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
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
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755

References CONS, EFFECT, effect_any_reference, ENTITY, EXPRESSION, expression_reference(), expression_reference_p(), expression_undefined_p, FOREACH, gen_free_list(), gen_full_free_list(), hash_del(), hash_table_scan(), load_proper_rw_effects_list(), NIL, references_may_conflict_p(), and vector_to_expressions.

Referenced by simdize_simple_statements_pass2().

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

◆ loadstore_type_conversion_string()

static bool loadstore_type_conversion_string ( int  argc,
list  args,
string lsType,
bool  isLoad 
)
static

This function change the "load/store type" to XX_TO_XX if a conversion is needed.

It returns true if a change is made, and the pointer *lsType must be freed after being used.

we can handle this situation :p

Definition at line 742 of file codegen.c.

743 {
744  string lsTypeTmp = (char*)local_name(get_simd_vector_type(args));
745  string realVectName = get_vect_name_from_data(argc, CDR(args));
746  if (!same_string_p(realVectName, lsTypeTmp))
747  {
748  entity forged_array = entity_undefined;
749  FOREACH(EXPRESSION,arg,CDR(args)) {
750  if(expression_reference_p(arg)) {
752  entity var = forged_array=reference_variable(r);
753  if(strncmp(entity_user_name(var),
755  sizeof(SAC_ALIGNED_VECTOR_NAME)-1)!=0) {
756  forged_array=entity_undefined;
757  break;
758  }
759  else if(entity_undefined_p(forged_array)) {
760  forged_array = var;
761  }
762  else if(!same_entity_p(forged_array,var)) {
763  forged_array=entity_undefined;
764  break;
765  }
766  }
767  }
768  /* we can handle this situation :p */
769  if(!entity_undefined_p(forged_array)) {
770  expression exp = EXPRESSION(CAR(args));
773  variable v = type_variable(t);
779  );
781  entity_initial(new) = copy_value(entity_initial(forged_array));
782  FOREACH(EXPRESSION,ex,CDR(args))
783  replace_entity(ex,forged_array,new);
784  }
785  else {
786  asprintf(lsType,"%s_TO_%s",
787  isLoad?realVectName:lsTypeTmp,
788  isLoad?lsTypeTmp:realVectName);
789  return true;
790  }
791  }
792  return false;
793 }
value copy_value(value p)
VALUE.
Definition: ri.c:2784
void free_value(value p)
Definition: ri.c:2787
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
void replace_entity(void *s, entity old, entity new)
per variable version of replace_entities.
Definition: replace.c:113
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define asprintf
Definition: misc-local.h:225
#define same_string_p(s1, s2)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
type ultimate_type(type)
Definition: type.c:3466
int basic_type_size(basic)
See also SizeOfElements()
Definition: type.c:1074
int dimension_size(dimension)
this function computes the size of a dimension.
Definition: size.c:491
#define variable_dimensions(x)
Definition: ri.h:3122
static entity make_new_simd_vector_with_prefix(int itemSize, int nbItems, enum basic_utype basicTag, const char *vname)
Definition: codegen.c:663
#define SAC_ALIGNED_VECTOR_NAME
Definition: codegen.c:645
static string get_vect_name_from_data(int argc, list exps)
Definition: codegen.c:524
static string get_simd_vector_type(list lExp)
Definition: codegen.c:494

References asprintf, basic_tag, basic_type_size(), CAR, CDR, copy_value(), DIMENSION, dimension_size(), entity_initial, entity_type, entity_undefined, entity_undefined_p, entity_user_name(), exp, EXPRESSION, expression_reference(), expression_reference_p(), FOREACH, free_value(), get_simd_vector_type(), get_vect_name_from_data(), local_name(), make_new_simd_vector_with_prefix(), reference_variable, replace_entity(), SAC_ALIGNED_VECTOR_NAME, same_entity_p(), same_string_p, type_variable, ultimate_type(), variable_basic, and variable_dimensions.

Referenced by make_loadsave_statement().

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

◆ make_exec_statement_from_name()

static statement make_exec_statement_from_name ( string  ename,
list  args 
)
static

SG: ugly patch to make sure fortran's parameter passing and c's are respected

Definition at line 602 of file codegen.c.

603 {
604  /* SG: ugly patch to make sure fortran's parameter passing and c's are respected */
605  entity exec_function = module_name_to_runtime_entity(ename);
606  if( c_module_p(exec_function) )
607  {
608  string pattern0;
609  asprintf(&pattern0,"%s" SIMD_GENERIC_SUFFIX,get_string_property("ACCEL_LOAD"));
610  string pattern1;
611  asprintf(&pattern1,"%s" SIMD_BROADCAST_SUFFIX,get_string_property("ACCEL_LOAD"));
612  if( strstr(ename,pattern0) )
614  else if( strstr(ename,pattern1) )
616  else {
618  }
619  free(pattern0);
620  free(pattern1);
621  }
623 }
call make_call(entity a1, list a2)
Definition: ri.c:269
char * get_string_property(const char *)
void free(void *)
#define call_to_statement(c)
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_runtime_entity(const char *name)
similar to module_name_to_entity but generates a warning and a stub if the entity is not found
Definition: entity.c:1485
#define SIMD_BROADCAST_SUFFIX
Definition: sac-local.h:55
#define SIMD_GENERIC_SUFFIX
Definition: sac-local.h:53
static void replace_subscript(expression e)
Definition: codegen.c:580

References asprintf, c_module_p(), call_to_statement, CAR, EXPRESSION, FOREACH, free(), get_string_property(), make_call(), module_name_to_runtime_entity(), replace_subscript(), SIMD_BROADCAST_SUFFIX, and SIMD_GENERIC_SUFFIX.

Referenced by make_exec_statement_from_opcode(), and make_loadsave_statement().

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

◆ make_exec_statement_from_opcode()

static statement make_exec_statement_from_opcode ( opcode  oc,
list  args 
)
static

Definition at line 624 of file codegen.c.

625 {
626  return make_exec_statement_from_name( opcode_name(oc) , args );
627 }
static statement make_exec_statement_from_name(string ename, list args)
Definition: codegen.c:602
#define opcode_name(x)
Definition: sac_private.h:289

References make_exec_statement_from_name(), and opcode_name.

Referenced by generate_exec_statement().

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

◆ make_load_statement()

static statement make_load_statement ( int  argc,
list  args 
)
static

Definition at line 1112 of file codegen.c.

1113 {
1114  return make_loadsave_statement(argc, args, true);
1115 }
static statement make_loadsave_statement(int argc, list args, bool isLoad)
Definition: codegen.c:795

References make_loadsave_statement().

Referenced by generate_load_statement().

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

◆ make_loadsave_statement()

static statement make_loadsave_statement ( int  argc,
list  args,
bool  isLoad 
)
static

the function should not be called with an empty arguments list

first, find out if the arguments are:

  • consecutive references to the same array
  • all constant
  • or any other situation

classify according to the second element (first one should be the SIMD vector)

and not real_exp !

now verify the estimation on the first element is correct, and update parameters needed later

eventually, we have four times the same reference loaded. In that case, use a broadcast call

first pass of analysis is done we may have found that we have no consecutive references but a set of scalar if so, we should replace those scalars by appropriate array

rray

no support for array inital value in fortran

manage replacements in the end, otherwise it disturbs the whole process

Now that the analyze is done, we can generate an "optimized" load instruction.

make the new binding available to everybody

Definition at line 795 of file codegen.c.

796 {
797  enum {
798  CONSEC_REFS,
799  MASKED_CONSEC_REFS,
800  CONSTANT,
801  OTHER,
802  BROADCAST
803  } argsType;
804  static char *funcNames[6][2] = { { NULL,NULL},{NULL,NULL},{NULL,NULL},{NULL,NULL}};
805  if(!funcNames[0][0]) {
806  asprintf(&funcNames[0][0],"%s_",get_string_property("ACCEL_STORE"));
807  asprintf(&funcNames[0][1],"%s_",get_string_property("ACCEL_LOAD"));
808  asprintf(&funcNames[1][0],"%s"SIMD_MASKED_SUFFIX"_",get_string_property("ACCEL_STORE"));
809  asprintf(&funcNames[1][1],"%s"SIMD_MASKED_SUFFIX"_",get_string_property("ACCEL_LOAD"));
810  asprintf(&funcNames[2][0],"%s"SIMD_CONSTANT_SUFFIX"_",get_string_property("ACCEL_STORE"));
811  asprintf(&funcNames[2][1],"%s"SIMD_CONSTANT_SUFFIX"_",get_string_property("ACCEL_LOAD"));
812  asprintf(&funcNames[3][0],"%s"SIMD_GENERIC_SUFFIX"_",get_string_property("ACCEL_STORE"));
813  asprintf(&funcNames[3][1],"%s"SIMD_GENERIC_SUFFIX"_",get_string_property("ACCEL_LOAD"));
814  asprintf(&funcNames[4][0],"%s"SIMD_BROADCAST_SUFFIX"_",get_string_property("ACCEL_STORE"));
815  asprintf(&funcNames[4][1],"%s"SIMD_BROADCAST_SUFFIX"_",get_string_property("ACCEL_LOAD"));
816  }
817  int lastOffset = 0;
818  char *functionName;
819 
820  string lsType = (char*)local_name(get_simd_vector_type(args));
821  bool all_scalar = false;
822  bool all_same_aligned_ref = false;
823  bool all_same_ref = true;
824 
825  /* the function should not be called with an empty arguments list */
826  assert((argc > 1) && (args != NIL));
827 
828  /* first, find out if the arguments are:
829  * - consecutive references to the same array
830  * - all constant
831  * - or any other situation
832  */
834 
835  /* classify according to the second element
836  * (first one should be the SIMD vector) */
837  expression exp = EXPRESSION(CAR(CDR(args)));
839  if (expression_constant_p(real_exp))
840  {
841  argsType = CONSTANT;
842  all_scalar = true;
843  }
844  // If e is a reference expression, let's analyse this reference
845  else if (expression_reference_p(real_exp))
846  {
847  argsType = CONSEC_REFS;
848  fstExp = exp;
849  all_scalar = expression_scalar_p(exp); /* and not real_exp ! */
850  all_same_aligned_ref = sac_aligned_expression_p(exp);
851  }
852  else
853  argsType = OTHER;
854 
855  /* now verify the estimation on the first element is correct, and update
856  * parameters needed later */
857  for(list iter = CDR(CDR(args));!ENDP(iter);POP(iter))
858  {
859  expression e = EXPRESSION(CAR(iter));
861  if(expression_undefined_p(fstExp) ||! same_expression_p(fstExp,real_e))
862  all_same_ref=false;
863 
864  if (argsType == OTHER)
865  {
866  all_scalar = all_scalar && expression_scalar_p(e) &&
868  continue;
869  }
870  else if (argsType == CONSTANT)
871  {
872  if (!expression_constant_p(real_e))
873  {
874  argsType = OTHER;
875  all_scalar = all_scalar && expression_scalar_p(e) &&
877  continue;
878  }
879  }
880  else if (argsType == CONSEC_REFS)
881  {
882  // If e is a reference expression, let's analyse this reference
883  // and see if e is consecutive to the previous references
884  if ( (expression_reference_p(real_e)) &&
885  (consecutive_expression_p(fstExp, lastOffset, e)) )
886  {
887  ++lastOffset;
888  all_scalar=false;
889  }
890  else
891  {
892  argsType = OTHER;
893  all_same_aligned_ref = all_same_aligned_ref && same_expression_p(e,fstExp);
894  all_scalar = all_scalar && expression_scalar_p(e) &&
896  continue;
897  }
898  }
899  }
900  /* eventually, we have four times the same reference loaded.
901  * In that case, use a broadcast call */
902  if(all_same_ref && !expression_undefined_p(fstExp) ) {
903  pips_assert("all reference are the same, so it's an 'other' kind\n",argsType==OTHER);
904  argsType = BROADCAST;
905  }
906  /* first pass of analysis is done
907  * we may have found that we have no consecutive references
908  * but a set of scalar
909  * if so, we should replace those scalars by appropriate array
910  */
911  else if(all_scalar)
912  {
914  size_t nbargs=gen_length(CDR(args));
915  basic shared_basic = basic_of_expressions(CDR(args),true);
916  char * tname =strdup(get_vect_name_from_data(nbargs,CDR(args)));
917  tname=strlower(tname,tname);
918  tname[0]='a';/*array*/
919 
923  )
924  );
925  free(tname);
926  AddEntityToCurrentModule(scalar_holder);
927  int index=0;
928  list inits = NIL;
929  list replacements = NIL;
930  for(list iter = CDR(args); !ENDP(iter) ; POP(iter) )
931  {
932  expression e = EXPRESSION(CAR(iter));
934  if(expression_constant_p(e) || formal_p)
935  {
936  /* no support for array inital value in fortran */
938  {
942  make_reference(scalar_holder,CONS(EXPRESSION,int_to_expression(index),NIL))
943  ),
945  }
946  else
947  {
948  inits=CONS(EXPRESSION,copy_expression(e),inits);
949  }
950  if(formal_p)
951  {
952  entity current_scalar = expression_to_entity(e);
953  expression replacement = make_entity_expression(scalar_holder,make_expression_list(int_to_expression(index)));
954  replacements=gen_cons(current_scalar,gen_cons(replacement,replacements));
955  }
956  else
957  {
958  expression replacement = make_entity_expression(scalar_holder,make_expression_list(int_to_expression(index)));
959  *REFCAR(iter) = (gen_chunkp)replacement;
960  }
961  }
962  else
963  {
964  entity current_scalar = expression_to_entity(e);
965  inits=CONS(EXPRESSION,int_to_expression(0),inits);
966  expression replacement = make_entity_expression(scalar_holder,make_expression_list(int_to_expression(index)));
967  replacements=gen_cons(current_scalar,gen_cons(replacement,replacements));
968  }
969  index++;
970  }
971  /* manage replacements in the end, otherwise it disturbs the whole process */
972  replacements=gen_nreverse(replacements);
973  for(list iter = replacements;!ENDP(iter);POP(iter))
974  {
975  expression r = EXPRESSION(CAR(iter));
976  POP(iter);
977  entity e = ENTITY(CAR(iter));
980  }
981  gen_free_list(replacements);
983  {
984  free_value(entity_initial(scalar_holder));
985  entity_initial(scalar_holder) = make_value_expression(
988  gen_nreverse(inits)
989  )
990  )
991  );
992  }
993  else if(!ENDP(new_statements))
995  argsType=CONSEC_REFS;
996  fstExp = EXPRESSION(CAR(CDR(args)));
997 
998  }
999  if(all_same_aligned_ref)
1000  {
1001  argsType=CONSEC_REFS;
1002  }
1003 
1004 
1005 
1006  /* Now that the analyze is done, we can generate an "optimized"
1007  * load instruction.
1008  */
1009  list current_args = NIL;
1010  char* tofree = NULL;
1011  switch(argsType)
1012  {
1013  case CONSEC_REFS:
1014  case MASKED_CONSEC_REFS:
1015  {
1016 
1017  if (loadstore_type_conversion_string(argc, args, &lsType, isLoad))
1018  tofree=lsType;
1019 
1020  if(get_bool_property("SIMD_FORTRAN_MEM_ORGANISATION"))
1021  {
1022  current_args = make_expression_list(
1023  copy_expression(EXPRESSION(CAR(args))),
1024  copy_expression(fstExp));
1025  }
1026  else
1027  {
1028  expression addr = fstExp;
1029  current_args = make_expression_list( copy_expression(EXPRESSION(CAR(args))), copy_expression(addr));
1030  }
1031 
1032  gSimdCost += - argc + 1;
1033 
1034  break;
1035  }
1036 
1037  case CONSTANT:
1038  {
1039  gSimdCost += - argc + 1;
1040 
1041  break;
1042  }
1043 
1044  case OTHER:
1045  {
1046  if (loadstore_type_conversion_string(argc, args, &lsType, isLoad))
1047  tofree=lsType;
1048  current_args=gen_full_copy_list(args);
1049  } break;
1050  case BROADCAST:
1051  current_args = make_expression_list(
1052  copy_expression(EXPRESSION(CAR(args))),
1053  copy_expression(fstExp)
1054  );
1055  default:
1056  break;
1057  }
1058  /* make the new binding available to everybody */
1060 
1061  asprintf(&functionName, "%s%s", funcNames[argsType][isLoad], lsType);
1062  if(tofree) free(tofree);
1063  statement es = make_exec_statement_from_name(functionName, current_args);
1064  free(functionName);
1065  return es;
1066 
1067 }
value make_value_expression(expression _field_)
Definition: ri.c:2850
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
union gen_chunk * gen_chunkp
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void replace_entity_by_expression(void *s, entity ent, expression exp)
replace all reference to entity ent by expression exp in s.
Definition: replace.c:220
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define REFCAR(pc)
Get the adress of the first element of a list.
Definition: newgen_list.h:119
list gen_cons(const void *item, const list next)
Definition: list.c:888
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
statement make_assign_statement(expression, expression)
Definition: statement.c:583
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#define BROADCAST
#define new_statements(p)
Definition: inlining.c:97
#define assert(ex)
Definition: newgen_assert.h:41
string strlower(string, const char *)
Definition: string.c:228
#define make_expression_list(stats...)
#define expression_scalar_p(e)
#define BRACE_INTRINSIC
Definition: ri-util-local.h:85
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression reference_to_expression(reference r)
Definition: expression.c:196
expression make_entity_expression(entity e, cons *inds)
Definition: expression.c:176
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
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
expression call_to_expression(call c)
Build an expression that call a function or procedure.
Definition: expression.c:309
void AddEntityToCurrentModule(entity)
Add a variable entity to the current module declarations.
Definition: variable.c:260
bool formal_parameter_p(entity)
Definition: variable.c:1489
entity make_new_scalar_variable_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
Definition: variable.c:592
#define CONSTANT(x)
CONSTANT.
Definition: ri.h:796
#define SIMD_MASKED_SUFFIX
simd_loop_const_elim.c
Definition: sac-local.h:52
#define SIMD_CONSTANT_SUFFIX
Definition: sac-local.h:54
static basic get_typedefed_array(const char *type_name, basic b, list dims)
Definition: codegen.c:629
static bool sac_aligned_expression_p(expression e)
Definition: codegen.c:651
static bool consecutive_expression_p(expression e0, int lastOffset, expression e1)
Definition: codegen.c:463
static void update_vector_to_expressions(entity e, list exps)
Definition: codegen.c:83
static bool loadstore_type_conversion_string(int argc, list args, string *lsType, bool isLoad)
This function change the "load/store type" to XX_TO_XX if a conversion is needed.
Definition: codegen.c:742
instruction sac_real_current_instruction
Definition: simdizer.c:723

References AddEntityToCurrentModule(), asprintf, assert, basic_of_expressions(), binary_call_rhs, BRACE_INTRINSIC, BROADCAST, call_to_expression(), CAR, CDR, CONS, consecutive_expression_p(), CONSTANT, copy_expression(), DIMENSION, ENDP, ENTITY, entity_initial, entity_intrinsic(), exp, EXPRESSION, expression_call(), expression_constant_p(), expression_field_p(), expression_reference(), expression_reference_p(), expression_scalar_p, expression_to_entity(), expression_undefined, expression_undefined_p, formal_parameter_p(), fortran_module_p(), free(), free_value(), gen_cons(), gen_free_list(), gen_full_copy_list(), gen_length(), gen_nreverse(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), get_simd_vector_type(), get_string_property(), get_typedefed_array(), get_vect_name_from_data(), gSimdCost, insert_statement(), int_to_expression(), loadstore_type_conversion_string(), local_name(), make_assign_statement(), make_block_statement(), make_call(), make_dimension(), make_entity_expression(), make_exec_statement_from_name(), make_expression_list, make_new_scalar_variable_with_prefix(), make_reference(), make_value_expression(), new_statements, NIL, pips_assert, POP, REFCAR, reference_to_expression(), reference_variable, replace_entity_by_expression(), sac_aligned_expression_p(), SAC_ALIGNED_VECTOR_NAME, sac_real_current_instruction, same_expression_p(), SIMD_BROADCAST_SUFFIX, SIMD_CONSTANT_SUFFIX, SIMD_GENERIC_SUFFIX, SIMD_MASKED_SUFFIX, STATEMENT, strdup(), strlower(), and update_vector_to_expressions().

Referenced by make_load_statement(), and make_save_statement().

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

◆ make_new_simd_vector()

static entity make_new_simd_vector ( int  itemSize,
int  nbItems,
enum basic_utype  basicTag 
)
static

Definition at line 734 of file codegen.c.

735 {
736  return make_new_simd_vector_with_prefix(itemSize, nbItems, basicTag, VECTOR_POSTFIX);
737 }
#define VECTOR_POSTFIX
Definition: codegen.c:53

References make_new_simd_vector_with_prefix(), and VECTOR_POSTFIX.

Referenced by make_simd_statement().

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

◆ make_new_simd_vector_with_prefix()

static entity make_new_simd_vector_with_prefix ( int  itemSize,
int  nbItems,
enum basic_utype  basicTag,
const char *  vname 
)
static

build the variable prefix code, which is in fact also the type

Definition at line 663 of file codegen.c.

664 {
665  //extern list integer_entities, real_entities, double_entities;
666 
667  basic simdVector;
668 
669  entity new_ent, mod_ent;
670  char prefix[6]={ same_string_p(vname,VECTOR_POSTFIX)?'v':'a', '0', '\0', '\0', '\0', '\0' },
671  num[1 + sizeof(VECTOR_POSTFIX) + 3 ],
672  name[sizeof(prefix)+sizeof(num)+1];
673  static int number = 0;
674 
676 
677  /* build the variable prefix code, which is in fact also the type */
678  prefix[1] += nbItems;
679  switch(itemSize)
680  {
681  case 8: prefix[2] = 'q'; break;
682  case 16: prefix[2] = 'h'; break;
683  case 32: prefix[2] = 's'; break;
684  case 64: prefix[2] = 'd'; break;
685  }
686 
687 
688  switch(basicTag)
689  {
690  case is_basic_int:
691  simdVector = make_basic_int(itemSize/8);
692  prefix[3] = 'i';
693  break;
694 
695  case is_basic_float:
696  simdVector = make_basic_float(itemSize/8);
697  prefix[3] = 'f';
698  break;
699 
700  default:
701  simdVector = make_basic_int(itemSize/8);
702  prefix[3] = 'i';
703  break;
704  }
705 
706  pips_assert("buffer doesnot overflow",number<10000);
707  sprintf(name, "%s%u", vname,number++);
708  list lis=CONS(DIMENSION,
710  int_to_expression(nbItems-1),
711  NIL),
712  NIL);
713 
714  basic typedefedSimdVector = get_typedefed_array(prefix,simdVector,lis);
715 
716  new_ent = make_new_scalar_variable_with_prefix(name, mod_ent , typedefedSimdVector);
717 
718 #if 0
719  string type_name = strdup(concatenate(prefix,"_struct", (char *) NULL));
720  entity str_type = FindOrCreateEntity(entity_local_name(mod_ent), type_name);
721  entity_type(str_type) =make_type_variable(make_variable(simdVector,NIL,NIL));
722 
724  entity_type(str_dec) = entity_type(str_type);
725 #endif
726 
727  if( same_string_p(vname, VECTOR_POSTFIX))
729  else
730  AddEntityToCurrentModule(new_ent);
731 
732  return new_ent;
733 }
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
basic make_basic_float(intptr_t _field_)
Definition: ri.c:161
static entity mod_ent
static int num
Definition: bourdoncle.c:137
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
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
void AddLocalEntityToDeclarations(entity, entity, statement)
Add the variable entity e to the list of variables of the function module.
Definition: variable.c:233
statement sac_current_block
Definition: simdizer.c:722

References AddEntityToCurrentModule(), AddLocalEntityToDeclarations(), concatenate(), CONS, DIMENSION, entity_local_name(), entity_type, FindOrCreateEntity(), get_current_module_entity(), get_typedefed_array(), int_to_expression(), is_basic_float, is_basic_int, make_basic_float(), make_basic_int(), make_dimension(), make_new_scalar_variable_with_prefix(), make_type_variable(), make_variable(), mod_ent, NIL, num, pips_assert, prefix, sac_current_block, same_string_p, strdup(), and VECTOR_POSTFIX.

Referenced by loadstore_type_conversion_string(), and make_new_simd_vector().

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

◆ make_permutations_indexes()

static void make_permutations_indexes ( list  exp_final,
list  exp_loaded,
int perms 
)
static

This function will create the permutations indexes that will allow the creation of exp_final from exp_loaded with a shuffle.

Definition at line 105 of file codegen.c.

106 {
107  int index_loaded = 0;
108  FOREACH(EXPRESSION,ef,exp_loaded) {
109  int index_perm = 0;
110  FOREACH(EXPRESSION,el,exp_final) {
111  if (expression_equal_p(ef,el)) {
112  perms[index_loaded] = index_perm;
113  break;
114  }
115  index_perm++;
116  }
117  index_loaded++;
118  }
119 }

References EXPRESSION, expression_equal_p(), and FOREACH.

Referenced by try_all_permutations().

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

◆ make_save_statement()

static statement make_save_statement ( int  argc,
list  args 
)
static

Definition at line 1117 of file codegen.c.

1118 {
1119  return make_loadsave_statement(argc, args, false);
1120 }

References make_loadsave_statement().

Referenced by generate_save_statement().

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

◆ make_shuffle_statement()

statement make_shuffle_statement ( entity from,
list  expressions,
int perms 
)

If the permutation indexes are equivalent to an invertion, generate an SIMD_INVERT function (useful for some MIS).

Parameters
fromrom
expressionsxpressions
permserms

Definition at line 1068 of file codegen.c.

1068  {
1069  list shuffle=NIL;
1070  FOREACH(EXPRESSION,_,expressions)
1073  entity out = make_entity_copy(*from);
1075  string sshuffle;
1076  statement outs;
1077  /* If the permutation indexes are equivalent to an invertion,
1078  * generate an SIMD_INVERT function (useful for some MIS). */
1079  if (perms[0] == 4 && perms[1] == 3 && perms[2] == 2 && perms[3] == 1) {
1080  asprintf(&sshuffle,"SIMD_INVERT_%s",
1081  get_vect_name_from_data(gen_length(expressions),expressions));
1082  list args = NIL;
1083  args = CONS(EXPRESSION,entity_to_expression(*from),args);
1084  args = CONS(EXPRESSION,entity_to_expression(out),args);
1085 
1086  outs = instruction_to_statement(
1088  make_call(
1090  args)
1091  )
1092  );
1093  }
1094  else {
1095  asprintf(&sshuffle,"SIMD_SHUFFLE_%s",
1096  get_vect_name_from_data(gen_length(expressions),expressions));
1097 
1098  outs = instruction_to_statement(
1100  make_call(
1104  )
1105  );
1106  }
1107  *from=out;
1108  return outs;
1109 }
instruction make_instruction_call(call _field_)
Definition: ri.c:1184
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
#define _
A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
Definition: stddef.in.h:59
entity make_entity_copy(entity e)
Create a copy of an entity, with (almost) identical type, storage and initial value if move_initializ...
Definition: entity.c:2433

References _, AddEntityToCurrentModule(), asprintf, CONS, entity_to_expression(), EXPRESSION, FOREACH, gen_length(), gen_nreverse(), get_vect_name_from_data(), instruction_to_statement(), int_to_expression(), make_call(), make_entity_copy(), make_instruction_call(), module_name_to_runtime_entity(), NIL, out, and shuffle().

Referenced by try_all_permutations().

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

◆ make_simd_statement()

static simdstatement make_simd_statement ( opcodeClass  kind,
opcode  oc,
list args 
)
static

find out the number of arguments needed

allocate memory

create the simd vector entities

Fill the matrix of arguments

Definition at line 1128 of file codegen.c.

1129 {
1130  simdstatement ss;
1131  size_t nbargs;
1132 
1133  /* find out the number of arguments needed */
1134  nbargs = opcodeClass_nbArgs(kind);
1135 
1136  /* allocate memory */
1137  ss = make_simdstatement(oc,
1138  nbargs,
1139  (entity *)malloc(sizeof(entity)*nbargs),
1140  (expression*)malloc(sizeof(expression) * nbargs * opcode_vectorSize(oc)));
1141 
1142 
1143  /* create the simd vector entities */
1145  int j=nbargs-1;
1146  pips_assert("nb parameters match nb dummy parameters",nbargs==gen_length(*args));
1147  FOREACH(EXPRESSION,exp,*args)
1148  {
1149  enum basic_utype basicTag = get_basic_from_opcode(oc, nbargs-1-j);
1151  register void * hiter = NULL;
1152  expression key;
1153  entity value;
1154  while ((hiter = hash_table_scan(expression_to_entity, hiter, (void**)&key, (void**)&value))) {
1155  if( expression_equal_p(exp,key ) ) {
1156  simdstatement_vectors(ss)[j] = value;
1157  break;
1158  }
1159  }
1160 
1162  {
1163  simdstatement_vectors(ss)[j] =
1165  opcode_vectorSize(oc),
1166  basicTag);
1168  }
1169  j--;
1170  }
1172 
1173  /* Fill the matrix of arguments */
1174  for(int j=0; j<opcode_vectorSize(oc); j++)
1175  {
1176 
1177  list l = args[j];
1178 
1179  for(int i=nbargs-1; i>=0; i--)
1180  {
1181  expression e = EXPRESSION(CAR(l));
1182 
1183  //Store it in the argument's matrix
1184  simdstatement_arguments(ss)[j + opcode_vectorSize(oc) * i] = e;
1185 
1186  l = CDR(l);
1187  }
1188  }
1189 
1190  return ss;
1191 }
simdstatement make_simdstatement(opcode a1, intptr_t a2, entity *a3, expression *a4)
Definition: sac_private.c:418
void * malloc(YYSIZE_T)
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_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
static entity make_new_simd_vector(int itemSize, int nbItems, enum basic_utype basicTag)
Definition: codegen.c:734
#define opcodeClass_nbArgs(x)
Definition: sac_private.h:536

References CAR, CDR, entity_undefined, entity_undefined_p, exp, EXPRESSION, expression_equal_p(), expression_to_entity(), FOREACH, gen_length(), get_basic_from_opcode(), get_subwordSize_from_opcode(), HASH_DEFAULT_SIZE, hash_pointer, hash_put(), hash_table_free(), hash_table_make(), hash_table_scan(), make_new_simd_vector(), make_simdstatement(), malloc(), opcode_vectorSize, opcodeClass_nbArgs, pips_assert, simdstatement_arguments, and simdstatement_vectors.

Referenced by make_simd_statements().

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

◆ make_simd_statements()

simdstatement make_simd_statements ( set  opkinds,
list  statements 
)

there should be a better order than this

get the variables

compute the opcode to use

update the pointer to the next statement to be processed

generate the statement information

Parameters
opkindspkinds
statementstatements

Definition at line 1193 of file codegen.c.

1194 {
1195  list args[MAX_PACK];
1196  /* there should be a better order than this */
1197  list first = statements;
1198  list last = gen_last(first);
1199  list kinds = set_to_list(opkinds);
1200 
1201  pips_debug(3,"make_simd_statements 1\n");
1202 
1203  if (first == last)
1204  return simdstatement_undefined;
1205 
1206  pips_debug(3,"make_simd_statements 2\n");
1207 
1208  list i = first;
1210 
1211  opcodeClass type = OPCODECLASS(CAR(kinds));
1212  {
1213  int index;
1214  opcode oc;
1215  list j;
1216 
1217  /* get the variables */
1218  for( index = 0, j = i;
1219  (index < MAX_PACK) && (j != CDR(last));
1220  index++, j = CDR(j) )
1221  {
1223  args[index] = match_args(m);
1224  }
1225 
1226  /* compute the opcode to use */
1227  oc = get_optimal_opcode(type, index, args);
1228 
1229  if (!opcode_undefined_p(oc))
1230  {
1231  /* update the pointer to the next statement to be processed */
1232  for(index = 0;
1233  (index<opcode_vectorSize(oc)) && (i!=CDR(last));
1234  index++)
1235  {
1236  i = CDR(i);
1237  }
1238 
1239  /* generate the statement information */
1240  pips_debug(3,"make_simd_statements : simd\n");
1241  instr = make_simd_statement(type, oc, args);
1242  }
1243  }
1244 
1245  pips_debug(3,"make_simd_statements 3\n");
1246  return instr;
1247 }
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
list set_to_list(const set)
create a list from a set the set is not freed
Definition: set.c:436
static simdstatement make_simd_statement(opcodeClass kind, opcode oc, list *args)
Definition: codegen.c:1128
static opcode get_optimal_opcode(opcodeClass kind, int argc, list *args)
Computes the optimal opcode for simdizing 'argc' statements of the 'kind' operation,...
Definition: codegen.c:297
#define MAX_PACK
Definition: codegen.c:52
match get_statement_match_of_kind(statement, opcodeClass)
simdizer.c
Definition: simdizer.c:101
#define simdstatement_undefined
Definition: sac_private.h:465
#define match_args(x)
Definition: sac_private.h:253
#define opcode_undefined_p(x)
Definition: sac_private.h:264
#define OPCODECLASS(x)
OPCODECLASS.
Definition: sac_private.h:501

References CAR, CDR, gen_last(), get_optimal_opcode(), get_statement_match_of_kind(), make_simd_statement(), match_args, MAX_PACK, opcode_undefined_p, opcode_vectorSize, OPCODECLASS, pips_debug, set_to_list(), simdstatement_undefined, and STATEMENT.

Referenced by simdize_simple_statements_pass2().

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

◆ offset_of_struct()

static expression offset_of_struct ( entity  e)
static

Definition at line 386 of file codegen.c.

387 {
388 
389  entity parent_struct = entity_field_to_entity_struct(e);
390  list fields = type_struct(entity_type(parent_struct));
392  FOREACH(ENTITY,field,fields)
393  if(same_entity_p(field,e)) break;
394  else {
399  );
400  }
401  return offset;
402 }
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
syntax make_syntax_sizeofexpression(sizeofexpression _field_)
Definition: ri.c:2506
type copy_type(type p)
TYPE.
Definition: ri.c:2655
sizeofexpression make_sizeofexpression_type(type _field_)
Definition: ri.c:2177
entity entity_field_to_entity_struct(entity f)
Definition: entity.c:905
#define type_struct(x)
Definition: ri.h:2964
#define normalized_undefined
Definition: ri.h:1745

References copy_expression(), copy_type(), ENTITY, entity_field_to_entity_struct(), entity_type, FOREACH, int_to_expression(), make_expression(), make_op_exp(), make_sizeofexpression_type(), make_syntax_sizeofexpression(), normalized_undefined, offset, PLUS_OPERATOR_NAME, same_entity_p(), and type_struct.

Referenced by distance_between_entity().

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

◆ replace_subscript()

static void replace_subscript ( expression  e)
static

Definition at line 580 of file codegen.c.

581 {
583  {
585  {
586  syntax syn = expression_syntax(e);
589  make_call(
593  )
594  )
595  )
596  );
597  }
598  }
599 
600 }
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
#define ADDRESS_OF_OPERATOR_NAME
bool expression_call_p(expression e)
Definition: expression.c:415
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 syntax_undefined
Definition: ri.h:2676
static bool simd_vector_expression_p(expression e)
expression is an simd vector if it is a reference array containing VECTOR_POSTFIX in its name
Definition: codegen.c:210

References ADDRESS_OF_OPERATOR_NAME, entity_intrinsic(), expression_call_p(), expression_constant_p(), expression_field_p(), expression_syntax, make_call(), make_expression(), make_expression_list, make_syntax_call(), normalized_undefined, simd_vector_expression_p(), syntax_undefined, and update_expression_syntax().

Referenced by make_exec_statement_from_name().

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

◆ reset_vector_to_expressions()

void reset_vector_to_expressions ( void  )

Definition at line 64 of file codegen.c.

65 {
69 }
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49

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

Referenced by simdize_simple_statements_pass2().

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

◆ sac_aligned_entity_p()

bool sac_aligned_entity_p ( entity  e)

Definition at line 646 of file codegen.c.

647 {
649 }
#define same_stringn_p(a, b, c)
Definition: misc-local.h:199

References entity_user_name(), SAC_ALIGNED_VECTOR_NAME, and same_stringn_p.

Referenced by sac_aligned_expression_p(), and sac_commenter().

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

◆ sac_aligned_expression_p()

static bool sac_aligned_expression_p ( expression  e)
static

Definition at line 651 of file codegen.c.

652 {
654  {
657  }
658  return false;
659 }
bool sac_aligned_entity_p(entity e)
Definition: codegen.c:646

References expression_reference(), expression_reference_p(), reference_variable, and sac_aligned_entity_p().

Referenced by make_loadsave_statement().

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

◆ simd_vector_entity_p()

bool simd_vector_entity_p ( entity  e)

Definition at line 197 of file codegen.c.

198 {
199  return
202  && !entity_scalar_p(e);
203  ;
204 }
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113

References entity_scalar_p(), entity_type, entity_user_name(), type_variable_p, and VECTOR_POSTFIX.

Referenced by get_basic_from_opcode(), and sac_commenter().

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

◆ simd_vector_expression_p()

static bool simd_vector_expression_p ( expression  e)
static

expression is an simd vector if it is a reference array containing VECTOR_POSTFIX in its name

Definition at line 210 of file codegen.c.

211 {
212  syntax s = expression_syntax(e);
214 }
#define syntax_reference_p(x)
Definition: ri.h:2728
bool simd_vector_entity_p(entity e)
Definition: codegen.c:197

Referenced by replace_subscript().

+ Here is the caller graph for this function:

◆ sreference_offset()

static expression sreference_offset ( reference  r)
static

computes the offset between an entity and its reference

Parameters
r
Returns
an expression of the offset, in octets

Definition at line 373 of file codegen.c.

374 {
375  if(get_bool_property("SIMD_FORTRAN_MEM_ORGANISATION")) {
376  reference cr = copy_reference(r);
379  free_reference(cr);
380  return out;
381  }
382  else
383  return reference_offset(r);
384 }
void free_reference(reference p)
Definition: ri.c:2050
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
expression reference_offset(reference ref)
computes the offset of a C reference with its origin
Definition: expression.c:3807
#define reference_indices(x)
Definition: ri.h:2328

References copy_reference(), free_reference(), gen_nreverse(), get_bool_property(), out, reference_indices, and reference_offset().

Referenced by distance_between_expression().

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

◆ try_all_permutations()

static entity try_all_permutations ( list  expressions,
list  remainder,
list  exp_org,
statement shuffle,
int perms 
)
static

Definition at line 121 of file codegen.c.

122 {
124  list tmp = gen_copy_seq(expressions);
125  list rtmp = gen_copy_seq(remainder);
126  gen_remove_once(&rtmp,exp);
127  list newexp = CONS(EXPRESSION,exp,tmp);
128  entity out = try_all_permutations(newexp,rtmp,exp_org,shuffle,perms);
129  gen_free_list(newexp);
130  gen_free_list(rtmp);
131  if(!entity_undefined_p(out))
132  return out;
133  }
134  if(ENDP(remainder)) {
135  entity out = do_expressions_to_vector(expressions);
136  if(!entity_undefined_p(out))
137  {
138  make_permutations_indexes(exp_org, expressions, perms);
139  *shuffle=make_shuffle_statement(&out,expressions,perms);
140  }
141  return out;
142  }
143  return entity_undefined;
144 }
void gen_remove_once(list *pl, const void *o)
Remove the first occurence of o in list pl:
Definition: list.c:691
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
statement make_shuffle_statement(entity *from, list expressions, int *perms)
Definition: codegen.c:1068
static void make_permutations_indexes(list exp_final, list exp_loaded, int *perms)
This function will create the permutations indexes that will allow the creation of exp_final from exp...
Definition: codegen.c:105
#define remainder
Definition: vasnprintf.c:209

References CONS, do_expressions_to_vector(), ENDP, entity_undefined, entity_undefined_p, exp, EXPRESSION, FOREACH, gen_copy_seq(), gen_free_list(), gen_remove_once(), make_permutations_indexes(), make_shuffle_statement(), out, remainder, and shuffle().

Referenced by expressions_to_vector().

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

◆ update_vector_to_expressions()

static void update_vector_to_expressions ( entity  e,
list  exps 
)
static

create the enw vector

remove the old ones

invalidate

Definition at line 83 of file codegen.c.

84 {
85  pips_assert("entity is ok",entity_consistent_p(e));
86  /* create the enw vector */
87  FOREACH(EXPRESSION,exp,exps) pips_assert("expressions are ok",expression_consistent_p(exp));
88  /* remove the old ones */
90  FOREACH(EXPRESSION,exp,exps) {
91  for(list iter=expressions;!ENDP(iter);POP(iter)) {
92  expression * piter = (expression*) REFCAR(iter);
93  if(expression_equal_p(exp,*piter)) /* invalidate */ {
94  free_expression(*piter);
95  *piter=expression_undefined;
96  }
97  }
98  }
99  }
101 }
bool expression_consistent_p(expression p)
Definition: ri.c:859
bool entity_consistent_p(entity p)
Definition: ri.c:2530
#define hash_put_or_update(h, k, v)
Definition: newgen_hash.h:80
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71

References ENDP, entity_consistent_p(), exp, EXPRESSION, expression_consistent_p(), expression_equal_p(), expression_undefined, FOREACH, free_expression(), gen_full_copy_list(), HASH_FOREACH, hash_put_or_update, pips_assert, POP, REFCAR, and vector_to_expressions.

Referenced by make_loadsave_statement().

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

Variable Documentation

◆ gSimdCost

float gSimdCost
static

Definition at line 56 of file codegen.c.

Referenced by generate_exec_statement(), generate_simd_code(), and make_loadsave_statement().

◆ vector_to_expressions