PIPS
if_conversion_compact.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 "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 "effects-generic.h"
#include "effects-simple.h"
#include "properties.h"
#include "sac.h"
#include "ricedg.h"
+ Include dependency graph for if_conversion_compact.c:

Go to the source code of this file.

Functions

static bool statement_phi_function_p (statement s)
 checks wether a statement is a phi function call of the form a=phi(cond, vt,vf) where phi is given by a property More...
 
static bool compact_phi_functions (statement s0, statement s1)
 try to compact two phi-statements into a single one More...
 
static bool statement_conflicts_p (statement sink, list source_successors)
 checks if there is a write-read conflict between source and sink according to dg successors source_successors More...
 
static void if_conversion_compact_stats (statement stat, graph dg)
 
bool if_conversion_compact (char *mod_name)
 cproto-generated files More...
 

Function Documentation

◆ compact_phi_functions()

static bool compact_phi_functions ( statement  s0,
statement  s1 
)
static

try to compact two phi-statements into a single one

Parameters
s0first statement to compact
s1second statement to compact
Returns
true if compaction succeeded, false otherwise

all datas are handeled as pairs in an array of 2 elements we use i and !i to denote current index and its opposite

let's compare assignment part

ok it may be good, now let's compare both phi functions

first constraint : ref[i] == false_val[i]

second constraint : cond[0] == !cond[1]

yes, we have in s1 a = cond ? b:a; and in s2 a = !cond ? c: a; it will become a = cond ? b :c ;

1:replace false_val[i] by true_val[!i]

2:unlink true_val[!i]

3: replace s[!i] by a continue

Definition at line 89 of file if_conversion_compact.c.

90 {
91  /* all datas are handeled as pairs in an array of 2 elements
92  * we use i and !i to denote current index and its opposite
93  */
94  statement s [2] = { s0,s1 };
95 
96  expression lhs[2];
97  for(size_t i=0;i<2;i++)
98  lhs[i]=binary_call_lhs(statement_call(s[i]));
99 
100  /* let's compare assignment part */
101  if(same_expression_p(lhs[0],lhs[1]) && expression_reference_p(lhs[0]))
102  {
103 
104  /* ok it may be good, now
105  let's compare both phi functions */
106  call phis[2];
107  reference ref[2];
108  expression cond[2], true_val[2], false_val[2];
109  for(size_t i=0;i<2;i++)
110  {
111  ref[i]=expression_reference(lhs[i]);
113  cond[i]=EXPRESSION(CAR(call_arguments(phis[i])));
114  true_val[i]=EXPRESSION(CAR(CDR(call_arguments(phis[i]))));
115  false_val[i]=EXPRESSION(CAR(CDR(CDR(call_arguments(phis[i])))));
116  }
117 
118  /* first constraint : ref[i] == false_val[i] */
119  if( expression_reference_p(false_val[0]) && expression_reference_p(false_val[1]))
120  {
121  if(reference_equal_p(ref[0],expression_reference(false_val[0])) &&
122  reference_equal_p(ref[1],expression_reference(false_val[1])))
123  {
124  /* second constraint : cond[0] == !cond[1] */
125  bool ok = false;
126  size_t i;
127  for(i =0;i<2;i++)
128  {
129  if(expression_call(cond[!i]) && ENTITY_NOT_P(call_function(expression_call(cond[!i]))))
130  {
132  cond[i])))
133  break;
134  }
135  }
136  if(ok)
137  {
138  /* yes, we have in s1 a = cond ? b:a; and in s2 a = !cond ? c: a;
139  * it will become a = cond ? b :c ;*/
140 
141  /* 1:replace false_val[i] by true_val[!i]*/
142  free_expression(false_val[i]);
143  *REFCAR(CDR(CDR(call_arguments(phis[i]))))=(gen_chunkp)true_val[!i];
144  /* 2:unlink true_val[!i]*/
146  /* 3: replace s[!i] by a continue */
148  return true;
149  }
150  }
151  }
152  }
153  return false;
154 }
void free_expression(expression p)
Definition: ri.c:853
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define gen_chunk_undefined
Definition: genC.h:74
union gen_chunk * gen_chunkp
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
#define REFCAR(pc)
Get the adress of the first element of a list.
Definition: newgen_list.h:119
#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
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
#define binary_call_rhs(c)
#define ENTITY_NOT_P(e)
#define binary_call_lhs(c)
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
call expression_call(expression e)
Definition: expression.c:445
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
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
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
#define call_function(x)
Definition: ri.h:709
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define call_arguments(x)
Definition: ri.h:711
s1
Definition: set.c:247
static bool ok

References binary_call_lhs, binary_call_rhs, call_arguments, call_function, CAR, CDR, ENTITY_NOT_P, EXPRESSION, expression_call(), expression_equal_p(), expression_reference(), expression_reference_p(), free_expression(), gen_chunk_undefined, make_continue_instruction(), ok, ref, REFCAR, reference_equal_p(), s1, same_expression_p(), statement_call(), and update_statement_instruction().

Referenced by if_conversion_compact_stats().

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

◆ if_conversion_compact()

bool if_conversion_compact ( char *  mod_name)

cproto-generated files

if_conversion_compact.c

Parameters
mod_nameod_name

Definition at line 252 of file if_conversion_compact.c.

