PIPS
simd_memory_packing.c
Go to the documentation of this file.
1 /*
2 
3  $Id: simd_memory_packing.c 23495 2018-10-24 09:19:47Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 #include "genC.h"
28 #include "linear.h"
29 #include "ri.h"
30 #include "effects.h"
31 
32 #include "resources.h"
33 
34 #include "misc.h"
35 #include "ri-util.h"
36 #include "syntheses.h"
37 #include "prettyprint.h"
38 #include "effects-util.h"
39 #include "pipsdbm.h"
40 
41 #include "effects-generic.h"
42 #include "accel-util.h"
43 
44 #include "sac.h"
45 
46 #include "effects-convex.h"
47 #include "preprocessor.h"
48 
49 static
50 bool simd_replace_parameters( hash_table array_to_vector )
51 {
52  bool failed = true;
55  {
56  dummy d = parameter_dummy(p);
57  if( dummy_identifier_p(d) )
58  {
59  /* recover the parameter name */
60  entity dummy_e = dummy_identifier(d);
61  const char* parameter_name = entity_local_name(dummy_e);
62  /* get associated entity */
64  /* find associated vector if any */
65  entity found = hash_get(array_to_vector,real_e);
66  if( ! entity_undefined_p(found) )
67  {
68  /* gather information concerning the vector */
71 
72  basic b = variable_basic(v);
73  pips_assert( "found vector is a vector of int", !basic_undefined_p(b) && basic_int_p(b) );
74 
75  /* create a new basic : increased int size*/
76  /* substitute this basic to the old one*/
77  variable new_var = copy_variable( type_variable(entity_type(real_e)) );
78 
79  basic new_var_basic = variable_basic(new_var);
80  while( basic_pointer_p(new_var_basic))
81  {
82  new_var_basic = variable_basic(type_variable( basic_pointer(new_var_basic)));
83  }
84  pips_assert("is a basic int",basic_int_p(new_var_basic));
85  basic_int(new_var_basic)=basic_int(b) * n ;
86 
87  /* update dummy parameter */
89  entity_type(dummy_e)= make_type_variable(new_var);
92 
93  /* update declaration */
94  FOREACH(ENTITY, decl_ent,
96  {
97  if( same_entity_lname_p(decl_ent, real_e))
98  {
100  entity_type(decl_ent)= make_type_variable(copy_variable(new_var));
101  }
102  }
103 
104  failed=false;
105  }
106  }
107  }
108  return !failed;
109 
110 }
111 
112 static
113 void simd_trace_call(statement s, hash_table array_to_vector)
114 {
115  /* we only look for load - save statement */
116  if( simd_dma_stat_p(s) )
117  {
119  int nb_args = gen_length(args);
120  /* and only of the form SIMD_(...)(vect,array) */
121  if( nb_args == 2 )
122  {
123  expression e = EXPRESSION(CAR(CDR(args)));
124  syntax s = expression_syntax(e);
125  bool through_address_of = false;
126  if( (through_address_of=(syntax_call_p(s) && ENTITY_ADDRESS_OF_P(call_function(syntax_call(s))))) )
128  pips_assert("parameter is a reference", syntax_reference_p(s));
130  pips_assert("parameter is a variable",type_variable_p(entity_type(reference_variable(r))));
132  pips_assert("parameter is an array", (through_address_of&&reference_indices(r)) || ! ENDP(variable_dimensions(v)));
133  hash_put(array_to_vector,
136  );
137  }
138  }
139 
140 }
141 string compilation_unit_of_module(const char*);
142 
143 /**
144  * @brief pack load / store from char or short array
145  * into load / store from int array
146  * a new module is generated
147  * @param mod_name name of the module to convert
148  *
149  * @return false if something went wrong
150  */
151 bool simd_memory_packing(char *mod_name)
152 {
153  bool failed = false;
154  /* get the resources */
155  statement mod_stmt = (statement)db_get_memory_resource(DBR_CODE, mod_name, true);
158 
159  /* first step : create a vector <> array table */
160  hash_table array_to_vector = hash_table_make(hash_pointer,0);
161  gen_context_recurse(mod_stmt, array_to_vector, statement_domain, gen_true2, simd_trace_call);
162  if(( failed=hash_table_empty_p(array_to_vector)) )
163  {
164  pips_user_warning("I did not find any simd load / store operation :'(\n");
165  goto simd_memory_packing_end;
166  }
167 
168  /* second step : look for any array ``vectorized'' in the parameter
169  * and modify their type to fit the real array size
170  */
171  {
172  bool replaced_something = simd_replace_parameters(array_to_vector);
173  if( ( failed = !replaced_something ) )
174  {
175  pips_user_warning("I did not find any vectorized array in module parameters :'(\n");
176  goto simd_memory_packing_end;
177  }
179  add_new_module_from_text( mod_name,
180  t,
182  );
183  free_text(t);
184  /* update/release resources */
185  hash_table_free(array_to_vector);
186 
189  }
190 
191 simd_memory_packing_end:
192  return !failed;
193 }
type make_type_variable(variable _field_)
Definition: ri.c:2715
variable copy_variable(variable p)
VARIABLE.
Definition: ri.c:2859
void free_variable(variable p)
Definition: ri.c:2862
void free_text(text p)
Definition: text.c:74
bool simd_dma_stat_p(statement)
This function returns true if the statement is a simd loadsave statement.
Definition: delay.c:127
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
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
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
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
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
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_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
bool add_new_module_from_text(const char *module_name, text code_text, bool is_fortran, const char *compilation_unit_name)
Add the new resource files associated to a module with its more-or-less correct code.
Definition: initializer.c:431
#define pips_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
@ hash_pointer
Definition: newgen_hash.h:32
#define hash_table_empty_p(htp)
Definition: newgen_hash.h:58
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
text text_module(entity, statement)
bool same_entity_lname_p(entity, entity)
Definition: same_names.c:64
#define ENTITY_ADDRESS_OF_P(e)
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
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
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
Value ValueNumberOfElements(list)
Definition: size.c:435
#define dummy_identifier(x)
Definition: ri.h:1033
#define basic_pointer(x)
Definition: ri.h:637
#define syntax_reference_p(x)
Definition: ri.h:2728
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define basic_int(x)
Definition: ri.h:616
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define code_declarations(x)
Definition: ri.h:784
#define basic_undefined_p(x)
Definition: ri.h:557
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define syntax_call(x)
Definition: ri.h:2736
#define variable_dimensions(x)
Definition: ri.h:3122
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define expression_syntax(x)
Definition: ri.h:1247
#define dummy_identifier_p(x)
Definition: ri.h:1031
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
#define entity_initial(x)
Definition: ri.h:2796
bool simd_memory_packing(char *mod_name)
pack load / store from char or short array into load / store from int array a new module is generated
static bool simd_replace_parameters(hash_table array_to_vector)
static void simd_trace_call(statement s, hash_table array_to_vector)
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
The structure used to build lists in NewGen.
Definition: newgen_list.h:41