< 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 >