PIPS
unroll.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 "effects-util.h"
#include "pipsdbm.h"
#include "effects-generic.h"
#include "transformations.h"
#include "control.h"
#include "sac.h"
#include "hyperplane.h"
#include "properties.h"
#include <limits.h>
+ Include dependency graph for unroll.c:

Go to the source code of this file.

Data Structures

struct  MinMaxVar
 

Functions

static bool should_unroll_p (instruction i)
 
static void compute_variable_size (statement s, MinMaxVar *varwidth)
 
static void simd_loop_unroll (statement loop_statement, intptr_t rate)
 
static int simple_simd_unroll_rate (loop l)
 
static bool simple_simd_unroll_loop_filter (statement s)
 
static void compute_parallelism_factor (statement s, MinMaxVar *factor)
 
static bool full_simd_unroll_loop_filter (statement s)
 
static void simd_unroll_as_needed (statement module_stmt)
 
bool loop_auto_unroll (const char *mod_name)
 unroll.c More...
 
bool simdizer_auto_unroll (char *mod_name)
 
static void gather_local_indices (reference r, set s)
 
static void keep_loop_indices (statement s, list *L)
 
static list do_simdizer_auto_tile_int_to_list (int maxdepth, int path, loop l)
 
static statement do_simdizer_auto_tile_generate_all_tests (statement root, int maxdepth, int path, expression *tests)
 
static statement simdizer_auto_tile_generate_all_tests (statement root, int maxdepth, expression tests[1+maxdepth])
 
static void stmt_rm_labels (statement s)
 
bool simdizer_auto_tile (const char *module_name)
 

Function Documentation

◆ compute_parallelism_factor()

static void compute_parallelism_factor ( statement  s,
MinMaxVar factor 
)
static

see if the statement can be SIMDized

and if so, to what extent it may benefit from unrolling

Definition at line 197 of file unroll.c.

198 {
200 
201  /* see if the statement can be SIMDized */
203  {
204  /* and if so, to what extent it may benefit from unrolling */
206  {
207  if (get_subwordSize_from_opcode(o, 0) >= varwidth) //opcode may be used
208  {
209  if (opcode_vectorSize(o) > factor->max)
210  factor->max = opcode_vectorSize(o);
211  if (opcode_vectorSize(o) < factor->min)
212  factor->min = opcode_vectorSize(o);
213  }
214  }
215  }
216 }
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define statement_instruction(x)
Definition: ri.h:2458
int get_subwordSize_from_opcode(opcode oc, int argNum)
Definition: codegen.c:246
int effective_variables_width(instruction)
varwidth.c
Definition: varwidth.c:85
list match_statement(statement)
return a list of matching statements
Definition: treematch.c:237
#define opcode_vectorSize(x)
Definition: sac_private.h:291
#define MATCH(x)
MATCH.
Definition: sac_private.h:221
#define match_type(x)
Definition: sac_private.h:251
#define opcodeClass_opcodes(x)
Definition: sac_private.h:538
#define OPCODE(x)
OPCODE.
Definition: sac_private.h:257
int max
Definition: unroll.c:87
int min
Definition: unroll.c:86

References effective_variables_width(), FOREACH, get_subwordSize_from_opcode(), MATCH, match_statement(), match_type, MinMaxVar::max, MinMaxVar::min, OPCODE, opcode_vectorSize, opcodeClass_opcodes, and statement_instruction.

Referenced by full_simd_unroll_loop_filter().

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

◆ compute_variable_size()

static void compute_variable_size ( statement  s,
MinMaxVar varwidth 
)
static

Definition at line 90 of file unroll.c.

91 {
93 
94  if (width > varwidth->max)
95  varwidth->max = width;
96 
97  if (width < varwidth->min)
98  varwidth->min = width;
99 }
#define min(a, b)

References effective_variables_width(), MinMaxVar::max, min, MinMaxVar::min, and statement_instruction.

Referenced by simple_simd_unroll_rate().

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

