Commit aaa57c69 by Oleg Endo

re PR target/53976 ([SH] Unnecessary clrt/sett after bt/bf)

	PR target/53976
	PR target/59243
	* config/sh/sh_optimize_sett_clrt.cc (struct ccreg_value): Update
	comments.
	(sh_optimize_sett_clrt::find_last_ccreg_values): Check stack of
	previously visited basic blocks before recursing instead of only one
	basic block.

From-SVN: r205358
parent 1b7b698a
2013-11-25 Oleg Endo <olegendo@gcc.gnu.org>
PR target/53976
PR target/59243
* config/sh/sh_optimize_sett_clrt.cc (struct ccreg_value): Update
comments.
(sh_optimize_sett_clrt::find_last_ccreg_values): Check stack of
previously visited basic blocks before recursing instead of only one
basic block.
2013-11-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2013-11-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.c (cortexa53_tuning): New struct. * config/aarch64/aarch64.c (cortexa53_tuning): New struct.
...@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h" #include "target.h"
#include <vector> #include <vector>
#include <algorithm>
/* /*
This pass tries to eliminate unnecessary sett or clrt instructions in cases This pass tries to eliminate unnecessary sett or clrt instructions in cases
...@@ -87,16 +88,15 @@ private: ...@@ -87,16 +88,15 @@ private:
struct ccreg_value struct ccreg_value
{ {
// The insn at which the ccreg value was determined. // The insn at which the ccreg value was determined.
// Might be NULL_RTX if e.g. an unknown value is recorded for an
// empty basic block.
rtx insn; rtx insn;
// The basic block where the insn was discovered. // The basic block where the insn was discovered.
// Notice that the CFG might be invalid at late RTL stages and
// BLOCK_FOR_INSN might return null. Thus the basic block are recorded
// here while traversing them.
basic_block bb; basic_block bb;
// The value of ccreg. If NULL_RTX, the value is not known, e.g. if the // The value of ccreg. If NULL_RTX, the exact value is not known, but
// ccreg is clobbered. // the ccreg is changed in some way (e.g. clobbered).
rtx value; rtx value;
}; };
...@@ -113,7 +113,7 @@ private: ...@@ -113,7 +113,7 @@ private:
// start insn. // start insn.
void find_last_ccreg_values (rtx start_insn, basic_block bb, void find_last_ccreg_values (rtx start_insn, basic_block bb,
std::vector<ccreg_value>& values_out, std::vector<ccreg_value>& values_out,
basic_block prev_visited_bb = NULL) const; std::vector<basic_block>& prev_visited_bb) const;
// Given a cbranch insn, its basic block and another basic block, determine // Given a cbranch insn, its basic block and another basic block, determine
// the value to which the ccreg will be set after jumping/falling through to // the value to which the ccreg will be set after jumping/falling through to
...@@ -199,6 +199,10 @@ sh_optimize_sett_clrt::execute (void) ...@@ -199,6 +199,10 @@ sh_optimize_sett_clrt::execute (void)
std::vector<ccreg_value> ccreg_values; std::vector<ccreg_value> ccreg_values;
ccreg_values.reserve (32); ccreg_values.reserve (32);
// Something for recording visited basic blocks to avoid infinite recursion.
std::vector<basic_block> visited_bbs;
visited_bbs.reserve (32);
// Look for insns that set the ccreg to a constant value and see if it can // Look for insns that set the ccreg to a constant value and see if it can
// be optimized. // be optimized.
basic_block bb; basic_block bb;
...@@ -221,7 +225,9 @@ sh_optimize_sett_clrt::execute (void) ...@@ -221,7 +225,9 @@ sh_optimize_sett_clrt::execute (void)
log_msg ("\n"); log_msg ("\n");
ccreg_values.clear (); ccreg_values.clear ();
find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values); visited_bbs.clear ();
find_last_ccreg_values (PREV_INSN (i), bb, ccreg_values,
visited_bbs);
log_msg ("number of ccreg values collected: %u\n", log_msg ("number of ccreg values collected: %u\n",
(unsigned int)ccreg_values.size ()); (unsigned int)ccreg_values.size ());
...@@ -307,12 +313,16 @@ void ...@@ -307,12 +313,16 @@ void
sh_optimize_sett_clrt sh_optimize_sett_clrt
::find_last_ccreg_values (rtx start_insn, basic_block bb, ::find_last_ccreg_values (rtx start_insn, basic_block bb,
std::vector<ccreg_value>& values_out, std::vector<ccreg_value>& values_out,
basic_block prev_visited_bb) const std::vector<basic_block>& prev_visited_bb) const
{ {
if (start_insn == NULL_RTX) // FIXME: For larger CFGs this will unnecessarily re-visit basic blocks.
return; // Once a basic block has been visited, the result should be stored in
// some container so that it can be looked up quickly eliminating the
log_msg ("looking for ccreg values in [bb %d]\n", bb->index); // re-visits.
log_msg ("looking for ccreg values in [bb %d] ", bb->index);
if (!prev_visited_bb.empty ())
log_msg ("(prev visited [bb %d])", prev_visited_bb.back ()->index);
log_msg ("\n");
for (rtx i = start_insn; i != NULL_RTX && i != PREV_INSN (BB_HEAD (bb)); for (rtx i = start_insn; i != NULL_RTX && i != PREV_INSN (BB_HEAD (bb));
i = PREV_INSN (i)) i = PREV_INSN (i))
...@@ -341,7 +351,7 @@ sh_optimize_sett_clrt ...@@ -341,7 +351,7 @@ sh_optimize_sett_clrt
return; return;
} }
if (any_condjump_p (i) && onlyjump_p (i) && prev_visited_bb != NULL) if (any_condjump_p (i) && onlyjump_p (i) && !prev_visited_bb.empty ())
{ {
// For a conditional branch the ccreg value will be a known constant // For a conditional branch the ccreg value will be a known constant
// of either 0 or STORE_FLAG_VALUE after branching/falling through // of either 0 or STORE_FLAG_VALUE after branching/falling through
...@@ -353,10 +363,11 @@ sh_optimize_sett_clrt ...@@ -353,10 +363,11 @@ sh_optimize_sett_clrt
ccreg_value v; ccreg_value v;
v.insn = i; v.insn = i;
v.bb = bb; v.bb = bb;
v.value = GEN_INT (sh_cbranch_ccreg_value (i, bb, prev_visited_bb)); v.value = GEN_INT (sh_cbranch_ccreg_value (i, bb,
prev_visited_bb.back ()));
log_msg (" branches to [bb %d] with ccreg value ", log_msg (" branches to [bb %d] with ccreg value ",
prev_visited_bb->index); prev_visited_bb.back ()->index);
log_rtx (v.value); log_rtx (v.value);
log_msg ("\n"); log_msg ("\n");
...@@ -370,26 +381,35 @@ sh_optimize_sett_clrt ...@@ -370,26 +381,35 @@ sh_optimize_sett_clrt
// In this case, check the predecessor basic blocks. // In this case, check the predecessor basic blocks.
unsigned int pred_bb_count = 0; unsigned int pred_bb_count = 0;
// If the current basic block is the same as the previous one, it's a loop. // If the current basic block is not in the stack of previously visited
// Don't try to recurse again, as this will result in an infinite loop. // basic blocks yet, we can recursively check the predecessor basic blocks.
if (bb != prev_visited_bb) // Otherwise we have a loop in the CFG and recursing again will result in
for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei); ei_next (&ei)) // an infinite loop.
{ if (std::find (prev_visited_bb.rbegin (), prev_visited_bb.rend (), bb)
basic_block pred_bb = ei_edge (ei)->src; == prev_visited_bb.rend ())
if (pred_bb->index == ENTRY_BLOCK) {
continue; prev_visited_bb.push_back (bb);
pred_bb_count += 1; for (edge_iterator ei = ei_start (bb->preds); !ei_end_p (ei);
find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out, bb); ei_next (&ei))
} {
basic_block pred_bb = ei_edge (ei)->src;
pred_bb_count += 1;
find_last_ccreg_values (BB_END (pred_bb), pred_bb, values_out,
prev_visited_bb);
}
prev_visited_bb.pop_back ();
}
else
log_msg ("loop detected for [bb %d]\n", bb->index);
log_msg ("[bb %d] pred_bb_count = %u\n", bb->index, pred_bb_count); log_msg ("[bb %d] pred_bb_count = %u\n", bb->index, pred_bb_count);
// If here, we've walked up all the predecessor basic blocks without finding
// anything setcc related. Add an entry for the last insn of the current
// basic block with the ccreg value being set to unknown (NULL_RTX).
if (pred_bb_count == 0) if (pred_bb_count == 0)
{ {
// If we haven't checked a single predecessor basic block, the current
// basic block is probably a leaf block and we don't know the ccreg value.
log_msg ("unknown ccreg value for [bb %d]\n", bb->index); log_msg ("unknown ccreg value for [bb %d]\n", bb->index);
ccreg_value v; ccreg_value v;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment