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
-----------------------------------------------------


Reply via email to