+2010-02-16 Alexandre Oliva <aoliva@redhat.com>
+
+ * params.def (PARAM_MAX_VARTRACK_SIZE): New.
+ * doc/invoke.texi: Document it.
+ * var-tracking.c: Include toplev.h and params.h.
+ (vt_find_locations): Return bool indicating success. Compute
+ hash sizes unconditionally. Check new parameter, report.
+ (variable_tracking_main_1): Check vt_find_locations results and
+ retry. Renamed from...
+ (variable_tracking_main): ... this. New wrapper to preserve
+ flag_var_tracking_assignments.
+ * Makefile.in (var-tracking.o): Adjust dependencies.
+
2010-02-16 Jack Howarth <howarth@bromo.med.uc.edu>
Jakub Jelinek <jakub@redhat.com>
motion optimization performed on them. The default value of the
parameter is 1000 for -O1 and 10000 for -O2 and above.
+@item max-vartrack-size
+Sets a maximum number of hash table slots to use during variable
+tracking dataflow analysis of any function. If this limit is exceeded
+with variable tracking at assignments enabled, analysis for that
+function is retried without it, after removing all debug insns from
+the function. If the limit is exceeded even without debug insns, var
+tracking analysis is completely disabled for the function. Setting
+the parameter to zero makes it unlimited.
+
@item min-nondebug-insn-uid
Use uids starting at this parameter for nondebug insns. The range below
the parameter is reserved exclusively for debug insns created by
#include "tree-flow.h"
#include "cselib.h"
#include "target.h"
+#include "toplev.h"
+#include "params.h"
/* var-tracking.c assumes that tree code with the same value as VALUE rtx code
has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
static void add_uses_1 (rtx *, void *);
static void add_stores (rtx, const_rtx, void *);
static bool compute_bb_dataflow (basic_block);
-static void vt_find_locations (void);
+static bool vt_find_locations (void);
static void dump_attrs_list (attrs);
static int dump_var_slot (void **, void *);
/* Find the locations of variables in the whole function. */
-static void
+static bool
vt_find_locations (void)
{
fibheap_t worklist, pending, fibheap_swap;
int *rc_order;
int i;
int htabsz = 0;
+ int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
+ bool success = true;
/* Compute reverse completion order of depth first search of the CFG
so that the data-flow runs faster. */
fibheap_insert (pending, bb_order[bb->index], bb);
sbitmap_ones (in_pending);
- while (!fibheap_empty (pending))
+ while (success && !fibheap_empty (pending))
{
fibheap_swap = pending;
pending = worklist;
SET_BIT (visited, bb->index);
- if (dump_file && VTI (bb)->in.vars)
+ if (VTI (bb)->in.vars)
{
htabsz
- -= htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars));
+ -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
+ + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
oldinsz
= htab_elements (shared_hash_htab (VTI (bb)->in.vars));
oldoutsz
}
changed = compute_bb_dataflow (bb);
- if (dump_file)
- htabsz += htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars));
+ htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
+ + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
+
+ if (htabmax && htabsz > htabmax)
+ {
+ if (MAY_HAVE_DEBUG_INSNS)
+ inform (DECL_SOURCE_LOCATION (cfun->decl),
+ "variable tracking size limit exceeded with "
+ "-fvar-tracking-assignments, retrying without");
+ else
+ inform (DECL_SOURCE_LOCATION (cfun->decl),
+ "variable tracking size limit exceeded");
+ success = false;
+ break;
+ }
if (changed)
{
}
}
- if (MAY_HAVE_DEBUG_INSNS)
+ if (success && MAY_HAVE_DEBUG_INSNS)
FOR_EACH_BB (bb)
gcc_assert (VTI (bb)->flooded);
sbitmap_free (visited);
sbitmap_free (in_worklist);
sbitmap_free (in_pending);
+
+ return success;
}
/* Print the content of the LIST to dump file. */
/* The entry point to variable tracking pass. */
-unsigned int
-variable_tracking_main (void)
+static inline unsigned int
+variable_tracking_main_1 (void)
{
+ bool success;
+
if (flag_var_tracking_assignments < 0)
{
delete_debug_insns ();
}
}
- vt_find_locations ();
+ success = vt_find_locations ();
+
+ if (!success && flag_var_tracking_assignments > 0)
+ {
+ vt_finalize ();
+
+ delete_debug_insns ();
+
+ /* This is later restored by our caller. */
+ flag_var_tracking_assignments = 0;
+
+ vt_initialize ();
+
+ if (!frame_pointer_needed && !vt_stack_adjustments ())
+ gcc_unreachable ();
+
+ success = vt_find_locations ();
+ }
+
+ if (!success)
+ {
+ vt_finalize ();
+ vt_debug_insns_local (false);
+ return 0;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
{
vt_debug_insns_local (false);
return 0;
}
+
+unsigned int
+variable_tracking_main (void)
+{
+ unsigned int ret;
+ int save = flag_var_tracking_assignments;
+
+ ret = variable_tracking_main_1 ();
+
+ flag_var_tracking_assignments = save;
+
+ return ret;
+}
\f
static bool
gate_handle_var_tracking (void)