PIPS
if_conversion_init.c File Reference
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "complexity_ri.h"
#include "text.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "database.h"
#include "misc.h"
#include "pipsdbm.h"
#include "resources.h"
#include "control.h"
#include "transformations.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "properties.h"
#include "complexity.h"
#include "sac.h"
+ Include dependency graph for if_conversion_init.c:

Go to the source code of this file.

Functions

static statement atomize_condition (statement cs)
 atomize the condition of a test and returns generated statements More...
 
static bool check_if_conv_call (call c, bool *success)
 accept if conversion if the call is an assignment call More...
 
static bool check_if_conv_test (test t, bool *success)
 checks if a test statement is suitable for if conversion, that is it only contains sequence of assignments More...
 
static bool check_if_conv_walker (instruction i, bool *success)
 
static bool check_if_conv (statement stat)
 checks if if conversion can be performed on test statement More...
 
static void update_test_condition (test t, expression cond)
 adds More...
 
static statement make_if_converted_test_statement (expression cond, statement branch)
 create a test statement with appropriate extension and a test under cond with a single true branch branch More...
 
static statement do_transform_if_statements (statement branch, expression cond)
 merge content of a test with the test itself More...
 
static void if_conv_init_statement (statement stat)
 
bool if_conversion_init (char *mod_name)
 if_conversion_init.c More...
 

Function Documentation

◆ atomize_condition()

static statement atomize_condition ( statement  cs)
static

atomize the condition of a test and returns generated statements

Parameters
cstest statement
Returns
generated statement

Definition at line 66 of file if_conversion_init.c.

67 {
68  test t = statement_test(cs);
69  expression cond = test_condition(t);
70  if(!expression_reference_p(cond))
72  return statement_undefined;
73 }
test statement_test(statement)
Get the test of a statement.
Definition: statement.c:1348
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
entity make_new_scalar_variable(entity, basic)
Definition: variable.c:741
#define test_condition(x)
Definition: ri.h:2833
#define statement_undefined
Definition: ri.h:2419
statement simd_atomize_this_expression(entity(*create)(entity, basic), expression e)
returns the assignment statement if moved, or NULL if not.
Definition: atomizer.c:87

References expression_reference_p(), make_new_scalar_variable(), simd_atomize_this_expression(), statement_test(), statement_undefined, and test_condition.

Referenced by if_conv_init_statement().

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

◆ check_if_conv()

static bool check_if_conv ( statement  stat)
static

checks if if conversion can be performed on test statement

Parameters
stattest statement
Returns
true if conversion possible

Definition at line 127 of file if_conversion_init.c.

128 {
130 
131  pips_assert("statement is a test", statement_test_p(stat));
132 
133  bool success = true;
135  return success;
136 }
bool success
Definition: gpips-local.h:59
bool statement_test_p(statement)
Definition: statement.c:343
static bool check_if_conv_test(test t, bool *success)
checks if a test statement is suitable for if conversion, that is it only contains sequence of assign...
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_test(x)
Definition: ri.h:1517

References check_if_conv_test(), instruction_test, pips_assert, statement_instruction, and statement_test_p().

Referenced by if_conv_init_statement().

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

◆ check_if_conv_call()

static bool check_if_conv_call ( call  c,
bool success 
)
static

accept if conversion if the call is an assignment call

Definition at line 79 of file if_conversion_init.c.

80 {
81  call tmp = copy_call(c);
82  split_update_call(tmp);
83  entity op = call_function(tmp);
85  free_call(tmp);
86  return *success;
87 }
call copy_call(call p)
CALL.
Definition: ri.c:233
void free_call(call p)
Definition: ri.c:236
void split_update_call(call c)
Definition: flatten_code.c:772
#define call_constant_p(C)
Definition: flint_check.c:51
#define ENTITY_ASSIGN_P(e)
#define ENTITY_CONTINUE_P(e)
#define call_function(x)
Definition: ri.h:709

