Dear all,
I have been trying to insert function calls during a new pass in the
compiler but it does not seem to like my way of doing it. The basic
idea is to insert a function call before any load in the program
(later on I'll be selecting a few loads but for now I just want to do
it for each and every one).
This looks like the profiling pass but I can't seem to understand what
is the matter...
This is what the compiler says when I try to compile this test case :
hello.c:18: internal compiler error: tree check: expected ssa_name,
have symbol_memory_tag in verify_ssa, at tree-ssa.c:776
This is what I did in my pass :
/* Generation of the call type, function will be of type
* de type void (*) (int) */
tree call_type = build_function_type_list ( void_type_node,
integer_type_node,
NULL_TREE);
tree call_fn = build_fn_decl ("__MarkovMainEntry",call_type);
data_reference_p a;
for (j = 0; VEC_iterate (data_reference_p, datarefs, j, a); j++)
{
tree stmt = DR_STMT (a);
/* Is it a load */
if (DR_IS_READ (a))
{
printf("Have a load : %d\n",compteur_interne);
tree compteur = build_int_cst (integer_type_node,
compteur_interne);
compteur_interne++;
/* Argument creation, just pass the constant integer node */
tree args = tree_cons (NULL_TREE, compteur, NULL_TREE);
tree call = build_function_call_expr (call_fn, args);
block_stmt_iterator bsi;
bsi = bsi_for_stmt (stmt);
bsi_insert_after(&bsi, call, BSI_SAME_STMT);
}
}
And the test code is :
#include <stdio.h>
int fct(int *t);
int main()
{
int tab[10];
int i;
tab[0] = 0;
printf("Hello World %d\n",tab[5]);
printf("Sum is : %d\n",fct(tab));
return 0;
}
int fct(int *t)
{
int i=10;
int tab[10];
while(i) {
tab[i] = tab[i]*2+1+tab[i+1];
i--;
printf("Here %d\n",tab[5]);
}
return t[i];
}
Does anyone have any ideas on to how I can modify my function and get
it to insert the functions correctly ?
Thanx for any help in finishing this pass,
Jc
Finally here is the patch that shows what I did using the trunk 4.2 :
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi (revision 116394)
+++ doc/invoke.texi (working copy)
@@ -342,7 +342,7 @@ Objective-C and Objective-C++ Dialects}.
-fsplit-ivs-in-unroller -funswitch-loops @gol
-fvariable-expansion-in-unroller @gol
-ftree-pre -ftree-ccp -ftree-dce -ftree-loop-optimize @gol
--ftree-loop-linear -ftree-loop-im -ftree-loop-ivcanon -fivopts @gol
+-ftree-loop-linear -ftree-load-inst -ftree-loop-im
-ftree-loop-ivcanon -fivopts @gol
-ftree-dominator-opts -ftree-dse -ftree-copyrename -ftree-sink @gol
-ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre -ftree-vectorize @gol
-ftree-vect-loop-version -ftree-salias -fipa-pta -fweb @gol
@@ -5120,6 +5120,10 @@ at @option{-O} and higher.
Perform linear loop transformations on tree. This flag can improve cache
performance and allow further loop optimizations to take place.
[EMAIL PROTECTED] -ftree-load-inst
+Perform instrumentation of load on trees. This flag inserts a call to
a profiling
+function before the loads of a program.
+
@item -ftree-loop-im
Perform loop invariant motion on trees. This pass moves only invariants that
would be hard to handle at RTL level (function calls, operations
that expand to
Index: tree-pass.h
===================================================================
--- tree-pass.h (revision 116394)
+++ tree-pass.h (working copy)
@@ -251,6 +251,7 @@ extern struct tree_opt_pass pass_empty_l
extern struct tree_opt_pass pass_record_bounds;
extern struct tree_opt_pass pass_if_conversion;
extern struct tree_opt_pass pass_vectorize;
+extern struct tree_opt_pass pass_load_inst;
extern struct tree_opt_pass pass_complete_unroll;
extern struct tree_opt_pass pass_loop_prefetch;
extern struct tree_opt_pass pass_iv_optimize;
Index: tree-load-inst.c
===================================================================
--- tree-load-inst.c (revision 0)
+++ tree-load-inst.c (revision 0)
@@ -0,0 +1,125 @@
+#include <stdlib.h>
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "ggc.h"
+#include "tree.h"
+#include "target.h"
+
+#include "rtl.h"
+#include "basic-block.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "timevar.h"
+#include "cfgloop.h"
+#include "expr.h"
+#include "optabs.h"
+#include "tree-chrec.h"
+#include "tree-data-ref.h"
+#include "tree-scalar-evolution.h"
+#include "tree-pass.h"
+#include "lambda.h"
+
+extern struct loops *current_loops;
+static void tree_handle_loop (struct loops *loops);
+
+
+static unsigned int tree_load_inst (void)
+{
+ fprintf (stderr, "My load instrumentation start\n");
+
+ if (current_loops == NULL)
+ {
+ fprintf (stderr,"No loop\n");
+ return 0;
+ }
+
+ tree_handle_loop (current_loops);
+ return 0;
+}
+
+void tree_handle_loop (struct loops *loops)
+{
+ unsigned int i;
+ unsigned int j;
+ static int compteur_interne = 0;
+
+ for (i = 1; i<loops->num; i++)
+ {
+ struct loop *loop_nest = loops->parray[i];
+
+ //If no loop_nest
+ if (!loop_nest)
+ continue;
+
+ VEC (ddr_p, heap) *dependence_relations;
+ VEC (data_reference_p, heap) *datarefs;
+
+ datarefs = VEC_alloc (data_reference_p, heap, 10);
+ dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
+ compute_data_dependences_for_loop (loop_nest, true, &datarefs,
+ &dependence_relations);
+
+ /* Generation de mon call statement, notre fonction sera
+ * de type void (*) (int) */
+ tree call_type = build_function_type_list (void_type_node,
+ integer_type_node,
+ NULL_TREE);
+ tree call_fn = build_fn_decl ("__MarkovMainEntry",call_type);
+
+ data_reference_p a;
+ for (j = 0; VEC_iterate (data_reference_p, datarefs, j, a); j++)
+ {
+ tree stmt = DR_STMT (a);
+
+ /* On fait nos test pour voir si c'est un load */
+ if (DR_IS_READ (a))
+ {
+ printf ("Have a load : %d\n", compteur_interne);
+ tree compteur = build_int_cst (integer_type_node,
compteur_interne);
+ compteur_interne++;
+
+ /* Generation de l'instruction pour l'appel */
+ tree args = build_tree_list (NULL_TREE, compteur);
+
+ /* Je suppose que args est correctement mis en place */
+ tree call = build_function_call_expr (call_fn, args);
+
+ block_stmt_iterator bsi;
+ bsi = bsi_for_stmt (stmt);
+ bsi_insert_after (&bsi, call, BSI_SAME_STMT);
+ }
+ }
+ }
+
+ fprintf (stderr,"My load instrumentation stop\n");
+ debug_loop_ir ();
+}
+
+static bool gate_tree_load_inst (void)
+{
+ return flag_tree_load_inst;
+}
+
+
+struct tree_opt_pass pass_load_inst =
+ {
+ "loadinst", /* name */
+ gate_tree_load_inst, /* gate */
+ tree_load_inst, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_LOAD_INST, /* tv_id */
+ PROP_cfg|PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func|TODO_verify_loops, /* todo_flags_finish */
+ 0 /* letter */
+ };
+
Index: timevar.def
===================================================================
--- timevar.def (revision 116394)
+++ timevar.def (working copy)
@@ -108,6 +108,7 @@ DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "
DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling")
DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization")
DEFTIMEVAR (TV_TREE_LINEAR_TRANSFORM , "tree loop linear")
+DEFTIMEVAR (TV_TREE_LOAD_INST , "tree load instrumentation")
DEFTIMEVAR (TV_TREE_PREFETCH , "tree prefetching")
DEFTIMEVAR (TV_TREE_LOOP_IVOPTS , "tree iv optimization")
DEFTIMEVAR (TV_TREE_LOOP_INIT , "tree loop init")
Index: common.opt
===================================================================
--- common.opt (revision 116394)
+++ common.opt (working copy)
@@ -965,6 +965,10 @@ ftree-loop-linear
Common Report Var(flag_tree_loop_linear)
Enable linear loop transforms on trees
+ftree-load-inst
+Common Report Var(flag_tree_load_inst)
+Enable load instrumentation on trees
+
ftree-loop-ivcanon
Common Report Var(flag_tree_loop_ivcanon) Init(1)
Create canonical induction variables in loops
Index: tree-profile.c
===================================================================
--- tree-profile.c (revision 116394)
+++ tree-profile.c (working copy)
@@ -175,7 +175,7 @@ tree_gen_pow2_profiler (histogram_value
tree_cons (NULL_TREE, val,
NULL_TREE));
call = build_function_call_expr (tree_pow2_profiler_fn, args);
- bsi_insert_before (&bsi, call, BSI_SAME_STMT);
+ bsi_insert_before(&bsi, call, BSI_SAME_STMT);
}
/* Output instructions as GIMPLE trees for code to find the most
common value.
Index: tree-flow.h
===================================================================
--- tree-flow.h (revision 116394)
+++ tree-flow.h (working copy)
@@ -949,6 +949,9 @@ tree force_gimple_operand_bsi (block_stm
/* In tree-ssa-structalias.c */
bool find_what_p_points_to (tree);
+/* In tree-load-inst.c */
+extern void load_inst(struct loops *);
+
/* In tree-ssa-live.c */
extern void remove_unused_locals (void);
Index: Makefile.in
===================================================================
--- Makefile.in (revision 116394)
+++ Makefile.in (working copy)
@@ -988,6 +988,7 @@ OBJS-common = \
tree-ssa-loop-ivcanon.o tree-ssa-propagate.o tree-ssa-address.o \
tree-ssa-math-opts.o
\
tree-ssa-loop-ivopts.o tree-if-conv.o tree-ssa-loop-unswitch.o
\
+ tree-load-inst.o \
alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o
\
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o
\
cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o
loop-unroll.o \
@@ -2104,6 +2105,11 @@ tree-loop-linear.o: tree-loop-linear.c $
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) $(LAMBDA_H) \
$(TARGET_H) tree-chrec.h
+tree-load-inst.o: tree-load-inst.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
+ tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) $(LAMBDA_H) \
+ $(TARGET_H) tree-chrec.h $(VARRAY_H)
tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FUNCTION_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
tree-stdarg.h $(TARGET_H) langhooks.h
Index: passes.c
===================================================================
--- passes.c (revision 116394)
+++ passes.c (working copy)
@@ -605,6 +605,7 @@ init_optimization_passes (void)
/* NEXT_PASS (pass_may_alias) cannot be done again because the
vectorizer creates alias relations that are not supported by
pass_may_alias. */
+ NEXT_PASS (pass_load_inst);
NEXT_PASS (pass_complete_unroll);
NEXT_PASS (pass_loop_prefetch);
NEXT_PASS (pass_iv_optimize);
-----------------------------------------------------
Degskalle There is no point in arguing with an idiot, they will just
drag you down to their level and beat you with experience
Référence: http://www.bash.org/?latest
-----------------------------------------------------