1*e4b17023SJohn Marino /* The tracer pass for the GNU compiler. 2*e4b17023SJohn Marino Contributed by Jan Hubicka, SuSE Labs. 3*e4b17023SJohn Marino Adapted to work on GIMPLE instead of RTL by Robert Kidd, UIUC. 4*e4b17023SJohn Marino Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 5*e4b17023SJohn Marino Free Software Foundation, Inc. 6*e4b17023SJohn Marino 7*e4b17023SJohn Marino This file is part of GCC. 8*e4b17023SJohn Marino 9*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it 10*e4b17023SJohn Marino under the terms of the GNU General Public License as published by 11*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option) 12*e4b17023SJohn Marino any later version. 13*e4b17023SJohn Marino 14*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT 15*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16*e4b17023SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17*e4b17023SJohn Marino License for more details. 18*e4b17023SJohn Marino 19*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 20*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 21*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 22*e4b17023SJohn Marino 23*e4b17023SJohn Marino /* This pass performs the tail duplication needed for superblock formation. 24*e4b17023SJohn Marino For more information see: 25*e4b17023SJohn Marino 26*e4b17023SJohn Marino Design and Analysis of Profile-Based Optimization in Compaq's 27*e4b17023SJohn Marino Compilation Tools for Alpha; Journal of Instruction-Level 28*e4b17023SJohn Marino Parallelism 3 (2000) 1-25 29*e4b17023SJohn Marino 30*e4b17023SJohn Marino Unlike Compaq's implementation we don't do the loop peeling as most 31*e4b17023SJohn Marino probably a better job can be done by a special pass and we don't 32*e4b17023SJohn Marino need to worry too much about the code size implications as the tail 33*e4b17023SJohn Marino duplicates are crossjumped again if optimizations are not 34*e4b17023SJohn Marino performed. */ 35*e4b17023SJohn Marino 36*e4b17023SJohn Marino 37*e4b17023SJohn Marino #include "config.h" 38*e4b17023SJohn Marino #include "system.h" 39*e4b17023SJohn Marino #include "coretypes.h" 40*e4b17023SJohn Marino #include "tm.h" 41*e4b17023SJohn Marino #include "tree.h" 42*e4b17023SJohn Marino #include "rtl.h" 43*e4b17023SJohn Marino #include "hard-reg-set.h" 44*e4b17023SJohn Marino #include "basic-block.h" 45*e4b17023SJohn Marino #include "output.h" 46*e4b17023SJohn Marino #include "cfglayout.h" 47*e4b17023SJohn Marino #include "fibheap.h" 48*e4b17023SJohn Marino #include "flags.h" 49*e4b17023SJohn Marino #include "timevar.h" 50*e4b17023SJohn Marino #include "params.h" 51*e4b17023SJohn Marino #include "coverage.h" 52*e4b17023SJohn Marino #include "tree-pass.h" 53*e4b17023SJohn Marino #include "tree-flow.h" 54*e4b17023SJohn Marino #include "tree-inline.h" 55*e4b17023SJohn Marino 56*e4b17023SJohn Marino static int count_insns (basic_block); 57*e4b17023SJohn Marino static bool ignore_bb_p (const_basic_block); 58*e4b17023SJohn Marino static bool better_p (const_edge, const_edge); 59*e4b17023SJohn Marino static edge find_best_successor (basic_block); 60*e4b17023SJohn Marino static edge find_best_predecessor (basic_block); 61*e4b17023SJohn Marino static int find_trace (basic_block, basic_block *); 62*e4b17023SJohn Marino static void tail_duplicate (void); 63*e4b17023SJohn Marino 64*e4b17023SJohn Marino /* Minimal outgoing edge probability considered for superblock formation. */ 65*e4b17023SJohn Marino static int probability_cutoff; 66*e4b17023SJohn Marino static int branch_ratio_cutoff; 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino /* A bit BB->index is set if BB has already been seen, i.e. it is 69*e4b17023SJohn Marino connected to some trace already. */ 70*e4b17023SJohn Marino sbitmap bb_seen; 71*e4b17023SJohn Marino 72*e4b17023SJohn Marino static inline void 73*e4b17023SJohn Marino mark_bb_seen (basic_block bb) 74*e4b17023SJohn Marino { 75*e4b17023SJohn Marino unsigned int size = SBITMAP_SIZE_BYTES (bb_seen) * 8; 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino if ((unsigned int)bb->index >= size) 78*e4b17023SJohn Marino bb_seen = sbitmap_resize (bb_seen, size * 2, 0); 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino SET_BIT (bb_seen, bb->index); 81*e4b17023SJohn Marino } 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino static inline bool 84*e4b17023SJohn Marino bb_seen_p (basic_block bb) 85*e4b17023SJohn Marino { 86*e4b17023SJohn Marino return TEST_BIT (bb_seen, bb->index); 87*e4b17023SJohn Marino } 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino /* Return true if we should ignore the basic block for purposes of tracing. */ 90*e4b17023SJohn Marino static bool 91*e4b17023SJohn Marino ignore_bb_p (const_basic_block bb) 92*e4b17023SJohn Marino { 93*e4b17023SJohn Marino gimple g; 94*e4b17023SJohn Marino 95*e4b17023SJohn Marino if (bb->index < NUM_FIXED_BLOCKS) 96*e4b17023SJohn Marino return true; 97*e4b17023SJohn Marino if (optimize_bb_for_size_p (bb)) 98*e4b17023SJohn Marino return true; 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino /* A transaction is a single entry multiple exit region. It must be 101*e4b17023SJohn Marino duplicated in its entirety or not at all. */ 102*e4b17023SJohn Marino g = last_stmt (CONST_CAST_BB (bb)); 103*e4b17023SJohn Marino if (g && gimple_code (g) == GIMPLE_TRANSACTION) 104*e4b17023SJohn Marino return true; 105*e4b17023SJohn Marino 106*e4b17023SJohn Marino return false; 107*e4b17023SJohn Marino } 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino /* Return number of instructions in the block. */ 110*e4b17023SJohn Marino 111*e4b17023SJohn Marino static int 112*e4b17023SJohn Marino count_insns (basic_block bb) 113*e4b17023SJohn Marino { 114*e4b17023SJohn Marino gimple_stmt_iterator gsi; 115*e4b17023SJohn Marino gimple stmt; 116*e4b17023SJohn Marino int n = 0; 117*e4b17023SJohn Marino 118*e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 119*e4b17023SJohn Marino { 120*e4b17023SJohn Marino stmt = gsi_stmt (gsi); 121*e4b17023SJohn Marino n += estimate_num_insns (stmt, &eni_size_weights); 122*e4b17023SJohn Marino } 123*e4b17023SJohn Marino return n; 124*e4b17023SJohn Marino } 125*e4b17023SJohn Marino 126*e4b17023SJohn Marino /* Return true if E1 is more frequent than E2. */ 127*e4b17023SJohn Marino static bool 128*e4b17023SJohn Marino better_p (const_edge e1, const_edge e2) 129*e4b17023SJohn Marino { 130*e4b17023SJohn Marino if (e1->count != e2->count) 131*e4b17023SJohn Marino return e1->count > e2->count; 132*e4b17023SJohn Marino if (e1->src->frequency * e1->probability != 133*e4b17023SJohn Marino e2->src->frequency * e2->probability) 134*e4b17023SJohn Marino return (e1->src->frequency * e1->probability 135*e4b17023SJohn Marino > e2->src->frequency * e2->probability); 136*e4b17023SJohn Marino /* This is needed to avoid changes in the decision after 137*e4b17023SJohn Marino CFG is modified. */ 138*e4b17023SJohn Marino if (e1->src != e2->src) 139*e4b17023SJohn Marino return e1->src->index > e2->src->index; 140*e4b17023SJohn Marino return e1->dest->index > e2->dest->index; 141*e4b17023SJohn Marino } 142*e4b17023SJohn Marino 143*e4b17023SJohn Marino /* Return most frequent successor of basic block BB. */ 144*e4b17023SJohn Marino 145*e4b17023SJohn Marino static edge 146*e4b17023SJohn Marino find_best_successor (basic_block bb) 147*e4b17023SJohn Marino { 148*e4b17023SJohn Marino edge e; 149*e4b17023SJohn Marino edge best = NULL; 150*e4b17023SJohn Marino edge_iterator ei; 151*e4b17023SJohn Marino 152*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs) 153*e4b17023SJohn Marino if (!best || better_p (e, best)) 154*e4b17023SJohn Marino best = e; 155*e4b17023SJohn Marino if (!best || ignore_bb_p (best->dest)) 156*e4b17023SJohn Marino return NULL; 157*e4b17023SJohn Marino if (best->probability <= probability_cutoff) 158*e4b17023SJohn Marino return NULL; 159*e4b17023SJohn Marino return best; 160*e4b17023SJohn Marino } 161*e4b17023SJohn Marino 162*e4b17023SJohn Marino /* Return most frequent predecessor of basic block BB. */ 163*e4b17023SJohn Marino 164*e4b17023SJohn Marino static edge 165*e4b17023SJohn Marino find_best_predecessor (basic_block bb) 166*e4b17023SJohn Marino { 167*e4b17023SJohn Marino edge e; 168*e4b17023SJohn Marino edge best = NULL; 169*e4b17023SJohn Marino edge_iterator ei; 170*e4b17023SJohn Marino 171*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds) 172*e4b17023SJohn Marino if (!best || better_p (e, best)) 173*e4b17023SJohn Marino best = e; 174*e4b17023SJohn Marino if (!best || ignore_bb_p (best->src)) 175*e4b17023SJohn Marino return NULL; 176*e4b17023SJohn Marino if (EDGE_FREQUENCY (best) * REG_BR_PROB_BASE 177*e4b17023SJohn Marino < bb->frequency * branch_ratio_cutoff) 178*e4b17023SJohn Marino return NULL; 179*e4b17023SJohn Marino return best; 180*e4b17023SJohn Marino } 181*e4b17023SJohn Marino 182*e4b17023SJohn Marino /* Find the trace using bb and record it in the TRACE array. 183*e4b17023SJohn Marino Return number of basic blocks recorded. */ 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino static int 186*e4b17023SJohn Marino find_trace (basic_block bb, basic_block *trace) 187*e4b17023SJohn Marino { 188*e4b17023SJohn Marino int i = 0; 189*e4b17023SJohn Marino edge e; 190*e4b17023SJohn Marino 191*e4b17023SJohn Marino if (dump_file) 192*e4b17023SJohn Marino fprintf (dump_file, "Trace seed %i [%i]", bb->index, bb->frequency); 193*e4b17023SJohn Marino 194*e4b17023SJohn Marino while ((e = find_best_predecessor (bb)) != NULL) 195*e4b17023SJohn Marino { 196*e4b17023SJohn Marino basic_block bb2 = e->src; 197*e4b17023SJohn Marino if (bb_seen_p (bb2) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) 198*e4b17023SJohn Marino || find_best_successor (bb2) != e) 199*e4b17023SJohn Marino break; 200*e4b17023SJohn Marino if (dump_file) 201*e4b17023SJohn Marino fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency); 202*e4b17023SJohn Marino bb = bb2; 203*e4b17023SJohn Marino } 204*e4b17023SJohn Marino if (dump_file) 205*e4b17023SJohn Marino fprintf (dump_file, " forward %i [%i]", bb->index, bb->frequency); 206*e4b17023SJohn Marino trace[i++] = bb; 207*e4b17023SJohn Marino 208*e4b17023SJohn Marino /* Follow the trace in forward direction. */ 209*e4b17023SJohn Marino while ((e = find_best_successor (bb)) != NULL) 210*e4b17023SJohn Marino { 211*e4b17023SJohn Marino bb = e->dest; 212*e4b17023SJohn Marino if (bb_seen_p (bb) || (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX)) 213*e4b17023SJohn Marino || find_best_predecessor (bb) != e) 214*e4b17023SJohn Marino break; 215*e4b17023SJohn Marino if (dump_file) 216*e4b17023SJohn Marino fprintf (dump_file, ",%i [%i]", bb->index, bb->frequency); 217*e4b17023SJohn Marino trace[i++] = bb; 218*e4b17023SJohn Marino } 219*e4b17023SJohn Marino if (dump_file) 220*e4b17023SJohn Marino fprintf (dump_file, "\n"); 221*e4b17023SJohn Marino return i; 222*e4b17023SJohn Marino } 223*e4b17023SJohn Marino 224*e4b17023SJohn Marino /* Look for basic blocks in frequency order, construct traces and tail duplicate 225*e4b17023SJohn Marino if profitable. */ 226*e4b17023SJohn Marino 227*e4b17023SJohn Marino static void 228*e4b17023SJohn Marino tail_duplicate (void) 229*e4b17023SJohn Marino { 230*e4b17023SJohn Marino fibnode_t *blocks = XCNEWVEC (fibnode_t, last_basic_block); 231*e4b17023SJohn Marino basic_block *trace = XNEWVEC (basic_block, n_basic_blocks); 232*e4b17023SJohn Marino int *counts = XNEWVEC (int, last_basic_block); 233*e4b17023SJohn Marino int ninsns = 0, nduplicated = 0; 234*e4b17023SJohn Marino gcov_type weighted_insns = 0, traced_insns = 0; 235*e4b17023SJohn Marino fibheap_t heap = fibheap_new (); 236*e4b17023SJohn Marino gcov_type cover_insns; 237*e4b17023SJohn Marino int max_dup_insns; 238*e4b17023SJohn Marino basic_block bb; 239*e4b17023SJohn Marino 240*e4b17023SJohn Marino /* Create an oversized sbitmap to reduce the chance that we need to 241*e4b17023SJohn Marino resize it. */ 242*e4b17023SJohn Marino bb_seen = sbitmap_alloc (last_basic_block * 2); 243*e4b17023SJohn Marino sbitmap_zero (bb_seen); 244*e4b17023SJohn Marino initialize_original_copy_tables (); 245*e4b17023SJohn Marino 246*e4b17023SJohn Marino if (profile_info && flag_branch_probabilities) 247*e4b17023SJohn Marino probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK); 248*e4b17023SJohn Marino else 249*e4b17023SJohn Marino probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY); 250*e4b17023SJohn Marino probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff; 251*e4b17023SJohn Marino 252*e4b17023SJohn Marino branch_ratio_cutoff = 253*e4b17023SJohn Marino (REG_BR_PROB_BASE / 100 * PARAM_VALUE (TRACER_MIN_BRANCH_RATIO)); 254*e4b17023SJohn Marino 255*e4b17023SJohn Marino FOR_EACH_BB (bb) 256*e4b17023SJohn Marino { 257*e4b17023SJohn Marino int n = count_insns (bb); 258*e4b17023SJohn Marino if (!ignore_bb_p (bb)) 259*e4b17023SJohn Marino blocks[bb->index] = fibheap_insert (heap, -bb->frequency, 260*e4b17023SJohn Marino bb); 261*e4b17023SJohn Marino 262*e4b17023SJohn Marino counts [bb->index] = n; 263*e4b17023SJohn Marino ninsns += n; 264*e4b17023SJohn Marino weighted_insns += n * bb->frequency; 265*e4b17023SJohn Marino } 266*e4b17023SJohn Marino 267*e4b17023SJohn Marino if (profile_info && flag_branch_probabilities) 268*e4b17023SJohn Marino cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK); 269*e4b17023SJohn Marino else 270*e4b17023SJohn Marino cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE); 271*e4b17023SJohn Marino cover_insns = (weighted_insns * cover_insns + 50) / 100; 272*e4b17023SJohn Marino max_dup_insns = (ninsns * PARAM_VALUE (TRACER_MAX_CODE_GROWTH) + 50) / 100; 273*e4b17023SJohn Marino 274*e4b17023SJohn Marino while (traced_insns < cover_insns && nduplicated < max_dup_insns 275*e4b17023SJohn Marino && !fibheap_empty (heap)) 276*e4b17023SJohn Marino { 277*e4b17023SJohn Marino basic_block bb = (basic_block) fibheap_extract_min (heap); 278*e4b17023SJohn Marino int n, pos; 279*e4b17023SJohn Marino 280*e4b17023SJohn Marino if (!bb) 281*e4b17023SJohn Marino break; 282*e4b17023SJohn Marino 283*e4b17023SJohn Marino blocks[bb->index] = NULL; 284*e4b17023SJohn Marino 285*e4b17023SJohn Marino if (ignore_bb_p (bb)) 286*e4b17023SJohn Marino continue; 287*e4b17023SJohn Marino gcc_assert (!bb_seen_p (bb)); 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino n = find_trace (bb, trace); 290*e4b17023SJohn Marino 291*e4b17023SJohn Marino bb = trace[0]; 292*e4b17023SJohn Marino traced_insns += bb->frequency * counts [bb->index]; 293*e4b17023SJohn Marino if (blocks[bb->index]) 294*e4b17023SJohn Marino { 295*e4b17023SJohn Marino fibheap_delete_node (heap, blocks[bb->index]); 296*e4b17023SJohn Marino blocks[bb->index] = NULL; 297*e4b17023SJohn Marino } 298*e4b17023SJohn Marino 299*e4b17023SJohn Marino for (pos = 1; pos < n; pos++) 300*e4b17023SJohn Marino { 301*e4b17023SJohn Marino basic_block bb2 = trace[pos]; 302*e4b17023SJohn Marino 303*e4b17023SJohn Marino if (blocks[bb2->index]) 304*e4b17023SJohn Marino { 305*e4b17023SJohn Marino fibheap_delete_node (heap, blocks[bb2->index]); 306*e4b17023SJohn Marino blocks[bb2->index] = NULL; 307*e4b17023SJohn Marino } 308*e4b17023SJohn Marino traced_insns += bb2->frequency * counts [bb2->index]; 309*e4b17023SJohn Marino if (EDGE_COUNT (bb2->preds) > 1 310*e4b17023SJohn Marino && can_duplicate_block_p (bb2)) 311*e4b17023SJohn Marino { 312*e4b17023SJohn Marino edge e; 313*e4b17023SJohn Marino basic_block copy; 314*e4b17023SJohn Marino 315*e4b17023SJohn Marino nduplicated += counts [bb2->index]; 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino e = find_edge (bb, bb2); 318*e4b17023SJohn Marino 319*e4b17023SJohn Marino copy = duplicate_block (bb2, e, bb); 320*e4b17023SJohn Marino flush_pending_stmts (e); 321*e4b17023SJohn Marino 322*e4b17023SJohn Marino add_phi_args_after_copy (©, 1, NULL); 323*e4b17023SJohn Marino 324*e4b17023SJohn Marino /* Reconsider the original copy of block we've duplicated. 325*e4b17023SJohn Marino Removing the most common predecessor may make it to be 326*e4b17023SJohn Marino head. */ 327*e4b17023SJohn Marino blocks[bb2->index] = 328*e4b17023SJohn Marino fibheap_insert (heap, -bb2->frequency, bb2); 329*e4b17023SJohn Marino 330*e4b17023SJohn Marino if (dump_file) 331*e4b17023SJohn Marino fprintf (dump_file, "Duplicated %i as %i [%i]\n", 332*e4b17023SJohn Marino bb2->index, copy->index, copy->frequency); 333*e4b17023SJohn Marino 334*e4b17023SJohn Marino bb2 = copy; 335*e4b17023SJohn Marino } 336*e4b17023SJohn Marino mark_bb_seen (bb2); 337*e4b17023SJohn Marino bb = bb2; 338*e4b17023SJohn Marino /* In case the trace became infrequent, stop duplicating. */ 339*e4b17023SJohn Marino if (ignore_bb_p (bb)) 340*e4b17023SJohn Marino break; 341*e4b17023SJohn Marino } 342*e4b17023SJohn Marino if (dump_file) 343*e4b17023SJohn Marino fprintf (dump_file, " covered now %.1f\n\n", 344*e4b17023SJohn Marino traced_insns * 100.0 / weighted_insns); 345*e4b17023SJohn Marino } 346*e4b17023SJohn Marino if (dump_file) 347*e4b17023SJohn Marino fprintf (dump_file, "Duplicated %i insns (%i%%)\n", nduplicated, 348*e4b17023SJohn Marino nduplicated * 100 / ninsns); 349*e4b17023SJohn Marino 350*e4b17023SJohn Marino free_original_copy_tables (); 351*e4b17023SJohn Marino sbitmap_free (bb_seen); 352*e4b17023SJohn Marino free (blocks); 353*e4b17023SJohn Marino free (trace); 354*e4b17023SJohn Marino free (counts); 355*e4b17023SJohn Marino fibheap_delete (heap); 356*e4b17023SJohn Marino } 357*e4b17023SJohn Marino 358*e4b17023SJohn Marino /* Main entry point to this file. */ 359*e4b17023SJohn Marino 360*e4b17023SJohn Marino static unsigned int 361*e4b17023SJohn Marino tracer (void) 362*e4b17023SJohn Marino { 363*e4b17023SJohn Marino gcc_assert (current_ir_type () == IR_GIMPLE); 364*e4b17023SJohn Marino 365*e4b17023SJohn Marino if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1) 366*e4b17023SJohn Marino return 0; 367*e4b17023SJohn Marino 368*e4b17023SJohn Marino mark_dfs_back_edges (); 369*e4b17023SJohn Marino if (dump_file) 370*e4b17023SJohn Marino dump_flow_info (dump_file, dump_flags); 371*e4b17023SJohn Marino 372*e4b17023SJohn Marino /* Trace formation is done on the fly inside tail_duplicate */ 373*e4b17023SJohn Marino tail_duplicate (); 374*e4b17023SJohn Marino 375*e4b17023SJohn Marino /* FIXME: We really only need to do this when we know tail duplication 376*e4b17023SJohn Marino has altered the CFG. */ 377*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 378*e4b17023SJohn Marino if (dump_file) 379*e4b17023SJohn Marino dump_flow_info (dump_file, dump_flags); 380*e4b17023SJohn Marino 381*e4b17023SJohn Marino return 0; 382*e4b17023SJohn Marino } 383*e4b17023SJohn Marino 384*e4b17023SJohn Marino static bool 385*e4b17023SJohn Marino gate_tracer (void) 386*e4b17023SJohn Marino { 387*e4b17023SJohn Marino return (optimize > 0 && flag_tracer && flag_reorder_blocks); 388*e4b17023SJohn Marino } 389*e4b17023SJohn Marino 390*e4b17023SJohn Marino struct gimple_opt_pass pass_tracer = 391*e4b17023SJohn Marino { 392*e4b17023SJohn Marino { 393*e4b17023SJohn Marino GIMPLE_PASS, 394*e4b17023SJohn Marino "tracer", /* name */ 395*e4b17023SJohn Marino gate_tracer, /* gate */ 396*e4b17023SJohn Marino tracer, /* execute */ 397*e4b17023SJohn Marino NULL, /* sub */ 398*e4b17023SJohn Marino NULL, /* next */ 399*e4b17023SJohn Marino 0, /* static_pass_number */ 400*e4b17023SJohn Marino TV_TRACER, /* tv_id */ 401*e4b17023SJohn Marino 0, /* properties_required */ 402*e4b17023SJohn Marino 0, /* properties_provided */ 403*e4b17023SJohn Marino 0, /* properties_destroyed */ 404*e4b17023SJohn Marino 0, /* todo_flags_start */ 405*e4b17023SJohn Marino TODO_update_ssa 406*e4b17023SJohn Marino | TODO_verify_ssa /* todo_flags_finish */ 407*e4b17023SJohn Marino } 408*e4b17023SJohn Marino }; 409