Retro68/gcc/gcc/tree-ssa-loop.cc

742 lines
16 KiB
C++
Raw Normal View History

2012-03-27 23:13:14 +00:00
/* Loop optimizations over tree-ssa.
Copyright (C) 2003-2022 Free Software Foundation, Inc.
2012-03-27 23:13:14 +00:00
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
2017-04-10 11:32:00 +00:00
#include "backend.h"
2012-03-27 23:13:14 +00:00
#include "tree.h"
2014-09-21 17:33:12 +00:00
#include "gimple.h"
2017-04-10 11:32:00 +00:00
#include "tree-pass.h"
#include "memmodel.h"
2017-04-10 11:32:00 +00:00
#include "tm_p.h"
#include "fold-const.h"
2014-09-21 17:33:12 +00:00
#include "gimple-iterator.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-manip.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
2012-03-27 23:13:14 +00:00
#include "cfgloop.h"
#include "tree-inline.h"
#include "tree-scalar-evolution.h"
#include "tree-vectorizer.h"
#include "omp-general.h"
2017-04-10 11:32:00 +00:00
#include "diagnostic-core.h"
2018-12-28 15:30:48 +00:00
#include "stringpool.h"
#include "attribs.h"
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
/* A pass making sure loops are fixed up. */
namespace {
const pass_data pass_data_fix_loops =
{
GIMPLE_PASS, /* type */
"fix_loops", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_fix_loops : public gimple_opt_pass
{
public:
pass_fix_loops (gcc::context *ctxt)
: gimple_opt_pass (pass_data_fix_loops, ctxt)
{}
/* opt_pass methods: */
virtual bool gate (function *) { return flag_tree_loop_optimize; }
virtual unsigned int execute (function *fn);
}; // class pass_fix_loops
unsigned int
pass_fix_loops::execute (function *)
{
if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
{
calculate_dominance_info (CDI_DOMINATORS);
fix_loop_structure (NULL);
}
return 0;
}
} // anon namespace
gimple_opt_pass *
make_pass_fix_loops (gcc::context *ctxt)
{
return new pass_fix_loops (ctxt);
}
/* Gate for loop pass group. The group is controlled by -ftree-loop-optimize
but we also avoid running it when the IL doesn't contain any loop. */
2012-03-27 23:13:14 +00:00
static bool
2015-08-28 15:33:40 +00:00
gate_loop (function *fn)
2012-03-27 23:13:14 +00:00
{
2015-08-28 15:33:40 +00:00
if (!flag_tree_loop_optimize)
return false;
/* For -fdump-passes which runs before loop discovery print the
state of -ftree-loop-optimize. */
if (!loops_for_fn (fn))
return true;
return number_of_loops (fn) > 1;
2012-03-27 23:13:14 +00:00
}
2015-08-28 15:33:40 +00:00
/* The loop superpass. */
2014-09-21 17:33:12 +00:00
namespace {
const pass_data pass_data_tree_loop =
{
GIMPLE_PASS, /* type */
"loop", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
2015-08-28 15:33:40 +00:00
0, /* todo_flags_finish */
2012-03-27 23:13:14 +00:00
};
2014-09-21 17:33:12 +00:00
class pass_tree_loop : public gimple_opt_pass
{
public:
pass_tree_loop (gcc::context *ctxt)
: gimple_opt_pass (pass_data_tree_loop, ctxt)
{}
/* opt_pass methods: */
2015-08-28 15:33:40 +00:00
virtual bool gate (function *fn) { return gate_loop (fn); }
2014-09-21 17:33:12 +00:00
}; // class pass_tree_loop
} // anon namespace
gimple_opt_pass *
make_pass_tree_loop (gcc::context *ctxt)
{
return new pass_tree_loop (ctxt);
}
2017-04-10 11:32:00 +00:00
/* Gate for oacc kernels pass group. */
static bool
gate_oacc_kernels (function *fn)
{
if (!flag_openacc)
return false;
2018-12-28 15:30:48 +00:00
if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
2017-04-10 11:32:00 +00:00
return false;
for (auto loop : loops_list (cfun, 0))
2017-04-10 11:32:00 +00:00
if (loop->in_oacc_kernels_region)
return true;
return false;
}
/* The oacc kernels superpass. */
namespace {
const pass_data pass_data_oacc_kernels =
{
GIMPLE_PASS, /* type */
"oacc_kernels", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_oacc_kernels : public gimple_opt_pass
{
public:
pass_oacc_kernels (gcc::context *ctxt)
: gimple_opt_pass (pass_data_oacc_kernels, ctxt)
{}
/* opt_pass methods: */
virtual bool gate (function *fn) { return gate_oacc_kernels (fn); }
}; // class pass_oacc_kernels
} // anon namespace
gimple_opt_pass *
make_pass_oacc_kernels (gcc::context *ctxt)
{
return new pass_oacc_kernels (ctxt);
}
/* The ipa oacc superpass. */
namespace {
const pass_data pass_data_ipa_oacc =
{
SIMPLE_IPA_PASS, /* type */
"ipa_oacc", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_ipa_oacc : public simple_ipa_opt_pass
{
public:
pass_ipa_oacc (gcc::context *ctxt)
: simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
{}
/* opt_pass methods: */
virtual bool gate (function *)
{
return (optimize
&& flag_openacc
/* Don't bother doing anything if the program has errors. */
&& !seen_error ());
}
}; // class pass_ipa_oacc
} // anon namespace
simple_ipa_opt_pass *
make_pass_ipa_oacc (gcc::context *ctxt)
{
return new pass_ipa_oacc (ctxt);
}
/* The ipa oacc kernels pass. */
namespace {
const pass_data pass_data_ipa_oacc_kernels =
{
SIMPLE_IPA_PASS, /* type */
"ipa_oacc_kernels", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
{
public:
pass_ipa_oacc_kernels (gcc::context *ctxt)
: simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
{}
}; // class pass_ipa_oacc_kernels
} // anon namespace
simple_ipa_opt_pass *
make_pass_ipa_oacc_kernels (gcc::context *ctxt)
{
return new pass_ipa_oacc_kernels (ctxt);
}
2015-08-28 15:33:40 +00:00
/* The no-loop superpass. */
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
namespace {
const pass_data pass_data_tree_no_loop =
2012-03-27 23:13:14 +00:00
{
2015-08-28 15:33:40 +00:00
GIMPLE_PASS, /* type */
"no_loop", /* name */
OPTGROUP_NONE, /* optinfo_flags */
TV_TREE_NOLOOP, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
class pass_tree_no_loop : public gimple_opt_pass
{
public:
pass_tree_no_loop (gcc::context *ctxt)
: gimple_opt_pass (pass_data_tree_no_loop, ctxt)
{}
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
/* opt_pass methods: */
virtual bool gate (function *fn) { return !gate_loop (fn); }
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
}; // class pass_tree_no_loop
} // anon namespace
gimple_opt_pass *
make_pass_tree_no_loop (gcc::context *ctxt)
{
return new pass_tree_no_loop (ctxt);
2012-03-27 23:13:14 +00:00
}
2015-08-28 15:33:40 +00:00
/* Loop optimizer initialization. */
2014-09-21 17:33:12 +00:00
namespace {
const pass_data pass_data_tree_loop_init =
{
GIMPLE_PASS, /* type */
"loopinit", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_NONE, /* tv_id */
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
TODO_update_address_taken, /* todo_flags_start */
2014-09-21 17:33:12 +00:00
0, /* todo_flags_finish */
2012-03-27 23:13:14 +00:00
};
2014-09-21 17:33:12 +00:00
class pass_tree_loop_init : public gimple_opt_pass
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
public:
pass_tree_loop_init (gcc::context *ctxt)
: gimple_opt_pass (pass_data_tree_loop_init, ctxt)
{}
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
/* opt_pass methods: */
2015-08-28 15:33:40 +00:00
virtual unsigned int execute (function *);
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
}; // class pass_tree_loop_init
2012-03-27 23:13:14 +00:00
2015-08-28 15:33:40 +00:00
unsigned int
pass_tree_loop_init::execute (function *fun ATTRIBUTE_UNUSED)
{
2017-04-10 11:32:00 +00:00
/* When processing a loop in the loop pipeline, we should be able to assert
that:
(loops_state_satisfies_p (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS
| LOOP_CLOSED_SSA)
&& scev_initialized_p ())
*/
2015-08-28 15:33:40 +00:00
loop_optimizer_init (LOOPS_NORMAL
| LOOPS_HAVE_RECORDED_EXITS);
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
scev_initialize ();
return 0;
}
2014-09-21 17:33:12 +00:00
} // anon namespace
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
gimple_opt_pass *
make_pass_tree_loop_init (gcc::context *ctxt)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
return new pass_tree_loop_init (ctxt);
2012-03-27 23:13:14 +00:00
}
/* Propagation of constants using scev. */
2014-09-21 17:33:12 +00:00
namespace {
const pass_data pass_data_scev_cprop =
{
GIMPLE_PASS, /* type */
"sccp", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_SCEV_CONST, /* tv_id */
( PROP_cfg | PROP_ssa ), /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
2019-06-02 15:48:37 +00:00
0, /* todo_flags_finish */
2012-03-27 23:13:14 +00:00
};
2014-09-21 17:33:12 +00:00
class pass_scev_cprop : public gimple_opt_pass
{
public:
pass_scev_cprop (gcc::context *ctxt)
: gimple_opt_pass (pass_data_scev_cprop, ctxt)
{}
/* opt_pass methods: */
2015-08-28 15:33:40 +00:00
virtual bool gate (function *) { return flag_tree_scev_cprop; }
2019-06-02 15:48:37 +00:00
virtual unsigned int execute (function *);
2014-09-21 17:33:12 +00:00
}; // class pass_scev_cprop
2019-06-02 15:48:37 +00:00
unsigned
pass_scev_cprop::execute (function *)
{
bool any = false;
/* Perform final value replacement in loops, in case the replacement
expressions are cheap. */
for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
2019-06-02 15:48:37 +00:00
any |= final_value_replacement_loop (loop);
return any ? TODO_cleanup_cfg | TODO_update_ssa_only_virtuals : 0;
}
2014-09-21 17:33:12 +00:00
} // anon namespace
gimple_opt_pass *
make_pass_scev_cprop (gcc::context *ctxt)
{
return new pass_scev_cprop (ctxt);
}
/* Induction variable optimizations. */
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
namespace {
const pass_data pass_data_iv_optimize =
{
GIMPLE_PASS, /* type */
"ivopts", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_TREE_LOOP_IVOPTS, /* tv_id */
( PROP_cfg | PROP_ssa ), /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_update_ssa, /* todo_flags_finish */
2012-03-27 23:13:14 +00:00
};
2014-09-21 17:33:12 +00:00
class pass_iv_optimize : public gimple_opt_pass
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
public:
pass_iv_optimize (gcc::context *ctxt)
: gimple_opt_pass (pass_data_iv_optimize, ctxt)
{}
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
/* opt_pass methods: */
2015-08-28 15:33:40 +00:00
virtual bool gate (function *) { return flag_ivopts != 0; }
virtual unsigned int execute (function *);
2014-09-21 17:33:12 +00:00
}; // class pass_iv_optimize
2015-08-28 15:33:40 +00:00
unsigned int
pass_iv_optimize::execute (function *fun)
{
if (number_of_loops (fun) <= 1)
return 0;
tree_ssa_iv_optimize ();
return 0;
}
2014-09-21 17:33:12 +00:00
} // anon namespace
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
gimple_opt_pass *
make_pass_iv_optimize (gcc::context *ctxt)
{
return new pass_iv_optimize (ctxt);
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
/* Loop optimizer finalization. */
static unsigned int
tree_ssa_loop_done (void)
2012-03-27 23:13:14 +00:00
{
2017-04-10 11:32:00 +00:00
free_numbers_of_iterations_estimates (cfun);
2014-09-21 17:33:12 +00:00
scev_finalize ();
loop_optimizer_finalize (cfun, true);
2014-09-21 17:33:12 +00:00
return 0;
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
namespace {
const pass_data pass_data_tree_loop_done =
{
GIMPLE_PASS, /* type */
"loopdone", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_NONE, /* tv_id */
PROP_cfg, /* properties_required */
PROP_loop_opts_done, /* properties_provided */
2014-09-21 17:33:12 +00:00
0, /* properties_destroyed */
0, /* todo_flags_start */
2015-08-28 15:33:40 +00:00
TODO_cleanup_cfg, /* todo_flags_finish */
2012-03-27 23:13:14 +00:00
};
2014-09-21 17:33:12 +00:00
class pass_tree_loop_done : public gimple_opt_pass
{
public:
pass_tree_loop_done (gcc::context *ctxt)
: gimple_opt_pass (pass_data_tree_loop_done, ctxt)
{}
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
/* opt_pass methods: */
2015-08-28 15:33:40 +00:00
virtual unsigned int execute (function *) { return tree_ssa_loop_done (); }
2014-09-21 17:33:12 +00:00
}; // class pass_tree_loop_done
} // anon namespace
gimple_opt_pass *
make_pass_tree_loop_done (gcc::context *ctxt)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
return new pass_tree_loop_done (ctxt);
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
/* Calls CBCK for each index in memory reference ADDR_P. There are two
kinds situations handled; in each of these cases, the memory reference
and DATA are passed to the callback:
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
Access to an array: ARRAY_{RANGE_}REF (base, index). In this case we also
pass the pointer to the index to the callback.
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
Pointer dereference: INDIRECT_REF (addr). In this case we also pass the
pointer to addr to the callback.
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
If the callback returns false, the whole search stops and false is returned.
Otherwise the function returns true after traversing through the whole
reference *ADDR_P. */
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
bool
for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
tree *nxt, *idx;
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
for (; ; addr_p = nxt)
{
switch (TREE_CODE (*addr_p))
{
case SSA_NAME:
return cbck (*addr_p, addr_p, data);
case MEM_REF:
nxt = &TREE_OPERAND (*addr_p, 0);
return cbck (*addr_p, nxt, data);
case BIT_FIELD_REF:
case VIEW_CONVERT_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
nxt = &TREE_OPERAND (*addr_p, 0);
break;
case COMPONENT_REF:
/* If the component has varying offset, it behaves like index
as well. */
idx = &TREE_OPERAND (*addr_p, 2);
if (*idx
&& !cbck (*addr_p, idx, data))
return false;
nxt = &TREE_OPERAND (*addr_p, 0);
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
nxt = &TREE_OPERAND (*addr_p, 0);
if (!cbck (*addr_p, &TREE_OPERAND (*addr_p, 1), data))
return false;
break;
case CONSTRUCTOR:
return true;
case ADDR_EXPR:
gcc_assert (is_gimple_min_invariant (*addr_p));
return true;
case TARGET_MEM_REF:
idx = &TMR_BASE (*addr_p);
if (*idx
&& !cbck (*addr_p, idx, data))
return false;
idx = &TMR_INDEX (*addr_p);
if (*idx
&& !cbck (*addr_p, idx, data))
return false;
idx = &TMR_INDEX2 (*addr_p);
if (*idx
&& !cbck (*addr_p, idx, data))
return false;
return true;
default:
2019-06-02 15:48:37 +00:00
if (DECL_P (*addr_p)
|| CONSTANT_CLASS_P (*addr_p))
return true;
2014-09-21 17:33:12 +00:00
gcc_unreachable ();
}
}
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
/* The name and the length of the currently generated variable
for lsm. */
#define MAX_LSM_NAME_LENGTH 40
static char lsm_tmp_name[MAX_LSM_NAME_LENGTH + 1];
static int lsm_tmp_name_length;
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
/* Adds S to lsm_tmp_name. */
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
static void
lsm_tmp_name_add (const char *s)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
int l = strlen (s) + lsm_tmp_name_length;
if (l > MAX_LSM_NAME_LENGTH)
return;
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
strcpy (lsm_tmp_name + lsm_tmp_name_length, s);
lsm_tmp_name_length = l;
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
/* Stores the name for temporary variable that replaces REF to
lsm_tmp_name. */
static void
gen_lsm_tmp_name (tree ref)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
const char *name;
switch (TREE_CODE (ref))
{
case MEM_REF:
case TARGET_MEM_REF:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
lsm_tmp_name_add ("_");
break;
case ADDR_EXPR:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
break;
case BIT_FIELD_REF:
case VIEW_CONVERT_EXPR:
case ARRAY_RANGE_REF:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
break;
case REALPART_EXPR:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
lsm_tmp_name_add ("_RE");
break;
case IMAGPART_EXPR:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
lsm_tmp_name_add ("_IM");
break;
case COMPONENT_REF:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
lsm_tmp_name_add ("_");
name = get_name (TREE_OPERAND (ref, 1));
if (!name)
name = "F";
lsm_tmp_name_add (name);
break;
case ARRAY_REF:
gen_lsm_tmp_name (TREE_OPERAND (ref, 0));
lsm_tmp_name_add ("_I");
break;
case SSA_NAME:
case VAR_DECL:
case PARM_DECL:
2017-04-10 11:32:00 +00:00
case FUNCTION_DECL:
case LABEL_DECL:
2014-09-21 17:33:12 +00:00
name = get_name (ref);
if (!name)
name = "D";
lsm_tmp_name_add (name);
break;
case STRING_CST:
lsm_tmp_name_add ("S");
break;
case RESULT_DECL:
lsm_tmp_name_add ("R");
break;
case INTEGER_CST:
2017-04-10 11:32:00 +00:00
default:
2014-09-21 17:33:12 +00:00
/* Nothing. */
break;
}
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00
/* Determines name for temporary variable that replaces REF.
The name is accumulated into the lsm_tmp_name variable.
N is added to the name of the temporary. */
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
char *
get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
{
char ns[2];
2012-03-27 23:13:14 +00:00
2014-09-21 17:33:12 +00:00
lsm_tmp_name_length = 0;
gen_lsm_tmp_name (ref);
lsm_tmp_name_add ("_lsm");
if (n < 10)
{
ns[0] = '0' + n;
ns[1] = 0;
lsm_tmp_name_add (ns);
}
if (suffix != NULL)
lsm_tmp_name_add (suffix);
return lsm_tmp_name;
2014-09-21 17:33:12 +00:00
}
/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
unsigned
tree_num_loop_insns (class loop *loop, eni_weights *weights)
2012-03-27 23:13:14 +00:00
{
2014-09-21 17:33:12 +00:00
basic_block *body = get_loop_body (loop);
gimple_stmt_iterator gsi;
unsigned size = 0, i;
for (i = 0; i < loop->num_nodes; i++)
for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
size += estimate_num_insns (gsi_stmt (gsi), weights);
free (body);
return size;
2012-03-27 23:13:14 +00:00
}
2014-09-21 17:33:12 +00:00