< prev index next >
src/share/vm/c1/c1_RangeCheckElimination.cpp
Print this page
rev 10549 : imported patch c1_Instruction_BBA
rev 10552 : imported patch c1_RCE
rev 10555 : imported patch primitive arrays
rev 10556 : imported patch update dates
*** 1,7 ****
/*
! * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 51,62 ****
}
}
// Constructor
RangeCheckEliminator::RangeCheckEliminator(IR *ir) :
! _bounds(Instruction::number_of_instructions(), NULL),
! _access_indexed_info(Instruction::number_of_instructions(), NULL)
{
_visitor.set_range_check_eliminator(this);
_ir = ir;
_number_of_instructions = Instruction::number_of_instructions();
_optimistic = ir->compilation()->is_optimistic();
--- 51,62 ----
}
}
// Constructor
RangeCheckEliminator::RangeCheckEliminator(IR *ir) :
! _bounds(Instruction::number_of_instructions(), Instruction::number_of_instructions(), NULL),
! _access_indexed_info(Instruction::number_of_instructions(), Instruction::number_of_instructions(), NULL)
{
_visitor.set_range_check_eliminator(this);
_ir = ir;
_number_of_instructions = Instruction::number_of_instructions();
_optimistic = ir->compilation()->is_optimistic();
*** 301,332 ****
// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.
RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {
// Wrong type or NULL -> No bound
if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;
! if (!_bounds[v->id()]) {
// First (default) bound is calculated
// Create BoundStack
! _bounds[v->id()] = new BoundStack();
_visitor.clear_bound();
Value visit_value = v;
visit_value->visit(&_visitor);
Bound *bound = _visitor.bound();
if (bound) {
! _bounds[v->id()]->push(bound);
}
! if (_bounds[v->id()]->length() == 0) {
assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");
! _bounds[v->id()]->push(new Bound());
}
! } else if (_bounds[v->id()]->length() == 0) {
// To avoid endless loops, bound is currently in calculation -> nothing known about it
return new Bound();
}
// Return bound
! return _bounds[v->id()]->top();
}
// Update bound
void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {
if (cond == Instruction::gtr) {
--- 301,332 ----
// Get bound. Returns the current bound on Value v. Normally this is the topmost element on the bound stack.
RangeCheckEliminator::Bound *RangeCheckEliminator::get_bound(Value v) {
// Wrong type or NULL -> No bound
if (!v || (!v->type()->as_IntType() && !v->type()->as_ObjectType())) return NULL;
! if (!_bounds.at(v->id())) {
// First (default) bound is calculated
// Create BoundStack
! _bounds.at_put(v->id(), new BoundStack());
_visitor.clear_bound();
Value visit_value = v;
visit_value->visit(&_visitor);
Bound *bound = _visitor.bound();
if (bound) {
! _bounds.at(v->id())->push(bound);
}
! if (_bounds.at(v->id())->length() == 0) {
assert(!(v->as_Constant() && v->type()->as_IntConstant()), "constants not handled here");
! _bounds.at(v->id())->push(new Bound());
}
! } else if (_bounds.at(v->id())->length() == 0) {
// To avoid endless loops, bound is currently in calculation -> nothing known about it
return new Bound();
}
// Return bound
! return _bounds.at(v->id())->top();
}
// Update bound
void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instruction::Condition cond, Value value, int constant) {
if (cond == Instruction::gtr) {
*** 351,382 ****
void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {
if (v->as_Constant()) {
// No bound update for constants
return;
}
! if (!_bounds[v->id()]) {
get_bound(v);
! assert(_bounds[v->id()], "Now Stack must exist");
}
Bound *top = NULL;
! if (_bounds[v->id()]->length() > 0) {
! top = _bounds[v->id()]->top();
}
if (top) {
bound->and_op(top);
}
! _bounds[v->id()]->push(bound);
pushed.append(v->id());
}
// Add instruction + idx for in block motion
void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {
int id = instruction->id();
! AccessIndexedInfo *aii = _access_indexed_info[id];
if (aii == NULL) {
aii = new AccessIndexedInfo();
! _access_indexed_info[id] = aii;
indices.append(instruction);
aii->_min = idx;
aii->_max = idx;
aii->_list = new AccessIndexedList();
} else if (idx >= aii->_min && idx <= aii->_max) {
--- 351,382 ----
void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Bound *bound) {
if (v->as_Constant()) {
// No bound update for constants
return;
}
! if (!_bounds.at(v->id())) {
get_bound(v);
! assert(_bounds.at(v->id()), "Now Stack must exist");
}
Bound *top = NULL;
! if (_bounds.at(v->id())->length() > 0) {
! top = _bounds.at(v->id())->top();
}
if (top) {
bound->and_op(top);
}
! _bounds.at(v->id())->push(bound);
pushed.append(v->id());
}
// Add instruction + idx for in block motion
void RangeCheckEliminator::add_access_indexed_info(InstructionList &indices, int idx, Value instruction, AccessIndexed *ai) {
int id = instruction->id();
! AccessIndexedInfo *aii = _access_indexed_info.at(id);
if (aii == NULL) {
aii = new AccessIndexedInfo();
! _access_indexed_info.at_put(id, aii);
indices.append(instruction);
aii->_min = idx;
aii->_max = idx;
aii->_list = new AccessIndexedList();
} else if (idx >= aii->_min && idx <= aii->_max) {
*** 459,469 ****
// Iterate over all different indices
if (_optimistic) {
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
! AccessIndexedInfo *info = _access_indexed_info[index_instruction->id()];
assert(info != NULL, "Info must not be null");
// if idx < 0, max > 0, max + idx may fall between 0 and
// length-1 and if min < 0, min + idx may overflow and be >=
// 0. The predicate wouldn't trigger but some accesses could
--- 459,469 ----
// Iterate over all different indices
if (_optimistic) {
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
! AccessIndexedInfo *info = _access_indexed_info.at(index_instruction->id());
assert(info != NULL, "Info must not be null");
// if idx < 0, max > 0, max + idx may fall between 0 and
// length-1 and if min < 0, min + idx may overflow and be >=
// 0. The predicate wouldn't trigger but some accesses could
*** 560,570 ****
}
// Clear data structures for next array
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
! _access_indexed_info[index_instruction->id()] = NULL;
}
indices.clear();
}
}
--- 560,570 ----
}
// Clear data structures for next array
for (int i = 0; i < indices.length(); i++) {
Instruction *index_instruction = indices.at(i);
! _access_indexed_info.at_put(index_instruction->id(), NULL);
}
indices.clear();
}
}
*** 1003,1013 ****
}
}
// Reset stack
for (int i=0; i<pushed.length(); i++) {
! _bounds[pushed[i]]->pop();
}
}
#ifndef PRODUCT
// Dump condition stack
--- 1003,1013 ----
}
}
// Reset stack
for (int i=0; i<pushed.length(); i++) {
! _bounds.at(pushed.at(i))->pop();
}
}
#ifndef PRODUCT
// Dump condition stack
*** 1049,1059 ****
}
}
#endif
// Verification or the IR
! RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), false) {
this->_ir = ir;
ir->iterate_linear_scan_order(this);
}
// Verify this block
--- 1049,1059 ----
}
}
#endif
// Verification or the IR
! RangeCheckEliminator::Verification::Verification(IR *ir) : _used(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), false) {
this->_ir = ir;
ir->iterate_linear_scan_order(this);
}
// Verify this block
*** 1144,1161 ****
// Try to reach Block end beginning in Block start and not using Block dont_use
bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {
if (start == end) return start != dont_use;
// Simple BSF from start to end
// BlockBeginList _current;
! for (int i=0; i<_used.length(); i++) {
! _used[i] = false;
}
! _current.truncate(0);
! _successors.truncate(0);
if (start != dont_use) {
_current.push(start);
! _used[start->block_id()] = true;
}
// BlockBeginList _successors;
while (_current.length() > 0) {
BlockBegin *cur = _current.pop();
--- 1144,1161 ----
// Try to reach Block end beginning in Block start and not using Block dont_use
bool RangeCheckEliminator::Verification::can_reach(BlockBegin *start, BlockBegin *end, BlockBegin *dont_use /* = NULL */) {
if (start == end) return start != dont_use;
// Simple BSF from start to end
// BlockBeginList _current;
! for (int i=0; i < _used.length(); i++) {
! _used.at_put(i, false);
}
! _current.trunc_to(0);
! _successors.trunc_to(0);
if (start != dont_use) {
_current.push(start);
! _used.at_put(start->block_id(), true);
}
// BlockBeginList _successors;
while (_current.length() > 0) {
BlockBegin *cur = _current.pop();
*** 1178,1198 ****
BlockBegin *xhandler = sux->exception_handler_at(j);
_successors.push(xhandler);
}
}
for (int i=0; i<_successors.length(); i++) {
! BlockBegin *sux = _successors[i];
assert(sux != NULL, "Successor must not be NULL!");
if (sux == end) {
return true;
}
! if (sux != dont_use && !_used[sux->block_id()]) {
! _used[sux->block_id()] = true;
_current.push(sux);
}
}
! _successors.truncate(0);
}
return false;
}
--- 1178,1198 ----
BlockBegin *xhandler = sux->exception_handler_at(j);
_successors.push(xhandler);
}
}
for (int i=0; i<_successors.length(); i++) {
! BlockBegin *sux = _successors.at(i);
assert(sux != NULL, "Successor must not be NULL!");
if (sux == end) {
return true;
}
! if (sux != dont_use && !_used.at(sux->block_id())) {
! _used.at_put(sux->block_id(), true);
_current.push(sux);
}
}
! _successors.trunc_to(0);
}
return false;
}
< prev index next >