28 #include "pips_config.h"
54 #define NORMALIZED_UPPER_BOUND_NAME "LU_NUB"
55 #define INTERMEDIATE_BOUND_NAME "LU_IB"
56 #define INDEX_NAME "LU_IND"
97 void (*statement_post_processor)(
statement))
206 pips_assert(
"The expression for the initial index is consistent",
213 pips_assert(
"The new loop body is consistent after index substitution",
223 if(statement_post_processor)
224 statement_post_processor(transformed_stmt);
237 list declaration_initializations =
NIL;
246 declaration_initializations =
250 declaration_initializations=
gen_nreverse(declaration_initializations);
276 pips_assert(
"the unrolled loop inst is consistent",
343 void (*statement_post_processor)(
statement))
359 bool numeric_range_p =
false;
399 numeric_range_p =
true;
400 pips_assert(
"The loop increment is not zero", incval != 0);
417 pips_assert(
"The expression for the number of iterations is consistent",
441 if (numeric_range_p) {
516 pips_assert(
"the cloned and substituted body is consistent",
588 pips_assert(
"The expression for the initial index is consistent",
594 pips_assert(
"The new loop body is consistent after index substitution",
603 if(statement_post_processor)
604 statement_post_processor(transformed_stmt);
617 list declaration_initializations =
NIL;
626 declaration_initializations =
630 declaration_initializations=
gen_nreverse(declaration_initializations);
657 pips_assert(
"the unrolled loop inst is consistent",
683 pips_assert(
"The old index assignment stmt is consistent",
716 void (*statement_post_processor)(
statement))
721 pips_assert(
"the unrolling factor is strictly positive", rate > 0);
735 statement_post_processor);
739 statement_post_processor);
755 bool unroll_p =
false;
836 for(iter = lbval; iter <= ubval; iter += incval) {
879 list declaration_initializations =
NIL;
888 declaration_initializations=
CONS(
STATEMENT,s,declaration_initializations);
891 declaration_initializations=
gen_nreverse(declaration_initializations);
963 const char *lp_label = NULL;
966 bool return_status =
true;
973 return_status =
false;
977 user_error(
"unroll",
"loop label `%s' does not exist\n", lp_label);
982 string resp =
user_request(
"How many times do you want to unroll?\n(choose integer greater or egal to 2): ");
986 return_status =
false;
988 if(sscanf(resp,
"%d", &rate)!=1 || rate <= 1)
989 user_error(
"unroll",
"unroll factor should be greater than 2\n");
992 if( return_status ) {
994 pips_debug(1,
"Unroll %d times loop %s in module %s\n",
995 rate, lp_label, mod_name);
1020 bool dependent_p =
false;
1030 pips_user_warning(
"Loop cannot be unrolled because it contains a dependent type.\n");
1031 return_status =
false;
1050 return_status =
true;
1057 if ( ! return_status )
1058 user_log(
"Loop unrolling has been cancelled.\n");
1060 return return_status;
1082 bool return_status =
true;
1084 debug_on(
"FULL_UNROLL_DEBUG_LEVEL");
1089 return_status =
false;
1093 pips_user_warning(
"loop label `%s' does not exist, unrolling all loops\n", lp_label);
1122 user_log(
"transformation has been cancelled\n");
1128 return return_status;
1149 #define FULL_UNROLL_PRAGMA "Cxxx"
1176 bool return_status =
false;
1178 debug_on(
"FULL_UNROLL_DEBUG_LEVEL");
1180 debug(1,
"full_unroll_pragma",
"Fully unroll loops with pragma in module %s\n",
1207 return_status =
true;
1213 user_log(
"%d loop%s could not be unrolled as requested\n", failures,
1215 return_status =
false;
1218 debug(1,
"full_unroll_pragma",
"done for %s\n", mod_name);
1224 return return_status;
int get_int_property(const string)
void user_log(const char *format,...)
clone_context make_clone_context(entity a1, entity a2, list a3, statement a4)
void free_clone_context(clone_context p)
bool instruction_consistent_p(instruction p)
execution make_execution(enum execution_utype tag, void *val)
expression make_expression(syntax a1, normalized a2)
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
basic copy_basic(basic p)
BASIC.
expression copy_expression(expression p)
EXPRESSION.
reference make_reference(entity a1, list a2)
bool statement_consistent_p(statement p)
bool range_consistent_p(range p)
bool expression_consistent_p(expression p)
void free_expression(expression p)
void free_instruction(instruction p)
instruction make_instruction(enum instruction_utype tag, void *val)
syntax make_syntax(enum syntax_utype tag, void *val)
execution copy_execution(execution p)
EXECUTION.
range make_range(expression a1, expression a2, expression a3)
list arguments_intersection(list a1, list a2)
Build a new list with all entities occuring in both a1 and a2.
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
statement clone_statement(statement s, clone_context cc)
clone_statement.c
struct _newgen_struct_statement_ * statement
bool empty_string_p(const char *s)
char * get_string_property(const char *)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
int gen_debug
Function interface for user applications.
#define gen_recurse(start, domain_number, flt, rwt)
statement make_block_statement(list)
Make a block statement from a list of statement.
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
void reset_current_module_entity(void)
Reset the current module entity.
void reset_current_module_statement(void)
Reset the current module statement.
statement set_current_module_statement(statement)
Set the current module statement.
statement get_current_module_statement(void)
Get the current module statement.
entity set_current_module_entity(entity)
static.c
entity get_current_module_entity(void)
Get the entity of the current module.
void replace_entity_by_expression(void *s, entity ent, expression exp)
replace all reference to entity ent by expression exp in s.
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
statement make_new_loop_statement(entity i, expression low, expression up, expression inc, statement b, execution e)
This is an ad'hoc function designed for do_loop_unroll_with_epilogue().
#define ENDP(l)
Test if a list is empty.
list gen_nreverse(list cp)
reverse a list in place
#define NIL
The empty list (nil in Lisp)
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
void gen_free_list(list l)
free the spine of the list
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
statement make_assign_statement(expression, expression)
list statement_to_called_user_entities(statement)
Get a list of all user function called recursively within a statement:
statement make_continue_statement(entity)
statement clear_labels(statement)
Get rid of all labels in controlized code before duplication.
bool empty_comments_p(const char *)
void fix_sequence_statement_attributes(statement)
Since blocks are not represented in Fortran, they cannot carry a label.
entity find_final_statement_label(statement)
Find the label associated with the last statement executed within s.
static void find_unroll_pragma_and_fully_unroll(statement s)
static bool apply_full_loop_unroll(struct _newgen_struct_statement_ *s)
bool loop_fully_unrollable_p(loop l)
#define INTERMEDIATE_BOUND_NAME
#define FULL_UNROLL_PRAGMA
C must be a capital C...
static int number_of_requested_unrollings
bool full_unroll_pragma(const string mod_name)
void loop_unroll(statement loop_statement, int rate)
fallbacks on do_loop_unroll without statement post processing
static basic basic_int_to_signed_basic(basic b)
static void do_loop_unroll_with_epilogue(statement loop_statement, int rate, void(*statement_post_processor)(statement))
db_get_current_module_name() unusable because module not set, and setting it causes previous current ...
#define NORMALIZED_UPPER_BOUND_NAME
bool unroll(const string mod_name)
Top-level functions.
static void do_loop_unroll_with_prologue(statement loop_statement, int rate, void(*statement_post_processor)(statement))
This function unrolls any DO loop by a constant factor "rate".
static int number_of_unrolled_loops
bool full_unroll(const string mod_name)
void full_loop_unroll(statement loop_statement)
get rid of the loop by body replication;
void do_loop_unroll(statement loop_statement, int rate, void(*statement_post_processor)(statement))
loop_unroll.c
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
#define pips_user_warning
#define FORTRAN_DIV(n, d)
#define FORTRAN_MOD(n, m)
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
#define user_error(fn,...)
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
string user_request(const char *,...)
void print_statement(statement)
Print a statement on stderr.
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.
#define instruction_block_p(i)
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define statement_block_p(stat)
#define MAX0_OPERATOR_NAME
#define DIVIDE_OPERATOR_NAME
#define instruction_block(i)
#define make_statement_list(stats...)
easy list constructor
#define MULTIPLY_OPERATOR_NAME
bool entity_in_list_p(entity ent, list ent_l)
look for ent in ent_l
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
entity entity_empty_label(void)
bool entity_empty_label_p(entity e)
entity make_new_label(entity module)
This function returns a new label.
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
const char * label_local_name(entity e)
END_EOLE.
bool expression_integer_value(expression e, intptr_t *pval)
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
expression make_ref_expr(entity ent, list args)
list string_to_user_modules(const char *s)
Build a list of functions from a string s containing SPACE separated function names.
bool dependent_type_p(type)
A type is dependent in many ways according to definitions given in Wikipedia.
void AddEntityToCurrentModule(entity)
Add a variable entity to the current module declarations.
entity make_new_scalar_variable_with_prefix(const char *, entity, basic)
Create a new scalar variable of type b in the given module.
entity find_label_entity(const char *, const char *)
util.c
#define normalized_undefined
#define loop_execution(x)
#define instruction_loop_p(x)
#define instruction_loop(x)
#define statement_domain
newgen_sizeofexpression_domain_defined
#define range_increment(x)
#define statement_label(x)
#define entity_undefined_p(x)
#define statement_declarations(x)
#define statement_instruction(x)
#define statement_comments(x)
@ is_execution_sequential
#define statement_undefined_p(x)
#define value_expression_p(x)
#define value_expression(x)
#define variable_basic(x)
#define statement_undefined
#define STATEMENT(x)
STATEMENT.
#define entity_initial(x)
The structure used to build lists in NewGen.