◆ do_simdizer_auto_tile_generate_all_tests()

static statement do_simdizer_auto_tile_generate_all_tests ( statement  root,
int  maxdepth,
int  path,
expression tests 
)
static

duplicate effects for the copied statement

Definition at line 365 of file unroll.c.

365  {
366  if(expression_undefined_p(*tests)) {
368  statement cp = clone_statement(root, cc);
369  /* duplicate effects for the copied statement */
373  statement siter = cp;
374  FOREACH(LOOP,li,l)
375  siter = loop_body(statement_loop(siter));
376  free_clone_context(cc);
377  return cp;
378  }
379  else {
380  int npath = path << 1 ;
381  return do_simdizer_auto_tile_generate_all_tests(root, maxdepth, npath+1, tests+1);
382  /*
383  int npath = path << 1 ;
384  statement trueb = do_simdizer_auto_tile_generate_all_tests(root, maxdepth, npath+1, tests+1);
385  statement falseb = do_simdizer_auto_tile_generate_all_tests(root, maxdepth, npath, tests+1);
386  return
387  instruction_to_statement(
388  make_instruction_test(
389  make_test(
390  *tests,
391  trueb,
392  falseb
393  )
394  )
395  );
396  */
397  }
398 }
clone_context make_clone_context(entity a1, entity a2, list a3, statement a4)
Definition: cloning.c:52
void free_clone_context(clone_context p)
Definition: cloning.c:19
effects copy_effects(effects p)
EFFECTS.
Definition: effects.c:532
statement clone_statement(statement s, clone_context cc)
clone_statement.c
effects load_cumulated_rw_effects(statement)
void store_cumulated_rw_effects(statement, effects)
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
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
void do_symbolic_tiling(statement, list)
symbolic_tiling.c
#define loop_body(x)
Definition: ri.h:1644
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define expression_undefined_p(x)
Definition: ri.h:1224
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static list do_simdizer_auto_tile_int_to_list(int maxdepth, int path, loop l)
Definition: unroll.c:354
static statement do_simdizer_auto_tile_generate_all_tests(statement root, int maxdepth, int path, expression *tests)
Definition: unroll.c:365

References clone_statement(), copy_effects(), cp, do_simdizer_auto_tile_int_to_list(), do_symbolic_tiling(), expression_undefined_p, FOREACH, free_clone_context(), get_current_module_entity(), get_current_module_statement(), load_cumulated_rw_effects(), LOOP, loop_body, make_clone_context(), NIL, statement_loop(), and store_cumulated_rw_effects().

Referenced by simdizer_auto_tile_generate_all_tests().

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

◆ do_simdizer_auto_tile_int_to_list()

static list do_simdizer_auto_tile_int_to_list ( int  maxdepth,
int  path,
loop  l 
)
static

Definition at line 354 of file unroll.c.

354  {
355  list out = NIL;
356  int rw = simple_simd_unroll_rate(l);
357  while(maxdepth--) {
358  int a = 1;
359  if(path & 1) a=rw;
361  }
362  return out;
363 }
static FILE * out
Definition: alias_check.c:128
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
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
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
static int simple_simd_unroll_rate(loop l)
Definition: unroll.c:141

References CONS, EXPRESSION, int_to_expression(), NIL, out, and simple_simd_unroll_rate().

Referenced by do_simdizer_auto_tile_generate_all_tests().

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

◆ full_simd_unroll_loop_filter()

static bool full_simd_unroll_loop_filter ( statement  s)
static

If this is not a loop, keep on recursing

Can only simdize certain loops

can't do anything

look at each of the statements in the body

Decide between min and max unroll factor, and unroll

Do not recursively analyse the loop

Definition at line 218 of file unroll.c.