253 {
254  // get the resources
255  statement mod_stmt = (statement)
256  db_get_memory_resource(DBR_CODE, mod_name, true);
257 
260  set_ordering_to_statement(mod_stmt);
261 
262  graph dg = (graph) db_get_memory_resource(DBR_DG, mod_name, true);
263 
265  db_get_memory_resource(DBR_PROPER_EFFECTS, mod_name, true));
266 
267  debug_on("IF_CONVERSION_COMPACT_DEBUG_LEVEL");
268  // Now do the job
269 
271 
272  // Reorder the module, because new statements have been added
273  module_reorder(mod_stmt);
274  DB_PUT_MEMORY_RESOURCE(DBR_CODE, mod_name, mod_stmt);
275 
276  // update/release resources
281 
282  debug_off();
283 
284  return true;
285 }
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
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_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
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
static void if_conversion_compact_stats(statement stat, graph dg)
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dg, gen_context_recurse, gen_true2(), if_conversion_compact_stats(), module_name_to_entity(), module_reorder(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), reset_proper_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), set_proper_rw_effects(), and statement_domain.

+ Here is the call graph for this function:

◆ if_conversion_compact_stats()

static void if_conversion_compact_stats ( statement  stat,
graph  dg 
)
static

iterate over the trailing statements to find a legal statement to compact we stop when a conflict is found or when we achived our goal

look for a write - read conflict between st and next

Definition at line 184 of file if_conversion_compact.c.

185 {
186  // Only look at the sequence statements
187  if(statement_block_p(stat))
188  {
190 
191  for(list iter = statement_block(stat);!ENDP(iter);POP(iter))
192  {
193  statement st = STATEMENT(CAR(iter));
195  {
196  ifdebug(1) {
197  pips_debug(1,"checking statement:\n");
198  print_statement(st);
199  }
200  /* iterate over the trailing statements to find a legal statement to compact
201  * we stop when a conflict is found or when we achived our goal
202  */
203  list succ = hash_get(successors,st);
204  FOREACH(STATEMENT,next,CDR(iter))
205  {
206 
207  if(statement_phi_function_p(next))
208  {
209  if(compact_phi_functions(st,next))
210  {
211  ifdebug(1) {
212  pips_debug(1,"compacted into statement:\n");
213  print_statement(st);
214  }
215  break;
216  }
217  }
218  /* look for a write - read conflict between st and next */
219  else if(statement_conflicts_p(next, succ)) break;
220  }
221  }
222  }
224  }
225 }
static list successors(list l)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define 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
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
static bool statement_phi_function_p(statement s)
checks wether a statement is a phi function call of the form a=phi(cond, vt,vf) where phi is given by...
static bool compact_phi_functions(statement s0, statement s1)
try to compact two phi-statements into a single one
static bool statement_conflicts_p(statement sink, list source_successors)
checks if there is a write-read conflict between source and sink according to dg successors source_su...
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define statement_block_p(stat)
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
hash_table statements_to_successors(list, graph)
creates a hash_table containing statements from statements as keys and their respective succesors acc...
Definition: util.c:1018
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CAR, CDR, compact_phi_functions(), dg, ENDP, FOREACH, hash_get(), hash_table_free(), ifdebug, pips_debug, POP, print_statement(), STATEMENT, statement_block(), statement_block_p, statement_conflicts_p(), statement_phi_function_p(), statements_to_successors(), and successors().

Referenced by if_conversion_compact().

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

◆ statement_conflicts_p()

static bool statement_conflicts_p ( statement  sink,
list  source_successors 
)
static

checks if there is a write-read conflict between source and sink according to dg successors source_successors

if there is a write-read conflict, we cannot do much

Definition at line 161 of file if_conversion_compact.c.

162 {
163  FOREACH(SUCCESSOR,s,source_successors)
164  {
166  if(ss==sink)
167  {
169  {
170  /* if there is a write-read conflict, we cannot do much */
173  return true;
174 
175  }
176  }
177  }
178  return false;
179 }
#define conflict_sink(x)
Definition: dg.h:167
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define conflict_source(x)
Definition: dg.h:165
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45

References CONFLICT, conflict_sink, conflict_source, dg_arc_label_conflicts, effect_read_p, effect_write_p, FOREACH, SUCCESSOR, successor_arc_label, successor_vertex, and vertex_to_statement().

Referenced by if_conversion_compact_stats().

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

◆ statement_phi_function_p()

static bool statement_phi_function_p ( statement  s)
static

checks wether a statement is a phi function call of the form a=phi(cond, vt,vf) where phi is given by a property

Parameters
sstatement to check
Returns
result of the check

Definition at line 65 of file if_conversion_compact.c.

66 {
68  {
70  if(expression_call_p(rhs))
71  {
72  const char* phi_name = get_string_property("IF_CONVERSION_PHI");
73  entity phi = entity_intrinsic(phi_name);
75  }
76  }
77  return false;
78 }
char * get_string_property(const char *)
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
bool expression_call_p(expression e)
Definition: expression.c:415

References assignment_statement_p(), binary_call_rhs, call_function, entity_intrinsic(), expression_call(), expression_call_p(), get_string_property(), same_entity_p(), and statement_call().

Referenced by if_conversion_compact_stats().

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