This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] [graphite] use debug_printer throughout graphite.
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: hiraditya <hiraditya at msn dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, s dot pop at samsung dot com, Tobias Grosser <tobias at grosser dot es>, aditya dot k7 at samsung dot com, Richard Biener <rguenther at suse dot de>
- Date: Wed, 7 Oct 2015 16:01:30 +0200
- Subject: Re: [PATCH] [graphite] use debug_printer throughout graphite.
- Authentication-results: sourceware.org; auth=none
- References: <1444222501-31106-1-git-send-email-hiraditya at msn dot com>
On Wed, Oct 7, 2015 at 2:55 PM, hiraditya <hiraditya@msn.com> wrote:
> The debug_printer provides an elegant way to represent debug related
> statements, so we are extending its usage throughout graphite infrastructure.
> No functional changes intended. Passes regtest and bootstrap.
But the DEBUG_PRINT macro is super-ugly. I find the existing style
with printfs better as it is what everybody else uses.
So I'd rather kill DEBUG_PRINT and friends...
Richard.
> gcc/ChangeLog:
>
> 2015-10-07 hiraditya <hiraditya@msn.com>
>
> * graphite-isl-ast-to-gimple.c (graphite_regenerate_ast_isl): Use debug_printer.
> * graphite-optimize-isl.c (get_schedule_for_band): Same.
> (optimize_isl): Same.
> * graphite-scop-detection.c (canonicalize_loop_closed_ssa): Rename db to dbgs.
> (scop_detection::merge_sese): Same.
> (scop_detection::build_scop_depth): Same.
> (scop_detection::build_scop_breadth): Same.
> (scop_detection::loop_is_valid_scop): Same.
> (scop_detection::add_scop): Same.
> (scop_detection::harmful_stmt_in_region): Same.
> (scop_detection::remove_subscops): Same.
> (scop_detection::remove_intersecting_scops): Same.
> (stmt_has_side_effects): Same.
> (scop_detection::graphite_can_represent_stmt): Same.
> (scop_detection::stmt_simple_for_scop_p): Same.
> (scop_detection::loop_body_is_valid_scop): Same.
> (build_scops): Same.
> (debug_printer): Move the declaration to sese.h
> * graphite.c (graphite_initialize): Initialize the dump_file for debug_printer.
> (graphite_finalize): Use debug_printer.
> (graphite_transform_loops): Use debug_printer.
> * sese.h: Move the declaration of debug_printer here.
> ---
> gcc/graphite-isl-ast-to-gimple.c | 28 +++++-------
> gcc/graphite-optimize-isl.c | 13 +++---
> gcc/graphite-scop-detection.c | 94 +++++++++++++---------------------------
> gcc/graphite.c | 49 +++++++++------------
> gcc/sese.h | 34 +++++++++++++++
> 5 files changed, 99 insertions(+), 119 deletions(-)
>
> diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c
> index 12e6c61..f986866 100644
> --- a/gcc/graphite-isl-ast-to-gimple.c
> +++ b/gcc/graphite-isl-ast-to-gimple.c
> @@ -1153,12 +1153,9 @@ graphite_regenerate_ast_isl (scop_p scop)
> graphite_regenerate_error = false;
> root_node = scop_to_isl_ast (scop, ip);
>
> - if (dump_file && (dump_flags & TDF_DETAILS))
> - {
> - fprintf (dump_file, "\nISL AST generated by ISL: \n");
> - print_isl_ast_node (dump_file, root_node, scop->isl_context);
> - fprintf (dump_file, "\n");
> - }
> + DEBUG_PRINT (dbgs << "\nISL AST generated by ISL: \n";
> + print_isl_ast_node (dump_file, root_node, scop->isl_context);
> + dbgs << "\n");
>
> recompute_all_dominators ();
> graphite_verify ();
> @@ -1200,18 +1197,13 @@ graphite_regenerate_ast_isl (scop_p scop)
> isl_ast_node_free (root_node);
> timevar_pop (TV_GRAPHITE_CODE_GEN);
>
> - if (dump_file && (dump_flags & TDF_DETAILS))
> - {
> - loop_p loop;
> - int num_no_dependency = 0;
> -
> - FOR_EACH_LOOP (loop, 0)
> - if (loop->can_be_parallel)
> - num_no_dependency++;
> -
> - fprintf (dump_file, "\n%d loops carried no dependency.\n",
> - num_no_dependency);
> - }
> + DEBUG_PRINT (
> + loop_p loop;
> + int num_no_dependency = 0;
> + FOR_EACH_LOOP (loop, 0)
> + if (loop->can_be_parallel)
> + num_no_dependency++;
> + dbgs << num_no_dependency << " loops carried no dependency.\n");
>
> return !graphite_regenerate_error;
> }
> diff --git a/gcc/graphite-optimize-isl.c b/gcc/graphite-optimize-isl.c
> index 2bae417..03ab5e9 100644
> --- a/gcc/graphite-optimize-isl.c
> +++ b/gcc/graphite-optimize-isl.c
> @@ -177,14 +177,12 @@ get_schedule_for_band (isl_band *band, int *dimensions)
> /* It does not make any sense to tile a band with just one dimension. */
> if (*dimensions == 1)
> {
> - if (dump_file && dump_flags)
> - fprintf (dump_file, "not tiled\n");
> + DEBUG_PRINT (dbgs << "not tiled\n");
> return partial_schedule;
> }
>
> - if (dump_file && dump_flags)
> - fprintf (dump_file, "tiled by %d\n",
> - PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE));
> + DEBUG_PRINT (dbgs << "tiled by %d\n"
> + << PARAM_VALUE (PARAM_LOOP_BLOCK_TILE_SIZE));
>
> ctx = isl_union_map_get_ctx (partial_schedule);
> space = isl_union_map_get_space (partial_schedule);
> @@ -348,9 +346,8 @@ optimize_isl (scop_p scop)
> isl_ctx_set_max_operations (scop->isl_context, old_max_operations);
> if (!schedule || isl_ctx_last_error (scop->isl_context) == isl_error_quota)
> {
> - if (dump_file && dump_flags)
> - fprintf (dump_file, "ISL timed out at %d operations\n",
> - max_operations);
> + DEBUG_PRINT (dbgs << "ISL timed out at " << max_operations
> + << " operations\n");
> if (schedule)
> isl_schedule_free (schedule);
> return false;
> diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
> index 700f6d0..675cc14 100644
> --- a/gcc/graphite-scop-detection.c
> +++ b/gcc/graphite-scop-detection.c
> @@ -56,38 +56,7 @@ along with GCC; see the file COPYING3. If not see
> #include "graphite-scop-detection.h"
> #include "gimple-pretty-print.h"
>
> -class debug_printer
> -{
> -private:
> - FILE *dump_file;
> -
> -public:
> - void
> - set_dump_file (FILE *f)
> - {
> - gcc_assert (f);
> - dump_file = f;
> - }
> -
> - friend debug_printer &
> - operator<< (debug_printer &output, int i)
> - {
> - fprintf (output.dump_file, "%d", i);
> - return output;
> - }
> - friend debug_printer &
> - operator<< (debug_printer &output, const char *s)
> - {
> - fprintf (output.dump_file, "%s", s);
> - return output;
> - }
> -} dp;
> -
> -#define DEBUG_PRINT(args) do \
> - { \
> - if (dump_file && (dump_flags & TDF_DETAILS)) { args; } \
> - } while (0);
> -
> +debug_printer dbgs;
>
> /* Return true if BB is empty, contains only DEBUG_INSNs. */
>
> @@ -216,7 +185,7 @@ canonicalize_loop_closed_ssa (loop_p loop)
> if (single_pred_p (bb))
> {
> e = split_block_after_labels (bb);
> - DEBUG_PRINT (dp << "\nSplitting bb_" << bb->index);
> + DEBUG_PRINT (dbgs << "\nSplitting bb_" << bb->index);
> make_close_phi_nodes_unique (e->src);
> }
> else
> @@ -225,7 +194,7 @@ canonicalize_loop_closed_ssa (loop_p loop)
> basic_block close = split_edge (e);
>
> e = single_succ_edge (close);
> - DEBUG_PRINT (dp << "\nSplitting edge (" << e->src->index << ","
> + DEBUG_PRINT (dbgs << "\nSplitting edge (" << e->src->index << ","
> << e->dest->index << ")\n");
>
> for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
> @@ -638,8 +607,8 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
> if (!second)
> return first;
>
> - DEBUG_PRINT (dp << "[try-merging-sese] s1: "; print_sese (dump_file, first);
> - dp << "[try-merging-sese] s2: ";
> + DEBUG_PRINT (dbgs << "[try-merging-sese] s1: "; print_sese (dump_file, first);
> + dbgs << "[try-merging-sese] s2: ";
> print_sese (dump_file, second));
>
> /* Assumption: Both the sese's should be at the same loop depth or one scop
> @@ -682,7 +651,7 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
> || !dominated_by_p (CDI_DOMINATORS, get_exit_bb (combined),
> get_entry_bb (combined)))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] cannot merge seses.\n");
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] cannot merge seses.\n");
> return invalid_sese;
> }
>
> @@ -697,7 +666,7 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
> combined.exit = single_succ_edge (imm_succ);
> else
> {
> - DEBUG_PRINT (dp << "\n[scop-detection-fail] Discarding SCoP because "
> + DEBUG_PRINT (dbgs << "\n[scop-detection-fail] Discarding SCoP because "
> << "no single exit (empty succ) for sese exit";
> print_sese (dump_file, combined));
> return invalid_sese;
> @@ -708,7 +677,7 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
> if (harmful_stmt_in_region (combined))
> return invalid_sese;
>
> - DEBUG_PRINT (dp << "[merged-sese] s1: "; print_sese (dump_file, combined));
> + DEBUG_PRINT (dbgs << "[merged-sese] s1: "; print_sese (dump_file, combined));
>
> return combined;
> }
> @@ -721,7 +690,7 @@ scop_detection::build_scop_depth (sese_l s, loop_p loop)
> if (!loop)
> return s;
>
> - DEBUG_PRINT (dp << "\n[Depth loop_" << loop->num << "]");
> + DEBUG_PRINT (dbgs << "\n[Depth loop_" << loop->num << "]");
> s = build_scop_depth (s, loop->inner);
>
> sese_l s2 = merge_sese (s, get_sese (loop));
> @@ -746,7 +715,7 @@ scop_detection::build_scop_breadth (sese_l s1, loop_p loop)
> {
> if (!loop)
> return s1;
> - DEBUG_PRINT (dp << "\n[Breadth loop_" << loop->num << "]");
> + DEBUG_PRINT (dbgs << "\n[Breadth loop_" << loop->num << "]");
> gcc_assert (s1);
>
> loop_p l = loop;
> @@ -816,14 +785,14 @@ scop_detection::loop_is_valid_scop (loop_p loop, sese_l scop) const
>
> if (!can_represent_loop (loop, scop))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] cannot represent loop_"
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] cannot represent loop_"
> << loop->num << "\n");
> return false;
> }
>
> if (loop_body_is_valid_scop (loop, scop))
> {
> - DEBUG_PRINT (dp << "[valid-scop] loop_" << loop->num
> + DEBUG_PRINT (dbgs << "[valid-scop] loop_" << loop->num
> << "is a valid scop.\n");
> return true;
> }
> @@ -856,14 +825,14 @@ scop_detection::add_scop (sese_l s)
> /* Do not add scops with only one loop. */
> if (region_has_one_loop (s))
> {
> - DEBUG_PRINT (dp << "\n[scop-detection-fail] Discarding one loop SCoP";
> + DEBUG_PRINT (dbgs << "\n[scop-detection-fail] Discarding one loop SCoP";
> print_sese (dump_file, s));
> return;
> }
>
> if (get_exit_bb (s) == EXIT_BLOCK_PTR_FOR_FN (cfun))
> {
> - DEBUG_PRINT (dp << "\n[scop-detection-fail] "
> + DEBUG_PRINT (dbgs << "\n[scop-detection-fail] "
> << "Discarding SCoP exiting to return";
> print_sese (dump_file, s));
> return;
> @@ -876,7 +845,7 @@ scop_detection::add_scop (sese_l s)
> remove_intersecting_scops (s);
>
> scops.safe_push (s);
> - DEBUG_PRINT (dp << "\nAdding SCoP "; print_sese (dump_file, s));
> + DEBUG_PRINT (dbgs << "\nAdding SCoP "; print_sese (dump_file, s));
> }
>
> /* Return true when a statement in SCOP cannot be represented by Graphite.
> @@ -890,7 +859,7 @@ scop_detection::harmful_stmt_in_region (sese_l scop) const
> basic_block exit_bb = get_exit_bb (scop);
> basic_block entry_bb = get_entry_bb (scop);
>
> - DEBUG_PRINT (dp << "\n[checking-harmful-bbs] ";
> + DEBUG_PRINT (dbgs << "\n[checking-harmful-bbs] ";
> print_sese (dump_file, scop));
> gcc_assert (dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb));
>
> @@ -905,7 +874,7 @@ scop_detection::harmful_stmt_in_region (sese_l scop) const
> basic_block bb;
> FOR_EACH_VEC_ELT (dom, i, bb)
> {
> - DEBUG_PRINT (dp << "\nVisiting bb_" << bb->index);
> + DEBUG_PRINT (dbgs << "\nVisiting bb_" << bb->index);
>
> /* We don't want to analyze any bb outside sese. */
> if (!dominated_by_p (CDI_POST_DOMINATORS, bb, exit_bb))
> @@ -940,7 +909,7 @@ scop_detection::remove_subscops (sese_l s1)
> {
> if (subsumes (s1, s2))
> {
> - DEBUG_PRINT (dp << "\nRemoving sub-SCoP";
> + DEBUG_PRINT (dbgs << "\nRemoving sub-SCoP";
> print_sese (dump_file, s2));
> scops.unordered_remove (j);
> }
> @@ -975,8 +944,8 @@ scop_detection::remove_intersecting_scops (sese_l s1)
> {
> if (intersects (s1, s2))
> {
> - DEBUG_PRINT (dp << "\nRemoving intersecting SCoP";
> - print_sese (dump_file, s2); dp << "Intersects with:";
> + DEBUG_PRINT (dbgs << "\nRemoving intersecting SCoP";
> + print_sese (dump_file, s2); dbgs << "Intersects with:";
> print_sese (dump_file, s1));
> scops.unordered_remove (j);
> }
> @@ -1161,7 +1130,7 @@ stmt_has_side_effects (gimple *stmt)
> && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
> || (gimple_code (stmt) == GIMPLE_ASM))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] "
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] "
> << "Statement has side-effects:\n";
> print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
> return true;
> @@ -1195,7 +1164,7 @@ scop_detection::graphite_can_represent_stmt (sese_l scop, gimple *stmt,
> || code == EQ_EXPR
> || code == NE_EXPR))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] "
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] "
> << "Graphite cannot handle cond stmt:\n";
> print_gimple_stmt (dump_file, stmt, 0,
> TDF_VOPS | TDF_MEMSYMS));
> @@ -1209,7 +1178,7 @@ scop_detection::graphite_can_represent_stmt (sese_l scop, gimple *stmt,
> /* We can only constrain on integer type. */
> || (TREE_CODE (TREE_TYPE (op)) != INTEGER_TYPE))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] "
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] "
> << "Graphite cannot represent stmt:\n";
> print_gimple_stmt (dump_file, stmt, 0,
> TDF_VOPS | TDF_MEMSYMS));
> @@ -1227,7 +1196,7 @@ scop_detection::graphite_can_represent_stmt (sese_l scop, gimple *stmt,
> default:
> /* These nodes cut a new scope. */
> DEBUG_PRINT (
> - dp << "[scop-detection-fail] "
> + dbgs << "[scop-detection-fail] "
> << "Gimple stmt not handled in Graphite:\n";
> print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS | TDF_MEMSYMS));
> return false;
> @@ -1254,7 +1223,7 @@ scop_detection::stmt_simple_for_scop_p (sese_l scop, gimple *stmt,
>
> if (!stmt_has_simple_data_refs_p (scop, stmt))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] "
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] "
> << "Graphite cannot handle data-refs in stmt:\n";
> print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS|TDF_MEMSYMS););
> return false;
> @@ -1483,14 +1452,14 @@ scop_detection::loop_body_is_valid_scop (loop_p loop, sese_l scop) const
> {
> if (!loop_ivs_can_be_represented (loop))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] loop_" << loop->num
> << "IV cannot be represented.\n");
> return false;
> }
>
> if (!loop_nest_has_data_refs (loop))
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] loop_" << loop->num
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] loop_" << loop->num
> << "does not have any data reference.\n");
> return false;
> }
> @@ -1868,9 +1837,6 @@ sese_dom_walker::after_dom_children (basic_block bb)
> void
> build_scops (vec<scop_p> *scops)
> {
> - if (dump_file)
> - dp.set_dump_file (dump_file);
> -
> canonicalize_loop_closed_ssa_form ();
>
> scop_detection sb;
> @@ -1889,7 +1855,7 @@ build_scops (vec<scop_p> *scops)
> to any loops. */
> if (sb.nb_pbbs_in_loops (scop) == 0)
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] no data references.\n");
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] no data references.\n");
> free_scop (scop);
> continue;
> }
> @@ -1904,7 +1870,7 @@ build_scops (vec<scop_p> *scops)
>
> if (scop_nb_params (scop) > max_dim)
> {
> - DEBUG_PRINT (dp << "[scop-detection-fail] too many parameters: "
> + DEBUG_PRINT (dbgs << "[scop-detection-fail] too many parameters: "
> << scop_nb_params (scop)
> << " larger than --param graphite-max-nb-scop-params="
> << max_dim << ".\n");
> @@ -1916,7 +1882,7 @@ build_scops (vec<scop_p> *scops)
> scops->safe_push (scop);
> }
>
> - DEBUG_PRINT (dp << "number of SCoPs: " << (scops ? scops->length () : 0););
> + DEBUG_PRINT (dbgs << "number of SCoPs: " << (scops ? scops->length () : 0););
> }
>
> #endif /* HAVE_isl */
> diff --git a/gcc/graphite.c b/gcc/graphite.c
> index 9489f8d..17bdac2 100644
> --- a/gcc/graphite.c
> +++ b/gcc/graphite.c
> @@ -223,20 +223,15 @@ graphite_initialize (isl_ctx *ctx)
> should be removed when the SCOP detection is faster. */
> || (nbbs > max_bbs))
> {
> - if (dump_file && (dump_flags & TDF_DETAILS))
> - {
> - if (nloops <= min_loops)
> - fprintf (dump_file, "\nFunction does not have enough loops: "
> - "PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION = %d.\n",
> - min_loops);
> -
> - else if (nbbs > max_bbs)
> - fprintf (dump_file, "\nFunction has too many basic blocks: "
> - "PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION = %d.\n", max_bbs);
> -
> - fprintf (dump_file, "\nnumber of SCoPs: 0\n");
> - print_global_statistics (dump_file);
> - }
> + DEBUG_PRINT (
> + if (nloops <= min_loops)
> + dbgs << "\nFunction does not have enough loops: "
> + << "PARAM_GRAPHITE_MIN_LOOPS_PER_FUNCTION = " << min_loops << "\n";
> + else if (nbbs > max_bbs)
> + dbgs << "\nFunction has too many basic blocks: "
> + << "PARAM_GRAPHITE_MAX_BBS_PER_FUNCTION = " << max_bbs << "\n";
> + dbgs << "\nnumber of SCoPs: 0\n";
> + print_global_statistics (dump_file));
>
> isl_ctx_free (ctx);
> return false;
> @@ -246,11 +241,8 @@ graphite_initialize (isl_ctx *ctx)
> recompute_all_dominators ();
> initialize_original_copy_tables ();
>
> - if (dump_file && dump_flags)
> - {
> - dump_function_to_file (current_function_decl, dump_file, dump_flags);
> - print_loops (dump_file, 3);
> - }
> + DEBUG_PRINT (dump_function_to_file (current_function_decl, dump_file, dump_flags);
> + print_loops (dump_file, 3));
>
> return true;
> }
> @@ -273,9 +265,7 @@ graphite_finalize (bool need_cfg_cleanup_p)
> }
>
> free_original_copy_tables ();
> -
> - if (dump_file && dump_flags)
> - print_loops (dump_file, 3);
> + DEBUG_PRINT (print_loops (dump_file, 3));
> }
>
> /* Deletes all scops in SCOPS. */
> @@ -293,6 +283,7 @@ free_scops (vec<scop_p> scops)
> }
>
> isl_ctx *the_isl_ctx;
> +extern debug_printer dbgs;
>
> /* Perform a set of linear transforms on the loops of the current
> function. */
> @@ -306,6 +297,10 @@ graphite_transform_loops (void)
> vec<scop_p> scops = vNULL;
> isl_ctx *ctx;
>
> + /* Set the file to put the debug messages. */
> + if (dump_file)
> + dbgs.set_dump_file (dump_file);
> +
> /* If a function is parallel it was most probably already run through graphite
> once. No need to run again. */
> if (parallelized_function_p (cfun->decl))
> @@ -319,11 +314,8 @@ graphite_transform_loops (void)
> the_isl_ctx = ctx;
> build_scops (&scops);
>
> - if (dump_file && (dump_flags & TDF_DETAILS))
> - {
> - print_graphite_statistics (dump_file, scops);
> - print_global_statistics (dump_file);
> - }
> + DEBUG_PRINT (print_graphite_statistics (dump_file, scops);
> + print_global_statistics (dump_file));
>
> FOR_EACH_VEC_ELT (scops, i, scop)
> if (dbg_cnt (graphite_scop))
> @@ -331,8 +323,7 @@ graphite_transform_loops (void)
> scop->isl_context = ctx;
> build_poly_scop (scop);
>
> - if (dump_file && dump_flags)
> - print_scop (dump_file, scop, 3);
> + DEBUG_PRINT (print_scop (dump_file, scop, 3));
>
> if (POLY_SCOP_P (scop)
> && apply_poly_transforms (scop)
> diff --git a/gcc/sese.h b/gcc/sese.h
> index 1478bd8..a32763c 100644
> --- a/gcc/sese.h
> +++ b/gcc/sese.h
> @@ -387,4 +387,38 @@ scev_analyzable_p (tree def, sese_l ®ion)
> || evolution_function_is_affine_p (scev));
> }
>
> +class debug_printer
> +{
> +private:
> + FILE *dump_file;
> +
> +public:
> + void
> + set_dump_file (FILE *f)
> + {
> + gcc_assert (f);
> + dump_file = f;
> + }
> +
> + friend debug_printer &
> + operator<< (debug_printer &output, int i)
> + {
> + fprintf (output.dump_file, "%d", i);
> + return output;
> + }
> + friend debug_printer &
> + operator<< (debug_printer &output, const char *s)
> + {
> + fprintf (output.dump_file, "%s", s);
> + return output;
> + }
> +};
> +
> +extern debug_printer dbgs;
> +
> +#define DEBUG_PRINT(args) do \
> + { \
> + if (dump_file && (dump_flags & TDF_DETAILS)) { args; } \
> + } while (0);
> +
> #endif
> --
> 2.1.4
>