219 {
220  MinMaxVar factor;
221  instruction i;
222  loop l;
223  instruction iBody;
224 
225  /* If this is not a loop, keep on recursing */
226  i = statement_instruction(s);
227  if (!instruction_loop_p(i))
228  return true;
229  l = instruction_loop(i);
230 
231  /* Can only simdize certain loops */
232  iBody = statement_instruction(loop_body(l));
233  if (!should_unroll_p(iBody))
234  return true; /* can't do anything */
235 
236  /* look at each of the statements in the body */
237  factor.min = INT_MAX;
238  factor.max = 1;
240  factor.min = factor.min > factor.max ? factor.max : factor.min;
241 
242 
243  /* Decide between min and max unroll factor, and unroll */
244  int unroll_rate = get_bool_property("SIMDIZER_AUTO_UNROLL_MINIMIZE_UNROLL") ? factor.min : factor.max;
245  simd_loop_unroll(s, unroll_rate);
246 
247  /* Do not recursively analyse the loop */
248  return false;
249 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#define instruction_loop_p(x)
Definition: ri.h:1518
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
static void compute_parallelism_factor(statement s, MinMaxVar *factor)
Definition: unroll.c:197
static void simd_loop_unroll(statement loop_statement, intptr_t rate)
Definition: unroll.c:101
static bool should_unroll_p(instruction i)
Definition: unroll.c:53

References compute_parallelism_factor(), gen_context_recurse, gen_true2(), get_bool_property(), instruction_loop, instruction_loop_p, loop_body, MinMaxVar::max, MinMaxVar::min, should_unroll_p(), simd_loop_unroll(), statement_domain, and statement_instruction.

Referenced by simd_unroll_as_needed().

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

◆ gather_local_indices()

static void gather_local_indices ( reference  r,
set  s 
)
static

Definition at line 339 of file unroll.c.

339  {
341  if(!ENDP(indices)) {
344  set_union(s,s,xs);
345  set_free(xs);
346  }
347 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
static list indices
Definition: icm.c:204
void set_free(set)
Definition: set.c:332
set set_union(set, const set, const set)
Definition: set.c:211
set get_referenced_entities(void *elem)
retrieves the set of entities used in elem beware that this entities may be formal parameters,...
Definition: entity.c:3063
#define reference_indices(x)
Definition: ri.h:2328
static char * x
Definition: split_file.c:159
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59

References CAR, ENDP, EXPRESSION, gen_last(), get_referenced_entities(), indices, reference_indices, set_free(), set_union(), and x.

Referenced by simdizer_auto_tile().

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

◆ keep_loop_indices()

static void keep_loop_indices ( statement  s,
list L 
)
static

Definition at line 349 of file unroll.c.

349  {
350  if(statement_loop_p(s))
351  *L=CONS(STATEMENT,s,*L);
352 }
bool statement_loop_p(statement)
Definition: statement.c:349
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Definition: pip__tab.h:30

References CONS, STATEMENT, and statement_loop_p().

Referenced by simdizer_auto_tile().

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

◆ loop_auto_unroll()

bool loop_auto_unroll ( const char *  mod_name)

unroll.c

do the job

Parameters
mod_nameod_name

Definition at line 270 of file unroll.c.

270  {
271  // get the resources
272  statement mod_stmt = (statement)
273  db_get_memory_resource(DBR_CODE, mod_name, true);
274 
277 
278  debug_on("SIMDIZER_DEBUG_LEVEL");
279 
280  /* do the job */
281  const char* slabel = get_string_property_or_ask("LOOP_LABEL","enter the label of a loop !");
282  entity elabel = find_label_entity(mod_name,slabel);
283 
284  if(entity_undefined_p(elabel)) {
285  pips_user_error("label %s does not exist !\n", slabel);
286  }
287  else {
288  statement theloopstatement = find_loop_from_label(get_current_module_statement(),elabel);
289  if(!statement_undefined_p(theloopstatement)) {
290  simple_simd_unroll_loop_filter(theloopstatement);
291  }
292  }
293 
294  pips_assert("Statement is consistent after SIMDIZER_AUTO_UNROLL",
295  statement_consistent_p(mod_stmt));
296 
297  // Reorder the module, because new statements have been added
298  module_reorder(mod_stmt);
299  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
300 
301  // update/release resources
304 
305  debug_off();
306 
307  return true;
308 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
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
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
#define debug_on(env)
Definition: misc-local.h:157
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
const char * get_string_property_or_ask(const char *, const char[])
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
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
#define entity_undefined_p(x)
Definition: ri.h:2762
#define statement_undefined_p(x)
Definition: ri.h:2420
statement find_loop_from_label(statement, entity)
Definition: util.c:218
static bool simple_simd_unroll_loop_filter(statement s)
Definition: unroll.c:173

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, entity_undefined_p, find_label_entity(), find_loop_from_label(), get_current_module_statement(), get_string_property_or_ask(), module_name_to_entity(), module_reorder(), pips_assert, pips_user_error, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), simple_simd_unroll_loop_filter(), statement_consistent_p(), and statement_undefined_p.

+ Here is the call graph for this function:

◆ should_unroll_p()

static bool should_unroll_p ( instruction  i)
static

Definition at line 53 of file unroll.c.

54 {
55  switch(instruction_tag(i))
56  {
58  return true;
59 
61  {
62  cons * j;
63 
65  j != NIL;
66  j = CDR(j) )
67  {
68  statement s = STATEMENT(CAR(j));
70  return false;
71  }
72  return true;
73  }
74 
80  default:
81  return false;
82  }
83 }
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514

References CAR, CDR, instruction_sequence, instruction_tag, is_instruction_call, is_instruction_goto, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, NIL, sequence_statements, STATEMENT, and statement_instruction.

Referenced by full_simd_unroll_loop_filter(), and simple_simd_unroll_loop_filter().

+ Here is the caller graph for this function:

◆ simd_loop_unroll()

static void simd_loop_unroll ( statement  loop_statement,
intptr_t  rate 
)
static

Definition at line 101 of file unroll.c.

102 {
103  range r = loop_range(statement_loop(loop_statement));
105  intptr_t irange;
106  if(expression_integer_value(erange,&irange) && irange <=rate) {
107  bool saved[] = {
108  get_bool_property("LOOP_NORMALIZE_ONE_INCREMENT"),
109  get_bool_property("LOOP_NORMALIZE_SKIP_INDEX_SIDE_EFFECT")
110  };
111  set_bool_property("LOOP_NORMALIZE_ONE_INCREMENT",true);
112  set_bool_property("LOOP_NORMALIZE_SKIP_INDEX_SIDE_EFFECT",true);
113  loop_normalize_statement(loop_statement);
114  range r = loop_range(statement_loop(loop_statement));
117  set_bool_property("LOOP_NORMALIZE_ONE_INCREMENT",saved[0]);
118  set_bool_property("LOOP_NORMALIZE_SKIP_INDEX_SIDE_EFFECT",saved[1]);
119  full_loop_unroll(loop_statement);
120  }
121  else
122  {
123  expression lower = range_lower(r);
124  NORMALIZE_EXPRESSION(lower);
125  entity new = entity_undefined;
127  new = make_new_index_entity(loop_index(statement_loop(loop_statement)),"i");
130  }
131  do_loop_unroll(loop_statement,rate,NULL);
132  if (! entity_undefined_p(new)){
133  insert_statement(loop_statement,
135  true);
136  }
137  }
138  free_expression(erange);
139 }
void free_expression(expression p)
Definition: ri.c:853
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
void full_loop_unroll(statement loop_statement)
get rid of the loop by body replication;
Definition: loop_unroll.c:788
void do_loop_unroll(statement loop_statement, int rate, void(*statement_post_processor)(statement))
loop_unroll.c
Definition: loop_unroll.c:714
void set_bool_property(const char *, bool)
#define NORMALIZE_EXPRESSION(e)
@ range_to_nbiter
expression range_to_expression(range r, enum range_to_expression_mode mode)
computes the distance between the lower bound and the upper bound of the range
Definition: eval.c:963
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
void AddEntityToCurrentModule(entity)
Add a variable entity to the current module declarations.
Definition: variable.c:260
entity make_new_index_entity(entity, string)
Definition: variable.c:1851
#define normalized_complex_p(x)
Definition: ri.h:1782
#define range_upper(x)
Definition: ri.h:2290
#define entity_undefined
Definition: ri.h:2761
#define expression_normalized(x)
Definition: ri.h:1249
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640
#define intptr_t
Definition: stdint.in.h:294
void loop_normalize_statement(statement)
loop_normalize.c