References call_constant_p, call_function, copy_call(), ENTITY_ASSIGN_P, ENTITY_CONTINUE_P, free_call(), and split_update_call().

Referenced by check_if_conv_walker().

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

◆ check_if_conv_test()

static bool check_if_conv_test ( test  t,
bool success 
)
static

checks if a test statement is suitable for if conversion, that is it only contains sequence of assignments

Definition at line 110 of file if_conversion_init.c.

111 {
112  statement branches[2] = { test_true(t), test_false(t) };
113 
114  for(size_t i=0;i<2;i++)
115  gen_context_recurse(branches[i], success,
117  return false;
118 }
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
static bool check_if_conv_walker(instruction i, bool *success)
#define test_false(x)
Definition: ri.h:2837
#define instruction_domain
newgen_functional_domain_defined
Definition: ri.h:202
#define test_true(x)
Definition: ri.h:2835

References check_if_conv_walker(), gen_context_recurse, gen_null2(), instruction_domain, test_false, and test_true.

Referenced by check_if_conv(), and check_if_conv_walker().

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

◆ check_if_conv_walker()

static bool check_if_conv_walker ( instruction  i,
bool success 
)
static

Definition at line 90 of file if_conversion_init.c.

91 {
92  switch(instruction_tag(i))
93  {
99  return true;
100  default:
101  return false;
102  };
103 }
static bool check_if_conv_call(call c, bool *success)
accept if conversion if the call is an assignment call
#define is_instruction_block
soft block->sequence transition
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
#define instruction_tag(x)
Definition: ri.h:1511
#define instruction_call(x)
Definition: ri.h:1529

References check_if_conv_call(), check_if_conv_test(), instruction_call, instruction_tag, instruction_test, is_instruction_block, is_instruction_call, and is_instruction_test.

Referenced by check_if_conv_test().

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

◆ do_transform_if_statements()

static statement do_transform_if_statements ( statement  branch,
expression  cond 
)
static

merge content of a test with the test itself

Parameters
branchcontent of the test
condcondition of the test
Returns
merged statements

Definition at line 168 of file if_conversion_init.c.

169 {
170  // only add the condition if content is a test
171  if(statement_test_p(branch))
172  {
173  update_test_condition( statement_test(branch) ,cond);
174  return copy_statement(branch);
175  }
176  // the big part : merge tests into a single block
177  // the idea is too stack statements until a test is met.
178  // stacked statements are put under condition, then the test is added and so on
179  else if(statement_block_p(branch))
180  {
181  list block=NIL;
182  list curr_block = NIL;
183  FOREACH(STATEMENT,st,statement_block(branch))
184  {
185  if(statement_test_p(st))
186  {
188  if(!ENDP(curr_block))
191  curr_block=NIL;
192  }
193  else
194  {
195  curr_block=CONS(STATEMENT,copy_statement(st),curr_block);
196  }
197  }
198  if(!ENDP(curr_block))
201  }
202  // not much to do there, ony allpy test condition
203  else
205 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
statement make_block_statement(list)
Make a block statement from a list of statement.
Definition: statement.c:616
#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 NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#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
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
static void update_test_condition(test t, expression cond)
adds
static statement make_if_converted_test_statement(expression cond, statement branch)
create a test statement with appropriate extension and a test under cond with a single true branch br...
#define statement_block_p(stat)
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CONS, copy_expression(), copy_statement(), ENDP, FOREACH, gen_nreverse(), make_block_statement(), make_if_converted_test_statement(), NIL, STATEMENT, statement_block(), statement_block_p, statement_test(), statement_test_p(), and update_test_condition().

Referenced by if_conv_init_statement().

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

◆ if_conv_init_statement()

static void if_conv_init_statement ( statement  stat)
static

Definition at line 212 of file if_conversion_init.c.

213 {
214  // Only interested in the test statements
215  if(statement_test_p(stat))
216  {
217 
219  if (ancestor && INSTANCE_OF(control, ancestor)) {
220  // Hmmm, we are inside a control node
221  control c = (control) ancestor;
222  if (gen_length(control_successors(c)) == 2) {
223  // A control node with 2 successors is an unstructured test:
224  pips_user_warning("not converting a non structured test yet...\n");
225  return;
226  }
227  }
228 
229  complexity stat_comp = load_statement_complexity(stat);
230  if(stat_comp != (complexity) HASH_UNDEFINED_VALUE)
231  {
232 
233  Ppolynome poly = complexity_polynome(stat_comp);
234  if(polynome_constant_p(poly))
235  {
236  clean_up_sequences(stat);
237  pips_debug(2,"analyzing statement:\n");
238  ifdebug(2) {
239  print_statement(stat);
240  }
241 
242  // Get the number of calls in the if statement
243  int cost = polynome_TCST(poly);
244  pips_debug(3,"cost %d\n", cost);
245 
246  // ensure the statement is valid
247  bool success = check_if_conv(stat);
248 
249  // If the number of calls is smaller than IF_CONV_THRESH
250  if(success && cost < get_int_property("IF_CONVERSION_INIT_THRESHOLD"))
251  {
252  test t = statement_test(stat);
253 
254  // Atomize the condition
256 
257  expression not_test_condition=
261  );
262  list block =
265  do_transform_if_statements(test_false(t),not_test_condition)
266  );
270  ifdebug(3) {
271  pips_debug(3,"new test:\n");
272  print_statement(stat);
273  }
274  }
275  }
276  else
277  pips_user_warning("not converting a test, complexity too ... complex \n");
278 
279  }
280  else
281  pips_user_warning("not converting a test, complexity not available\n");
282  }
283 }
int get_int_property(const string)
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
Ppolynome complexity_polynome(complexity comp)
Because complexity is composed of two elements, we use this function to get the first element : polyn...
Definition: comp_math.c:506
complexity load_statement_complexity(statement)
gen_chunk * gen_get_recurse_current_ancestor(void)
Get the ancestor of the current object.
Definition: genClib.c:3526
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
size_t gen_length(const list l)
Definition: list.c:150
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
static statement atomize_condition(statement cs)
atomize the condition of a test and returns generated statements
static statement do_transform_if_statements(statement branch, expression cond)
merge content of a test with the test itself
static bool check_if_conv(statement stat)
checks if if conversion can be performed on test statement
struct _newgen_struct_control_ * control
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
float polynome_TCST(Ppolynome pp)
float polynome_TCST(Ppolynome pp) returns the constant term of polynomial pp.
Definition: pnome-reduc.c:156
bool polynome_constant_p(Ppolynome pp)
bool polynome_constant_p(Ppolynome pp) return true if pp is a constant polynomial (including null pol...
Definition: pnome-reduc.c:180
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define INSTANCE_OF(type, value)
polymorhism thanks to newgen !
#define make_statement_list(stats...)
easy list constructor
#define NOT_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
#define control_successors(x)
Definition: ri.h:945
#define statement_undefined_p(x)
Definition: ri.h:2420
#define ifdebug(n)
Definition: sg.c:47
A gen_chunk is used to store every object.
Definition: genC.h:58

References atomize_condition(), check_if_conv(), clean_up_sequences(), complexity_polynome(), CONS, control_successors, copy_expression(), do_transform_if_statements(), entity_intrinsic(), gen_get_recurse_current_ancestor(), gen_length(), get_int_property(), HASH_UNDEFINED_VALUE, ifdebug, INSTANCE_OF, load_statement_complexity(), make_instruction_block(), make_statement_list, MakeUnaryCall(), NOT_OPERATOR_NAME, pips_debug, pips_user_warning, polynome_constant_p(), polynome_TCST(), print_statement(), STATEMENT, statement_test(), statement_test_p(), statement_undefined_p, test_condition, test_false, test_true, and update_statement_instruction().

Referenced by if_conversion_init().

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

◆ if_conversion_init()

bool if_conversion_init ( char *  mod_name)

if_conversion_init.c

Parameters
mod_nameod_name

Definition at line 337 of file if_conversion_init.c.

338 {
339  // get the resources
341  statement root = (statement) db_get_memory_resource(DBR_CODE, mod_name, true);
343 
344  set_current_module_statement(fake);// to prevent a complex bug with gen_recurse and AddEntityToCurrentModule
345  set_complexity_map( (statement_mapping) db_get_memory_resource(DBR_COMPLEXITIES, mod_name, true));
346 
347  debug_on("IF_CONVERSION_INIT_DEBUG_LEVEL");
348 
349  ifdebug(1) {
350  pips_debug(1, "Code before if_conversion_init:\n");
351  print_statement(root);
352  }
353 
354  // Now do the job
356 
357  ifdebug(1) {
358  pips_debug(1, "Code after if_conv_init_statement:\n");
359  print_statement(root);
360  }
361 
362  // and share decl
365  free_statement(fake);
366 
367  ifdebug(1) {
368  pips_debug(1, "Code after copying from fake statement:\n");
369  print_statement(root);
370  }
371 
372  // Reorder the module, because new statements have been added
373  module_reorder(root);
374  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, root);
375 
376  // update/release resources
380 
381  debug_off();
382 
383  return true;
384 }
void free_statement(statement p)
Definition: ri.c:2189
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void reset_complexity_map(void)
void set_complexity_map(statement_mapping)
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
Definition: statement.c:625
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
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
void insert_statement_no_matter_what(statement, statement, bool)
Break the IR consistency or, at the very least, do not insert new declarations at the usual place,...
Definition: statement.c:2581
static void if_conv_init_statement(statement stat)
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References copy_statement(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, FOREACH, free_statement(), gen_recurse, gen_true(), if_conv_init_statement(), ifdebug, insert_statement_no_matter_what(), make_empty_block_statement(), module_name_to_entity(), module_reorder(), pips_debug, print_statement(), reset_complexity_map(), reset_current_module_entity(), reset_current_module_statement(), set_complexity_map(), set_current_module_entity(), set_current_module_statement(), STATEMENT, statement_block(), and statement_domain.

+ Here is the call graph for this function:

◆ make_if_converted_test_statement()

static statement make_if_converted_test_statement ( expression  cond,
statement  branch 
)
static

create a test statement with appropriate extension and a test under cond with a single true branch branch

Definition at line 150 of file if_conversion_init.c.

151 {
154  make_test(cond,branch,make_empty_statement())));
156  return s;
157 }
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
extension make_extension_pragma(pragma _field_)
Definition: ri.c:938
instruction make_instruction_test(test _field_)
Definition: ri.c:1172
pragma make_pragma_string(string _field_)
Definition: ri.c:1775
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
#define make_empty_statement
An alias for make_empty_block_statement.
#define EXTENSION(x)
EXTENSION.
Definition: ri.h:1253
#define statement_extensions(x)
Definition: ri.h:2464
#define extensions_extension(x)
Definition: ri.h:1330
#define IF_TO_CONVERT
if conversion
Definition: sac-local.h:43
char * strdup()

References CONS, EXTENSION, extensions_extension, IF_TO_CONVERT, instruction_to_statement(), make_empty_statement, make_extension_pragma(), make_instruction_test(), make_pragma_string(), make_test(), NIL, statement_extensions, and strdup().

Referenced by do_transform_if_statements().

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

◆ update_test_condition()

static void update_test_condition ( test  t,
expression  cond 
)
static

adds

Parameters
condto the condtion of
t

Definition at line 142 of file if_conversion_init.c.

143 {
145 }
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354

References AND_OPERATOR_NAME, copy_expression(), entity_intrinsic(), MakeBinaryCall(), and test_condition.

Referenced by do_transform_if_statements().

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