Permalink
Browse files

Loop invariant code motion implemented.

  • Loading branch information...
1 parent 2de02c4 commit 6fcabfbad5fe9179adde49d82b7fe9e214f2baba @schani committed Aug 15, 2009
Showing with 421 additions and 53 deletions.
  1. +1 −1 Makefile
  2. +1 −1 backends/cc.c
  3. +23 −1 bitvector.c
  4. +5 −1 bitvector.h
  5. +11 −1 compiler-internals.h
  6. +96 −48 compiler.c
  7. +284 −0 compopt/licm.c
View
@@ -122,7 +122,7 @@ CXX = g++
export CFLAGS CC
-COMMON_OBJECTS = mathmap_common.o builtins/builtins.o exprtree.o parser.o scanner.o vars.o tags.o tuples.o internals.o macros.o userval.o overload.o jump.o builtins/libnoise.o builtins/spec_func.o compiler.o bitvector.o expression_db.o drawable.o floatmap.o tree_vectors.o mmpools.o designer/designer.o designer/cycles.o designer/loadsave.o designer_filter.o native-filters/gauss.o compopt/dce.o compopt/resize.o backends/cc.o backends/lazy_creator.o $(FFTW_OBJECTS) $(LLVM_OBJECTS)
+COMMON_OBJECTS = mathmap_common.o builtins/builtins.o exprtree.o parser.o scanner.o vars.o tags.o tuples.o internals.o macros.o userval.o overload.o jump.o builtins/libnoise.o builtins/spec_func.o compiler.o bitvector.o expression_db.o drawable.o floatmap.o tree_vectors.o mmpools.o designer/designer.o designer/cycles.o designer/loadsave.o designer_filter.o native-filters/gauss.o compopt/dce.o compopt/resize.o compopt/licm.o backends/cc.o backends/lazy_creator.o $(FFTW_OBJECTS) $(LLVM_OBJECTS)
#COMMON_OBJECTS += designer/widget.o
COMMON_OBJECTS += designer/cairo_widget.o
View
@@ -812,7 +812,7 @@ generate_plug_in (char *filter, char *output_filename,
return 0;
}
- compiler_generate_ir_code(mathmap->main_filter, analyze_constants, 0, -1);
+ compiler_generate_ir_code(mathmap->main_filter, analyze_constants, 0, -1, FALSE);
out = fopen(output_filename, "w");
View
@@ -3,7 +3,7 @@
*
* MathMap
*
- * Copyright (C) 2004 Mark Probst
+ * Copyright (C) 2004-2009 Mark Probst
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -92,6 +92,28 @@ bit_vector_bit (bit_vector_t *bitvec, unsigned long which)
return (bitvec->data[which >> LONG_SHIFT] & BIT(which & LONG_MASK)) != 0;
}
+void
+bit_vector_add (bit_vector_t *bitvec, bit_vector_t *addee)
+{
+ int i;
+
+ g_assert(bitvec->size == addee->size);
+
+ for (i = 0; i < BIT_SIZE_TO_LONG_SIZE(bitvec->size); ++i)
+ bitvec->data[i] |= addee->data[i];
+}
+
+void
+bit_vector_dump (bit_vector_t *bitvec)
+{
+ int i;
+
+ for (i = 0; i < bitvec->size; ++i)
+ if (bit_vector_bit(bitvec, i))
+ printf("%d ", i);
+ printf("\n");
+}
+
#ifdef TEST_BITVECTOR
#include <stdio.h>
View
@@ -3,7 +3,7 @@
*
* MathMap
*
- * Copyright (C) 2004 Mark Probst
+ * Copyright (C) 2004-2009 Mark Probst
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -38,3 +38,7 @@ void bit_vector_set (bit_vector_t *bitvec, unsigned long which);
void bit_vector_clear (bit_vector_t *bitvec, unsigned long which);
int bit_vector_bit (bit_vector_t *bitvec, unsigned long which);
+
+void bit_vector_add (bit_vector_t *bitvec, bit_vector_t *addee);
+
+void bit_vector_dump (bit_vector_t *bitvec);
View
@@ -302,20 +302,28 @@ extern void compiler_replace_op_rhs_arg (statement_t *stmt, int arg_num, primary
extern value_set_t* compiler_new_value_set (void);
extern void compiler_value_set_add (value_set_t *set, value_t *val);
+extern void compiler_value_set_add_set (value_set_t *set, value_set_t *addee);
extern gboolean compiler_value_set_contains (value_set_t *set, value_t *val);
+extern value_set_t* compiler_value_set_copy (value_set_t *set);
extern void compiler_free_value_set (value_set_t *set);
+extern statement_t* compiler_stmt_unlink (statement_t **stmtp);
+extern statement_t** compiler_stmt_insert_before (statement_t *stmt, statement_t **insertion_point);
+
extern void compiler_for_each_value_in_rhs (rhs_t *rhs, void (*func) (value_t *value, void *info),
void *info);
extern void compiler_for_each_value_in_statements (statement_t *stmt,
void (*func) (value_t *value, statement_t *stmt, void *info),
void *info);
+extern void compiler_for_each_value_in_statement (statement_t *stmt,
+ void (*func) (value_t *value, statement_t *stmt, void *info),
+ void *info);
extern int compiler_slice_code (statement_t *stmt, unsigned int slice_flag,
int (*predicate) (statement_t *stmt, void *info), void *info);
extern filter_code_t* compiler_generate_ir_code (filter_t *filter, int constant_analysis,
- int convert_types, int timeout);
+ int convert_types, int timeout, gboolean debug_output);
extern filter_code_t** compiler_compile_filters (mathmap_t *mathmap, int timeout);
@@ -327,9 +335,11 @@ extern void compiler_slice_code_for_const (statement_t *stmt, int const_type);
extern gboolean compiler_opt_remove_dead_assignments (statement_t *first_stmt);
extern gboolean compiler_opt_orig_val_resize (statement_t **first_stmt);
extern gboolean compiler_opt_strip_resize (statement_t **first_stmt);
+extern gboolean compiler_opt_loop_invariant_code_motion (statement_t **first_stmt);
#define COMPILER_FOR_EACH_VALUE_IN_RHS(rhs,func,...) do { long __clos[] = { __VA_ARGS__ }; compiler_for_each_value_in_rhs((rhs),(func),__clos); } while (0)
#define COMPILER_FOR_EACH_VALUE_IN_STATEMENTS(stmt,func,...) do { long __clos[] = { __VA_ARGS__ }; compiler_for_each_value_in_statements((stmt),(func),__clos); } while (0)
+#define COMPILER_FOR_EACH_VALUE_IN_STATEMENT(stmt,func,...) do { long __clos[] = { __VA_ARGS__ }; compiler_for_each_value_in_statement((stmt),(func),__clos); } while (0)
#define COMPILER_SLICE_CODE(stmt,flag,func,...) do { long __clos[] = { __VA_ARGS__ }; compiler_slice_code((stmt),(flag),(func),__clos); } while (0)
#ifdef __cplusplus
View
@@ -173,14 +173,20 @@ compiler_value_set_add (value_set_t *set, value_t *val)
bit_vector_set(set, val->global_index);
}
+void
+compiler_value_set_add_set (value_set_t *set, value_set_t *addee)
+{
+ bit_vector_add(set, addee);
+}
+
gboolean
compiler_value_set_contains (value_set_t *set, value_t *val)
{
return bit_vector_bit(set, val->global_index);
}
-static value_set_t*
-value_set_copy (value_set_t *set)
+value_set_t*
+compiler_value_set_copy (value_set_t *set)
{
return copy_bit_vector(set);
}
@@ -191,6 +197,32 @@ compiler_free_value_set (value_set_t *set)
free_bit_vector(set);
}
+statement_t*
+compiler_stmt_unlink (statement_t **stmtp)
+{
+ statement_t *stmt = *stmtp;
+
+ g_assert(stmt != NULL);
+
+ *stmtp = stmt->next;
+ stmt->next = NULL;
+ stmt->parent = NULL;
+ return stmt;
+}
+
+statement_t**
+compiler_stmt_insert_before (statement_t *stmt, statement_t **insertion_point)
+{
+ g_assert(stmt != NULL && stmt->next == NULL && stmt->parent == NULL);
+ g_assert(*insertion_point != NULL);
+
+ stmt->next = *insertion_point;
+ stmt->parent = stmt->next->parent;
+ *insertion_point = stmt;
+
+ return &stmt->next;
+}
+
int
compiler_op_index (operation_t *op)
{
@@ -742,39 +774,44 @@ _call_func (value_t *value, void *info)
}
void
-compiler_for_each_value_in_statements (statement_t *stmt, void (*func) (value_t *value, statement_t *stmt, void *info), void *info)
+compiler_for_each_value_in_statement (statement_t *stmt, void (*func) (value_t *value, statement_t *stmt, void *info), void *info)
{
- while (stmt != 0)
+ switch (stmt->kind)
{
- switch (stmt->kind)
- {
- case STMT_NIL :
- break;
+ case STMT_NIL :
+ break;
- case STMT_PHI_ASSIGN :
- COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.assign.rhs2, &_call_func, func, stmt, info);
- case STMT_ASSIGN :
- COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.assign.rhs, &_call_func, func, stmt, info);
- func(stmt->v.assign.lhs, stmt, info);
- break;
+ case STMT_PHI_ASSIGN :
+ COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.assign.rhs2, &_call_func, func, stmt, info);
+ case STMT_ASSIGN :
+ COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.assign.rhs, &_call_func, func, stmt, info);
+ func(stmt->v.assign.lhs, stmt, info);
+ break;
- case STMT_IF_COND :
- COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.if_cond.condition, &_call_func, func, stmt, info);
- compiler_for_each_value_in_statements(stmt->v.if_cond.consequent, func, info);
- compiler_for_each_value_in_statements(stmt->v.if_cond.alternative, func, info);
- compiler_for_each_value_in_statements(stmt->v.if_cond.exit, func, info);
- break;
+ case STMT_IF_COND :
+ COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.if_cond.condition, &_call_func, func, stmt, info);
+ compiler_for_each_value_in_statements(stmt->v.if_cond.consequent, func, info);
+ compiler_for_each_value_in_statements(stmt->v.if_cond.alternative, func, info);
+ compiler_for_each_value_in_statements(stmt->v.if_cond.exit, func, info);
+ break;
- case STMT_WHILE_LOOP :
- COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.while_loop.invariant, &_call_func, func, stmt, info);
- compiler_for_each_value_in_statements(stmt->v.while_loop.entry, func, info);
- compiler_for_each_value_in_statements(stmt->v.while_loop.body, func, info);
- break;
+ case STMT_WHILE_LOOP :
+ COMPILER_FOR_EACH_VALUE_IN_RHS(stmt->v.while_loop.invariant, &_call_func, func, stmt, info);
+ compiler_for_each_value_in_statements(stmt->v.while_loop.entry, func, info);
+ compiler_for_each_value_in_statements(stmt->v.while_loop.body, func, info);
+ break;
- default :
- g_assert_not_reached();
- }
+ default :
+ g_assert_not_reached();
+ }
+}
+void
+compiler_for_each_value_in_statements (statement_t *stmt, void (*func) (value_t *value, statement_t *stmt, void *info), void *info)
+{
+ while (stmt != 0)
+ {
+ compiler_for_each_value_in_statement(stmt, func, info);
stmt = stmt->next;
}
}
@@ -3117,7 +3154,7 @@ analyze_least_const_type_multiply_used_in (statement_t *stmt, int in_loop, value
sub_least_const = analyze_least_const_type_multiply_used_in(stmt->v.while_loop.entry,
in_loop, multiply_assigned_set, changed);
- copy = value_set_copy(multiply_assigned_set);
+ copy = compiler_value_set_copy(multiply_assigned_set);
assert(copy != 0);
/* we have to process the body twice because
@@ -4435,7 +4472,7 @@ check_ssa_with_undo (statement_t *stmts, statement_t *parent, GHashTable *curren
value_set_t *defined_set_copy;
current_value_hash_copy = direct_hash_table_copy(current_value_hash);
- defined_set_copy = value_set_copy(defined_set);
+ defined_set_copy = compiler_value_set_copy(defined_set);
check_ssa_recursively(stmts, parent, current_value_hash_copy, defined_set_copy);
@@ -4636,7 +4673,7 @@ optimization_time_out (struct timeval *start, int timeout)
}
filter_code_t*
-compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_types, int timeout)
+compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_types, int timeout, gboolean debug_output)
{
gboolean changed;
filter_code_t *code;
@@ -4669,10 +4706,11 @@ compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_
check_ssa(first_stmt);
#endif
-#ifdef DEBUG_OUTPUT
- printf("--------------------------------\n");
- dump_code(first_stmt, 0);
-#endif
+ if (debug_output)
+ {
+ printf("--------------------------------\n");
+ dump_code(first_stmt, 0);
+ }
optimize_closure_application(first_stmt);
CHECK_SSA;
@@ -4687,6 +4725,8 @@ compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_
CHECK_SSA;
changed = optimize_make_tuple() || changed;
CHECK_SSA;
+ changed = compiler_opt_loop_invariant_code_motion(&first_stmt) || changed;
+ CHECK_SSA;
changed = common_subexpression_elimination() || changed;
CHECK_SSA;
changed = copy_propagation() || changed;
@@ -4696,16 +4736,18 @@ compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_
changed = simplify_ops() || changed;
CHECK_SSA;
-#ifdef DEBUG_OUTPUT
- printf("-------------------------------- before resize\n");
- dump_code(first_stmt, 0);
-#endif
+ if (debug_output)
+ {
+ printf("-------------------------------- before resize\n");
+ dump_code(first_stmt, 0);
+ }
changed = compiler_opt_orig_val_resize(&first_stmt) || changed;
CHECK_SSA;
-#ifdef DEBUG_OUTPUT
- printf("-------------------------------- after resize\n");
- dump_code(first_stmt, 0);
-#endif
+ if (debug_output)
+ {
+ printf("-------------------------------- after resize\n");
+ dump_code(first_stmt, 0);
+ }
changed = compiler_opt_strip_resize(&first_stmt) || changed;
CHECK_SSA;
@@ -4729,10 +4771,11 @@ compiler_generate_ir_code (filter_t *filter, int constant_analysis, int convert_
analyze_constants();
#endif
-#ifdef DEBUG_OUTPUT
- printf("----------- final ---------------------\n");
- dump_code(first_stmt, 0);
-#endif
+ if (debug_output)
+ {
+ printf("----------- final ---------------------\n");
+ dump_code(first_stmt, 0);
+ }
check_ssa(first_stmt);
/* no statement reordering after this point */
@@ -4753,6 +4796,11 @@ compiler_compile_filters (mathmap_t *mathmap, int timeout)
filter_code_t **filter_codes;
int num_filters, i;
filter_t *filter;
+#ifdef DEBUG_OUTPUT
+ gboolean debug_output = TRUE;
+#else
+ gboolean debug_output = FALSE;
+#endif
init_pools(&compiler_pools);
vector_variables = g_hash_table_new(g_direct_hash, g_direct_equal);
@@ -4773,7 +4821,7 @@ compiler_compile_filters (mathmap_t *mathmap, int timeout)
#ifdef DEBUG_OUTPUT
g_print("compiling filter %s\n", filter->name);
#endif
- filter_codes[i] = compiler_generate_ir_code(filter, 1, 0, timeout);
+ filter_codes[i] = compiler_generate_ir_code(filter, 1, 0, timeout, debug_output && filter == mathmap->main_filter);
}
return filter_codes;
Oops, something went wrong.

0 comments on commit 6fcabfb

Please sign in to comment.