Dear sir, I write a pass to instrument loops to count runtime number of iterations. I insert a variable in each loop by create_tmp_var() and output the results by inserting a printf function at the exit edge of loop. The code is the attachment.
The problem is that for the loops without switch statement inside, my pass works well, but for loops with switch statement inside, my final printf can not catch the correct runtime value of my instrumented variable. In some later pass, the pass will remove my variable increasing statement in loops as a dead code. My final instrumentation will output the initial value only. I attached a simple "hello" world program and dump output tree for it after my pass. Thank you for your help. Fern ====== hello world test program====== =============================== int main(int argc, char * argv[] ) { int i; for (i=0; i<10; i++) { printf("Hello World\n"); switch(i) { case 1: printf("Hello World 1\n"); break; } } =========dump tree file of my pass=============== ;; Function main (main) SSA replacement table N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j looptest1.25_1 -> { looptest1.25_6 } Number of virtual NEW -> OLD mappings: 0 Number of real NEW -> OLD mappings: 1 Number of total NEW -> OLD mappings: 1 Number of virtual symbols: 0 Incremental SSA update started at block: 6 Number of blocks in CFG: 9 Number of blocks to update: 3 ( 33%) ssa loop profile main (argc, argv) { int looptest1.25; int prephitmp.20; int pretmp.19; int i; <bb 2>: __builtin_puts (&"Hello World"[0]); goto <bb 6>; <bb 3>: __builtin_puts (&"Hello World"[0]); switch (i_3) { case 1: goto <L1>; default : goto <L7>; } <L7>:; goto <bb 5> (<L6>); <L1>:; __builtin_puts (&"Hello World 1"[0]); # i_5 = PHI <1(4), i_3(8)> <L6>:; looptest1.25_6 = looptest1.25_4 + 1; <bb 6>: # looptest1.25_4 = PHI <looptest1.25_6(5), 0(2)> # i_7 = PHI <i_5(5), 0(2)> i_3 = i_7 + 1; if (i_3 <= 9) goto <bb 3>; else goto <bb 7>; <bb 7>: # looptest1.25_1 = PHI <looptest1.25_8(D)(6)> printf (&"main loopid: 1 counter: %d\n"[0], looptest1.25_1); return; } ================ my pass code======= ==================================== unsigned int tree_profile_ssa_loop (void){ struct loop *loop; loop_iterator li; FOR_EACH_LOOP (li, loop, 0){ tree ivvarloop,ivvarincedloop; bool insert_after= false; block_stmt_iterator bsi = bsi_start (loop->header); char var_name[40]; sprintf (var_name, "%s%d", "looptest", loop->num); ivvarloop = create_tmp_var (integer_type_node, var_name); add_referenced_var (ivvarloop); standard_iv_increment_position (loop, &bsi, &insert_after); create_iv (build_int_cst_type (integer_type_node, 0), build_int_cst_type (integer_type_node, 1), ivvarloop, loop, &bsi, insert_after, &ivvarloop, &ivvarincedloop); /////////////////////////////////////// // add print i; at loop ends /////////////////////////////////////// char tmp_name[80]; unsigned i; VEC (edge, heap) *exits = get_loop_exit_edges (loop); edge ex; basic_block exitbb = NULL; for (i = 0; VEC_iterate (edge, exits, i, ex); i++){ exitbb = ex->dest; //exitbb = ex->src; block_stmt_iterator bsi = bsi_start (exitbb); sprintf (tmp_name, "%s%s%d%s", current_function_name() ," loopid: ", loop->num," counter: %d\n"); tree call= BuildPrintfCall(tmp_name, ivvarincedloop); bsi_insert_before (&bsi, call, BSI_NEW_STMT); /****** keep call as memery variable to have ssa form****/ update_stmt(call); mark_symbols_for_renaming(call); } VEC_free (edge, heap, exits); } rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); update_ssa (TODO_update_ssa); verify_flow_info (); verify_dominators (CDI_DOMINATORS); verify_loop_structure (); verify_loop_closed_ssa (); if (dump_file ) fprintf (dump_file,"ssa loop profile \n"); //intsru_argv(); return 0; } ====================================================