References AddEntityToCurrentModule(), do_loop_unroll(), entity_to_expression(), entity_undefined, entity_undefined_p, expression_integer_value(), expression_normalized, free_expression(), full_loop_unroll(), get_bool_property(), insert_statement(), intptr_t, loop_index, loop_normalize_statement(), loop_range, make_assign_statement(), make_new_index_entity(), NORMALIZE_EXPRESSION, normalized_complex_p, range_lower, range_to_expression(), range_to_nbiter, range_upper, set_bool_property(), simplify_expression(), and statement_loop().

Referenced by full_simd_unroll_loop_filter(), and simple_simd_unroll_loop_filter().

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

◆ simd_unroll_as_needed()

static void simd_unroll_as_needed ( statement  module_stmt)
static

Choose algorithm to use, and use it

Definition at line 251 of file unroll.c.

252 {
253  /* Choose algorithm to use, and use it */
254  if (get_bool_property("SIMDIZER_AUTO_UNROLL_SIMPLE_CALCULATION"))
255  {
256  gen_recurse(module_stmt, statement_domain,
258  }
259  else
260  {
261  set_simd_treematch((matchTree)db_get_memory_resource(DBR_SIMD_TREEMATCH,"",true));
262  set_simd_operator_mappings(db_get_memory_resource(DBR_SIMD_OPERATOR_MAPPINGS,"",true));
263 
264  gen_recurse(module_stmt, statement_domain,
268  }
269 }
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
void reset_simd_operator_mappings()
Definition: operatorid.c:48
void set_simd_operator_mappings(void *m)
operatorid.c
Definition: operatorid.c:43
void reset_simd_treematch(void)
Definition: treematch.c:52
void set_simd_treematch(matchTree)
treematch.c
Definition: treematch.c:46
static bool full_simd_unroll_loop_filter(statement s)
Definition: unroll.c:218

References db_get_memory_resource(), full_simd_unroll_loop_filter(), gen_null(), gen_recurse, get_bool_property(), reset_simd_operator_mappings(), reset_simd_treematch(), set_simd_operator_mappings(), set_simd_treematch(), simple_simd_unroll_loop_filter(), and statement_domain.

Referenced by simdizer_auto_unroll().

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

◆ simdizer_auto_tile()

bool simdizer_auto_tile ( const char *  module_name)

do the job

retrieve loop indices that are referenced as last element

build tests

iterate over all possible combination of tests

create the if's recursively

validate

Parameters
module_nameodule_name

Definition at line 409 of file unroll.c.

409  {
410  bool success = false;
414 
415  /* do the job */
416  const char* slabel = get_string_property_or_ask("LOOP_LABEL","enter the label of a loop !");
417  entity elabel = find_label_entity(module_name,slabel);
418 
419  if(entity_undefined_p(elabel)) {
420  pips_user_error("label %s does not exist !\n", slabel);
421  }
422  else {
423  statement theloopstatement = find_loop_from_label(get_current_module_statement(),elabel);
424  if(!statement_undefined_p(theloopstatement)) {
425  if(perfectly_nested_loop_p(theloopstatement)) {
426  /* retrieve loop indices that are referenced as last element */
429  list tloops = NIL;
431  list allloops =gen_copy_seq(tloops);
432  FOREACH(STATEMENT,l,allloops) {
434  gen_remove_once(&tloops,l);
435  }
436  theloopstatement=STATEMENT(CAR((tloops)));
437  //allloops=gen_nreverse(allloops);
438  while(theloopstatement!=STATEMENT(CAR(allloops))) POP(allloops);
439  set_free(indices);
441 
442  /* build tests */
443  int max_unroll_rate = simple_simd_unroll_rate(statement_loop(theloopstatement));
444  int nloops=gen_length(allloops);
445  /* iterate over all possible combination of tests */
446  expression alltests[1+nloops];
447  alltests[nloops] = expression_undefined ;
448  int j=0;
449  FOREACH(STATEMENT,sl,allloops) {
450  alltests[j++]=MakeBinaryCall(
453  int_to_expression(2*max_unroll_rate)
454  );
455  }
456  /* create the if's recursively */
457  statement root =
459  theloopstatement,
460  nloops,
461  alltests);
463  *theloopstatement=*root;
464  loop_label(statement_loop(theloopstatement))=elabel;
465  success=true;
466 
467  /* validate */
470  }
471  else pips_user_error("loop is not perfectly nested !\n");
472  }
473  else pips_user_error("label is not on a loop!\n");
474  }
475 
479  return success;
480 }
static list loops
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool success
Definition: gpips-local.h:59
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
bool perfectly_nested_loop_p(statement stat)
Test if a statement is a perfect loop-nest.
Definition: loop.c:543
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
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
size_t gen_length(const list l)
Definition: list.c:150
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
set set_assign_list(set, const list)
assigns a list contents to a set all duplicated elements are lost
Definition: set.c:474
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ 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
#define GREATER_THAN_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define expression_undefined
Definition: ri.h:1223
#define loop_label(x)
Definition: ri.h:1646
static void gather_local_indices(reference r, set s)
Definition: unroll.c:339
static statement simdizer_auto_tile_generate_all_tests(statement root, int maxdepth, expression tests[1+maxdepth])
Definition: unroll.c:400
static void stmt_rm_labels(statement s)
Definition: unroll.c:404
static void keep_loop_indices(statement s, list *L)
Definition: unroll.c:349

References CAR, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, entity_intrinsic(), entity_undefined_p, expression_undefined, find_label_entity(), find_loop_from_label(), FOREACH, gather_local_indices(), gen_context_recurse, gen_copy_seq(), gen_free_list(), gen_length(), gen_recurse, gen_remove_once(), gen_true(), gen_true2(), get_current_module_statement(), get_string_property_or_ask(), GREATER_THAN_OPERATOR_NAME, indices, int_to_expression(), keep_loop_indices(), loop_index, loop_label, loop_range, loops, MakeBinaryCall(), module_name(), module_name_to_entity(), module_reorder(), NIL, perfectly_nested_loop_p(), pips_user_error, POP, range_to_expression(), range_to_nbiter, reference_domain, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), set_assign_list(), set_belong_p(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_free(), set_make(), set_pointer, simdizer_auto_tile_generate_all_tests(), simple_simd_unroll_rate(), STATEMENT, statement_domain, statement_loop(), statement_undefined_p, and stmt_rm_labels().

+ Here is the call graph for this function:

◆ simdizer_auto_tile_generate_all_tests()

static statement simdizer_auto_tile_generate_all_tests ( statement  root,
int  maxdepth,
expression  tests[1+maxdepth] 
)
static

Definition at line 400 of file unroll.c.

400  {
401  return do_simdizer_auto_tile_generate_all_tests(root,maxdepth,0,&tests[0]);
402 }

References do_simdizer_auto_tile_generate_all_tests().

Referenced by simdizer_auto_tile().

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

◆ simdizer_auto_unroll()

bool simdizer_auto_unroll ( char *  mod_name)
Parameters
mod_nameod_name

Definition at line 310 of file unroll.c.

311 {
312  // get the resources
313  statement mod_stmt = (statement)
314  db_get_memory_resource(DBR_CODE, mod_name, true);
315 
318 
319  debug_on("SIMDIZER_DEBUG_LEVEL");
320 
321  simd_unroll_as_needed(mod_stmt);
322 
323  pips_assert("Statement is consistent after SIMDIZER_AUTO_UNROLL",
324  statement_consistent_p(mod_stmt));
325 
326  // Reorder the module, because new statements have been added
327  module_reorder(mod_stmt);
328  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
329 
330  // update/release resources
333 
334  debug_off();
335 
336  return true;
337 }
static void simd_unroll_as_needed(statement module_stmt)
Definition: unroll.c:251

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, module_name_to_entity(), module_reorder(), pips_assert, reset_current_module_entity(), reset_current_module_statement(), set_current_module_entity(), set_current_module_statement(), simd_unroll_as_needed(), and statement_consistent_p().

+ Here is the call graph for this function:

◆ simple_simd_unroll_loop_filter()

static bool simple_simd_unroll_loop_filter ( statement  s)
static

If this is not a loop, keep on recursing

Can only simdize certain loops

can't do anything

Unroll as many times as needed by the variables width

Do not recursively analyse the loop

Definition at line 173 of file unroll.c.

174 {
175  instruction i;
176  loop l;
177  instruction iBody;
178 
179  /* If this is not a loop, keep on recursing */
180  i = statement_instruction(s);
181  if (!instruction_loop_p(i))
182  return true;
183  l = instruction_loop(i);
184 
185  /* Can only simdize certain loops */
186  iBody = statement_instruction(loop_body(l));
187  if (!should_unroll_p(iBody))
188  return true; /* can't do anything */
189 
190  /* Unroll as many times as needed by the variables width */
192 
193  /* Do not recursively analyse the loop */
194  return false;
195 }

References instruction_loop, instruction_loop_p, loop_body, should_unroll_p(), simd_loop_unroll(), simple_simd_unroll_rate(), and statement_instruction.

Referenced by loop_auto_unroll(), and simd_unroll_as_needed().

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

◆ simple_simd_unroll_rate()

static int simple_simd_unroll_rate ( loop  l)
static

Compute variable size

Decide between min and max unroll factor

Round up varwidth to a power of 2

Unroll as many times as needed by the variables width

Definition at line 141 of file unroll.c.

141  {
142  /* Compute variable size */
143  MinMaxVar varwidths = { INT_MAX , 0 };
144  int varwidth;
145  gen_context_recurse(loop_body(l), &varwidths,
147 
148  /* Decide between min and max unroll factor */
149  if (get_bool_property("SIMDIZER_AUTO_UNROLL_MINIMIZE_UNROLL"))
150  varwidth = varwidths.max;
151  else
152  varwidth = varwidths.min;
153 
154  /* Round up varwidth to a power of 2 */
155  int regWidth = get_int_property("SAC_SIMD_REGISTER_WIDTH");
156 
157  if ((varwidth > regWidth/2) || (varwidth <= 0))
158  return 1;
159 
160  for(int j = 8; j <= regWidth/2; j*=2)
161  {
162  if (varwidth <= j)
163  {
164  varwidth = j;
165  break;
166  }
167  }
168 
169  /* Unroll as many times as needed by the variables width */
170  return regWidth / varwidth;
171 }
int get_int_property(const string)
static void compute_variable_size(statement s, MinMaxVar *varwidth)
Definition: unroll.c:90

References compute_variable_size(), gen_context_recurse, gen_true2(), get_bool_property(), get_int_property(), loop_body, MinMaxVar::max, MinMaxVar::min, and statement_domain.

Referenced by do_simdizer_auto_tile_int_to_list(), simdizer_auto_tile(), and simple_simd_unroll_loop_filter().

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

◆ stmt_rm_labels()

static void stmt_rm_labels ( statement  s)
static

Definition at line 404 of file unroll.c.

405 {
406  (void) statement_remove_useless_label(s, false);
407 }
void statement_remove_useless_label(statement, bool *)
remove the label of a statement if the statement is not unstructured.
Definition: statement.c:4275

References statement_remove_useless_label().

Referenced by simdizer_auto_tile().

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