/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "c1/c1_Canonicalizer.hpp"
#include "c1/c1_ValueMap.hpp"
#include "utilities/bitMap.inline.hpp"
#ifndef PRODUCT
#else
#endif
: _nesting(0)
, _killed_values()
, _entry_count(0)
{
}
, _killed_values()
{
for (int i = size() - 1; i >= 0; i--) {
}
}
int new_entry_count = 0;
for (int i = old_size - 1; i >= 0; i--) {
}
}
// changing entries with a lower nesting than the current nesting of the table
// is not allowed because then the same entry is contained in multiple value maps.
// clone entry when next-pointer must be changed
}
}
}
}
if (hash != 0) {
// 0 hash means: exclude from value numbering
for (ValueMapEntry* entry = entry_at(entry_index(hash, size())); entry != NULL; entry = entry->next()) {
TRACE_VALUE_NUMBERING(tty->print_cr("Value Numbering: %s %c%d equal to %c%d (size %d, entries %d, nesting-diff %d)", x->name(), x->type()->tchar(), x->id(), f->type()->tchar(), f->id(), size(), entry_count(), nesting() - entry->nesting()));
// non-constant values of of another block must be pinned,
// otherwise it is possible that they are not evaluated
}
return f;
}
}
}
// x not found, so insert it
if (entry_count() >= size_threshold()) {
}
_entry_count++;
TRACE_VALUE_NUMBERING(tty->print_cr("Value Numbering: insert %s %c%d (size %d, entries %d, nesting %d)", x->name(), x->type()->tchar(), x->id(), size(), entry_count(), nesting()));
}
return x;
}
NOT_PRODUCT(_number_of_kills++); \
\
for (int i = size() - 1; i >= 0; i--) { \
\
\
if (must_kill) { \
kill_value(value); \
\
if (prev_entry == NULL) { \
_entry_count--; \
_entry_count--; \
} else { \
prev_entry = entry; \
} \
\
TRACE_VALUE_NUMBERING(tty->print_cr("Value Numbering: killed %s %c%d (size %d, entries %d, nesting-diff %d)", value->name(), value->type()->tchar(), value->id(), size(), entry_count(), nesting() - entry->nesting())); \
} else { \
prev_entry = entry; \
} \
} \
} \
/* ciField's are not unique; must compare their contents */ \
}
}
}
}
}
for (int i = size() - 1; i >= 0; i--) {
}
_entry_count = 0;
}
#ifndef PRODUCT
int entries = 0;
for (int i = 0; i < size(); i++) {
tty->print("%s %c%d (%s%d) -> ", value->name(), value->type()->tchar(), value->id(), is_killed(value) ? "x" : "", entry->nesting());
entries++;
}
}
}
}
_number_of_finds = 0;
_number_of_hits = 0;
_number_of_kills = 0;
}
float hit_rate = 0;
if (_number_of_finds != 0) {
}
tty->print_cr("finds:%3d hits:%3d kills:%3d hit rate: %1.4f", _number_of_finds, _number_of_hits, _number_of_kills, hit_rate);
}
#endif
private:
bool _too_complicated_loop;
// simplified access to methods of GlobalValueNumbering
// implementation for abstract methods of ValueNumberingVisitor
void kill_field(ciField* field, bool all_offsets) { current_map()->kill_field(field, all_offsets); };
public:
, _too_complicated_loop(false)
{
}
};
_too_complicated_loop = false;
for (int i = 0; i < _loop_blocks.length(); i++) {
// this would be too complicated
return false;
}
// add predecessors to worklist
return false;
}
}
}
// use the instruction visitor for killing values
if (_too_complicated_loop) {
return false;
}
}
}
return true;
}
: _current_map(NULL)
{
int subst_count = 0;
assert(start_block == ir->start() && start_block->number_of_preds() == 0 && start_block->dominator() == NULL, "must be start block");
assert(start_block->next()->as_Base() != NULL && start_block->next()->next() == NULL, "start block must not have instructions");
// initial, empty value map with nesting 0
for (int i = 1; i < num_blocks; i++) {
// create new value map with increased nesting
if (num_preds == 1) {
// nothing to do here
// block has incoming backward branches -> try to optimize short loops
// loop is too complicated, so kill all memory loads because there might be
// stores to them in the loop
current_map()->kill_memory();
}
} else {
// only incoming forward branches that are already processed
for (int j = 0; j < num_preds; j++) {
// propagate killed values of the predecessor to this block
} else {
// kill all memory loads because predecessor not yet processed
// (this can happen with non-natural loops and OSR-compiles)
current_map()->kill_memory();
}
}
}
current_map()->kill_exception();
}
// visit all instructions of this block
// check if instruction kills any values
if (f != instr) {
subst_count++;
}
}
}
// remember value map for successors
}
if (subst_count != 0) {
}
TRACE_VALUE_NUMBERING(tty->print("****** end of global value numbering. "); ValueMap::print_statistics());
}