I'm attempting to eliminate global state from the insides of gcc. gcc/tracer.c has various global variables, which are only used during the lifetime of the execute callback of that pass, and cleaned up at the end of each invocation of the pass.
The attached patch introduces a class to hold the state of the pass ("tracer_state"), eliminating these globals. An instance of the state is created on the stack, and all of the various "static" functions in tracer.c that used the globals become member functions of the state. Hence the state is passed around by the implicit "this" of the tracer_state, avoiding the need to patch each individual use of a field within the state, minimizing the diff. Bootstrapped and tested on x86_64-unknown-linux-gnu against r199189, and has the same test results as an unpatched bootstrap of that revision. OK to commit to trunk? 2013-05-21 David Malcolm <dmalc...@redhat.com> * tracer.c (tracer_state): New class (probability_cutoff): Convert global variable to be member data within tracer_state (branch_ratio_cutoff): ditto (bb_seen): ditto (mark_bb_seen): convert to... (tracer_state::mark_bb_seen): ...member function of new tracer_state class (find_best_predecessor): likewise, convert to... (tracer_state::find_best_predecessor): ...this (find_trace): likewise, convert to... (tracer_state::find_trace): ...this (tail_duplicate): likewise, convert to... (tracer_state::tail_duplicate): ...this (tracer): introduce tracer_state instance to move state within the pass from being global to being on the stack
commit a5aea6ce6802fa3d74a8a801cd7809869a63a96a Author: David Malcolm <dmalc...@redhat.com> Date: Wed May 22 06:20:30 2013 -0400 Remove global state from gcc/tracer.c gcc/ * tracer.c (tracer_state): New class (probability_cutoff): Convert global variable to be member data within tracer_state (branch_ratio_cutoff): ditto (bb_seen): ditto (mark_bb_seen): convert to... (tracer_state::mark_bb_seen): ...member function of new tracer_state class (find_best_predecessor): likewise, convert to... (tracer_state::find_best_predecessor): ...this (find_trace): likewise, convert to... (tracer_state::find_trace): ...this (tail_duplicate): likewise, convert to... (tracer_state::tail_duplicate): ...this (tracer): introduce tracer_state instance to move state within the pass from being global to being on the stack diff --git a/gcc/tracer.c b/gcc/tracer.c index 975cadb..977adcb 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -53,20 +53,43 @@ static int count_insns (basic_block); static bool ignore_bb_p (const_basic_block); static bool better_p (const_edge, const_edge); -static edge find_best_successor (basic_block); -static edge find_best_predecessor (basic_block); -static int find_trace (basic_block, basic_block *); -/* Minimal outgoing edge probability considered for superblock formation. */ -static int probability_cutoff; -static int branch_ratio_cutoff; +class tracer_state +{ +public: + tracer_state(); + + bool tail_duplicate (); + +private: + + edge find_best_successor (basic_block); + edge find_best_predecessor (basic_block); + int find_trace (basic_block, basic_block *); + void mark_bb_seen (basic_block bb); + bool bb_seen_p (basic_block bb); + +private: + + /* Minimal outgoing edge probability considered for superblock formation. */ + int probability_cutoff; + int branch_ratio_cutoff; -/* A bit BB->index is set if BB has already been seen, i.e. it is - connected to some trace already. */ -sbitmap bb_seen; + /* A bit BB->index is set if BB has already been seen, i.e. it is + connected to some trace already. */ + sbitmap bb_seen; -static inline void -mark_bb_seen (basic_block bb) +}; // tracer_state + +tracer_state::tracer_state() + : probability_cutoff(0), + branch_ratio_cutoff(0), + bb_seen() +{ +} + +inline void +tracer_state::mark_bb_seen (basic_block bb) { unsigned int size = SBITMAP_SIZE (bb_seen); @@ -76,8 +99,8 @@ mark_bb_seen (basic_block bb) bitmap_set_bit (bb_seen, bb->index); } -static inline bool -bb_seen_p (basic_block bb) +inline bool +tracer_state::bb_seen_p (basic_block bb) { return bitmap_bit_p (bb_seen, bb->index); } @@ -138,8 +161,8 @@ better_p (const_edge e1, const_edge e2) /* Return most frequent successor of basic block BB. */ -static edge -find_best_successor (basic_block bb) +edge +tracer_state::find_best_successor (basic_block bb) { edge e; edge best = NULL; @@ -157,8 +180,8 @@ find_best_successor (basic_block bb) /* Return most frequent predecessor of basic block BB. */ -static edge -find_best_predecessor (basic_block bb) +edge +tracer_state::find_best_predecessor (basic_block bb) { edge e; edge best = NULL; @@ -178,8 +201,8 @@ find_best_predecessor (basic_block bb) /* Find the trace using bb and record it in the TRACE array. Return number of basic blocks recorded. */ -static int -find_trace (basic_block bb, basic_block *trace) +int +tracer_state::find_trace (basic_block bb, basic_block *trace) { int i = 0; edge e; @@ -220,8 +243,8 @@ find_trace (basic_block bb, basic_block *trace) /* Look for basic blocks in frequency order, construct traces and tail duplicate if profitable. */ -static bool -tail_duplicate (void) +bool +tracer_state::tail_duplicate () { fibnode_t *blocks = XCNEWVEC (fibnode_t, last_basic_block); basic_block *trace = XNEWVEC (basic_block, n_basic_blocks); @@ -376,7 +399,8 @@ tracer (void) brief_dump_cfg (dump_file, dump_flags); /* Trace formation is done on the fly inside tail_duplicate */ - changed = tail_duplicate (); + tracer_state state; + changed = state.tail_duplicate (); if (changed) { free_dominance_info (CDI_DOMINATORS);