8220420: Cleanup c1_LinearScan

Reviewed-by: thartmann, neliasso
This commit is contained in:
Claes Redestad 2019-03-11 17:33:55 +01:00
parent bacddb40eb
commit 8c047147f9
2 changed files with 46 additions and 98 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2019, 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
@ -81,7 +81,7 @@ LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map)
, _max_spills(0)
, _unused_spill_slot(-1)
, _intervals(0) // initialized later with correct length
, _new_intervals_from_allocation(new IntervalList())
, _new_intervals_from_allocation(NULL)
, _sorted_intervals(NULL)
, _needs_full_resort(false)
, _lir_ops(0) // initialized later with correct length
@ -287,7 +287,11 @@ Interval* LinearScan::create_interval(int reg_num) {
void LinearScan::append_interval(Interval* it) {
it->set_reg_num(_intervals.length());
_intervals.append(it);
_new_intervals_from_allocation->append(it);
IntervalList* new_intervals = _new_intervals_from_allocation;
if (new_intervals == NULL) {
new_intervals = _new_intervals_from_allocation = new IntervalList();
}
new_intervals->append(it);
}
// copy the vreg-flags if an interval is split
@ -1283,7 +1287,7 @@ void LinearScan::build_intervals() {
// temp ranges for fpu registers are only created when the method has
// virtual fpu operands. Otherwise no allocation for fpu registers is
// perfomed and so the temp ranges would be useless
// performed and so the temp ranges would be useless
if (has_fpu_registers()) {
#ifdef X86
if (UseSSE < 2) {
@ -1616,7 +1620,7 @@ void LinearScan::sort_intervals_after_allocation() {
IntervalArray* old_list = _sorted_intervals;
IntervalList* new_list = _new_intervals_from_allocation;
int old_len = old_list->length();
int new_len = new_list->length();
int new_len = new_list == NULL ? 0 : new_list->length();
if (new_len == 0) {
// no intervals have been added during allocation, so sorted list is already up to date
@ -1721,13 +1725,12 @@ Interval* LinearScan::interval_at_op_id(int reg_num, int op_id) {
void LinearScan::resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver) {
DEBUG_ONLY(move_resolver.check_empty());
const int num_regs = num_virtual_regs();
const int size = live_set_size();
const ResourceBitMap live_at_edge = to_block->live_in();
// visit all registers where the live_at_edge bit is set
for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) {
assert(r < num_regs, "live information set for not exisiting interval");
assert(r < num_virtual_regs(), "live information set for not exisiting interval");
assert(from_block->live_out().at(r) && to_block->live_in().at(r), "interval not live at this edge");
Interval* from_interval = interval_at_block_end(from_block, r);
@ -4124,7 +4127,7 @@ Interval::Interval(int reg_num) :
_cached_to(-1),
_cached_opr(LIR_OprFact::illegalOpr),
_cached_vm_reg(VMRegImpl::Bad()),
_split_children(0),
_split_children(NULL),
_canonical_spill_slot(-1),
_insert_move_when_activated(false),
_spill_state(noDefinitionFound),
@ -4149,18 +4152,18 @@ int Interval::calc_to() {
#ifdef ASSERT
// consistency check of split-children
void Interval::check_split_children() {
if (_split_children.length() > 0) {
if (_split_children != NULL && _split_children->length() > 0) {
assert(is_split_parent(), "only split parents can have children");
for (int i = 0; i < _split_children.length(); i++) {
Interval* i1 = _split_children.at(i);
for (int i = 0; i < _split_children->length(); i++) {
Interval* i1 = _split_children->at(i);
assert(i1->split_parent() == this, "not a split child of this interval");
assert(i1->type() == type(), "must be equal for all split children");
assert(i1->canonical_spill_slot() == canonical_spill_slot(), "must be equal for all split children");
for (int j = i + 1; j < _split_children.length(); j++) {
Interval* i2 = _split_children.at(j);
for (int j = i + 1; j < _split_children->length(); j++) {
Interval* i2 = _split_children->at(j);
assert(i1->reg_num() != i2->reg_num(), "same register number");
@ -4187,11 +4190,11 @@ Interval* Interval::register_hint(bool search_split_child) const {
if (_register_hint->assigned_reg() >= 0 && _register_hint->assigned_reg() < LinearScan::nof_regs) {
return _register_hint;
} else if (_register_hint->_split_children.length() > 0) {
} else if (_register_hint->_split_children != NULL && _register_hint->_split_children->length() > 0) {
// search the first split child that has a register assigned
int len = _register_hint->_split_children.length();
int len = _register_hint->_split_children->length();
for (int i = 0; i < len; i++) {
Interval* cur = _register_hint->_split_children.at(i);
Interval* cur = _register_hint->_split_children->at(i);
if (cur->assigned_reg() >= 0 && cur->assigned_reg() < LinearScan::nof_regs) {
return cur;
@ -4210,23 +4213,23 @@ Interval* Interval::split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mo
assert(op_id >= 0, "invalid op_id (method can not be called for spill moves)");
Interval* result;
if (_split_children.length() == 0) {
if (_split_children == NULL || _split_children->length() == 0) {
result = this;
} else {
result = NULL;
int len = _split_children.length();
int len = _split_children->length();
// in outputMode, the end of the interval (op_id == cur->to()) is not valid
int to_offset = (mode == LIR_OpVisitState::outputMode ? 0 : 1);
int i;
for (i = 0; i < len; i++) {
Interval* cur = _split_children.at(i);
Interval* cur = _split_children->at(i);
if (cur->from() <= op_id && op_id < cur->to() + to_offset) {
if (i > 0) {
// exchange current split child to start of list (faster access for next call)
_split_children.at_put(i, _split_children.at(0));
_split_children.at_put(0, cur);
_split_children->at_put(i, _split_children->at(0));
_split_children->at_put(0, cur);
}
// interval found
@ -4237,7 +4240,7 @@ Interval* Interval::split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mo
#ifdef ASSERT
for (i = 0; i < len; i++) {
Interval* tmp = _split_children.at(i);
Interval* tmp = _split_children->at(i);
if (tmp != result && tmp->from() <= op_id && op_id < tmp->to() + to_offset) {
tty->print_cr("two valid result intervals found for op_id %d: %d and %d", op_id, result->reg_num(), tmp->reg_num());
result->print();
@ -4262,11 +4265,12 @@ Interval* Interval::split_child_before_op_id(int op_id) {
Interval* parent = split_parent();
Interval* result = NULL;
int len = parent->_split_children.length();
assert(parent->_split_children != NULL, "no split children available");
int len = parent->_split_children->length();
assert(len > 0, "no split children available");
for (int i = len - 1; i >= 0; i--) {
Interval* cur = parent->_split_children.at(i);
Interval* cur = parent->_split_children->at(i);
if (cur->to() <= op_id && (result == NULL || result->to() < cur->to())) {
result = cur;
}
@ -4277,29 +4281,6 @@ Interval* Interval::split_child_before_op_id(int op_id) {
}
// checks if op_id is covered by any split child
bool Interval::split_child_covers(int op_id, LIR_OpVisitState::OprMode mode) {
assert(is_split_parent(), "can only be called for split parents");
assert(op_id >= 0, "invalid op_id (method can not be called for spill moves)");
if (_split_children.length() == 0) {
// simple case if interval was not split
return covers(op_id, mode);
} else {
// extended case: check all split children
int len = _split_children.length();
for (int i = 0; i < len; i++) {
Interval* cur = _split_children.at(i);
if (cur->covers(op_id, mode)) {
return true;
}
}
return false;
}
}
// Note: use positions are sorted descending -> first use has highest index
int Interval::first_usage(IntervalUseKind min_use_kind) const {
assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals");
@ -4404,13 +4385,13 @@ Interval* Interval::new_split_child() {
result->set_register_hint(parent);
// insert new interval in children-list of parent
if (parent->_split_children.length() == 0) {
if (parent->_split_children == NULL) {
assert(is_split_parent(), "list must be initialized at first split");
parent->_split_children = IntervalList(4);
parent->_split_children.append(this);
parent->_split_children = new IntervalList(4);
parent->_split_children->append(this);
}
parent->_split_children.append(result);
parent->_split_children->append(result);
return result;
}
@ -4655,12 +4636,6 @@ IntervalWalker::IntervalWalker(LinearScan* allocator, Interval* unhandled_fixed_
}
// append interval at top of list
void IntervalWalker::append_unsorted(Interval** list, Interval* interval) {
interval->set_next(*list); *list = interval;
}
// append interval in order of current range from()
void IntervalWalker::append_sorted(Interval** list, Interval* interval) {
Interval* prev = NULL;
@ -4964,17 +4939,6 @@ void LinearScanWalker::free_collect_inactive_any(Interval* cur) {
}
}
void LinearScanWalker::free_collect_unhandled(IntervalKind kind, Interval* cur) {
Interval* list = unhandled_first(kind);
while (list != Interval::end()) {
set_use_pos(list, list->intersects_at(cur), true);
if (kind == fixedKind && cur->to() <= list->from()) {
set_use_pos(list, list->from(), true);
}
list = list->next();
}
}
void LinearScanWalker::spill_exclude_active_fixed() {
Interval* list = active_first(fixedKind);
while (list != Interval::end()) {
@ -4983,14 +4947,6 @@ void LinearScanWalker::spill_exclude_active_fixed() {
}
}
void LinearScanWalker::spill_block_unhandled_fixed(Interval* cur) {
Interval* list = unhandled_first(fixedKind);
while (list != Interval::end()) {
set_block_pos(list, list->intersects_at(cur));
list = list->next();
}
}
void LinearScanWalker::spill_block_inactive_fixed(Interval* cur) {
Interval* list = inactive_first(fixedKind);
while (list != Interval::end()) {
@ -5412,7 +5368,6 @@ bool LinearScanWalker::alloc_free_reg(Interval* cur) {
free_exclude_active_any();
free_collect_inactive_fixed(cur);
free_collect_inactive_any(cur);
// free_collect_unhandled(fixedKind, cur);
assert(unhandled_first(fixedKind) == Interval::end(), "must not have unhandled fixed intervals because all fixed intervals have a use at position 0");
// _use_pos contains the start of the next interval that has this register assigned
@ -5445,8 +5400,8 @@ bool LinearScanWalker::alloc_free_reg(Interval* cur) {
int interval_to = cur->to();
bool need_split = false;
int split_pos = -1;
int reg = any_reg;
int split_pos;
int reg;
int regHi = any_reg;
if (_adjacent_regs) {
@ -5500,7 +5455,7 @@ bool LinearScanWalker::alloc_free_reg(Interval* cur) {
}
int LinearScanWalker::find_locked_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split) {
int LinearScanWalker::find_locked_reg(int reg_needed_until, int interval_to, int ignore_reg, bool* need_split) {
int max_reg = any_reg;
for (int i = _first_reg; i <= _last_reg; i++) {
@ -5508,7 +5463,7 @@ int LinearScanWalker::find_locked_reg(int reg_needed_until, int interval_to, int
// this register must be ignored
} else if (_use_pos[i] > reg_needed_until) {
if (max_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_reg] && max_reg != hint_reg)) {
if (max_reg == any_reg || _use_pos[i] > _use_pos[max_reg]) {
max_reg = i;
}
}
@ -5521,7 +5476,7 @@ int LinearScanWalker::find_locked_reg(int reg_needed_until, int interval_to, int
return max_reg;
}
int LinearScanWalker::find_locked_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split) {
int LinearScanWalker::find_locked_double_reg(int reg_needed_until, int interval_to, bool* need_split) {
assert((_last_reg - _first_reg + 1) % 2 == 0, "adjust algorithm");
int max_reg = any_reg;
@ -5571,7 +5526,6 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) {
// collect current usage of registers
init_use_lists(false);
spill_exclude_active_fixed();
// spill_block_unhandled_fixed(cur);
assert(unhandled_first(fixedKind) == Interval::end(), "must not have unhandled fixed intervals because all fixed intervals have a use at position 0");
spill_block_inactive_fixed(cur);
spill_collect_active_any();
@ -5601,7 +5555,7 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) {
int reg, regHi;
if (_adjacent_regs) {
reg = find_locked_double_reg(reg_needed_until, interval_to, any_reg, &need_split);
reg = find_locked_double_reg(reg_needed_until, interval_to, &need_split);
regHi = reg + 1;
if (reg != any_reg) {
@ -5609,7 +5563,7 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) {
split_pos = MIN2(_block_pos[reg], _block_pos[regHi]);
}
} else {
reg = find_locked_reg(reg_needed_until, interval_to, any_reg, cur->assigned_reg(), &need_split);
reg = find_locked_reg(reg_needed_until, interval_to, cur->assigned_reg(), &need_split);
regHi = any_reg;
if (reg != any_reg) {
@ -5621,7 +5575,7 @@ void LinearScanWalker::alloc_locked_reg(Interval* cur) {
regHi = reg;
reg = cur->assigned_reg();
} else {
regHi = find_locked_reg(reg_needed_until, interval_to, any_reg, reg, &need_split);
regHi = find_locked_reg(reg_needed_until, interval_to, reg, &need_split);
if (regHi != any_reg) {
use_pos = MIN2(use_pos, _use_pos[regHi]);
split_pos = MIN2(split_pos, _block_pos[regHi]);

View File

@ -34,7 +34,6 @@
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
class DebugInfoCache;
class FpuStackAllocator;
class IRScopeDebugInfo;
class Interval;
@ -190,15 +189,12 @@ class LinearScan : public CompilationResourceObj {
int interval_count() const { return _intervals.length(); }
Interval* interval_at(int reg_num) const { return _intervals.at(reg_num); }
IntervalList* new_intervals_from_allocation() const { return _new_intervals_from_allocation; }
// access to LIR_Ops and Blocks indexed by op_id
int max_lir_op_id() const { assert(_lir_ops.length() > 0, "no operations"); return (_lir_ops.length() - 1) << 1; }
LIR_Op* lir_op_with_id(int op_id) const { assert(op_id >= 0 && op_id <= max_lir_op_id() && op_id % 2 == 0, "op_id out of range or not even"); return _lir_ops.at(op_id >> 1); }
BlockBegin* block_of_op_with_id(int op_id) const { assert(_block_of_op.length() > 0 && op_id >= 0 && op_id <= max_lir_op_id() + 1, "op_id out of range"); return _block_of_op.at(op_id >> 1); }
bool is_block_begin(int op_id) { return op_id == 0 || block_of_op_with_id(op_id) != block_of_op_with_id(op_id - 1); }
bool covers_block_begin(int op_id_1, int op_id_2) { return block_of_op_with_id(op_id_1) != block_of_op_with_id(op_id_2); }
bool has_call(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_call.at(op_id >> 1); }
bool has_info(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_info.at(op_id >> 1); }
@ -523,7 +519,7 @@ class Interval : public CompilationResourceObj {
VMReg _cached_vm_reg;
Interval* _split_parent; // the original interval where this interval is derived from
IntervalList _split_children; // list of all intervals that are split off from this interval (only available for split parents)
IntervalList* _split_children; // list of all intervals that are split off from this interval (only available for split parents)
Interval* _current_split_child; // the current split child that has been active or inactive last (always stored in split parents)
int _canonical_spill_slot; // the stack slot where all split parts of this interval are spilled to (always stored in split parents)
@ -549,7 +545,10 @@ class Interval : public CompilationResourceObj {
Range* first() const { return _first; }
int from() const { return _first->from(); }
int to() { if (_cached_to == -1) _cached_to = calc_to(); assert(_cached_to == calc_to(), "invalid cached value"); return _cached_to; }
#ifndef PRODUCT
int num_use_positions() const { return _use_pos_and_kinds.length() / 2; }
#endif
Interval* next() const { return _next; }
Interval** next_addr() { return &_next; }
@ -572,7 +571,6 @@ class Interval : public CompilationResourceObj {
Interval* split_parent() const { assert(_split_parent->is_split_parent(), "must be"); return _split_parent; }
Interval* split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mode);
Interval* split_child_before_op_id(int op_id);
bool split_child_covers(int op_id, LIR_OpVisitState::OprMode mode);
DEBUG_ONLY(void check_split_children();)
// information stored in split parent, but available for all children
@ -658,7 +656,6 @@ class IntervalWalker : public CompilationResourceObj {
Interval** active_first_addr(IntervalKind kind) { check_bounds(kind); return &_active_first[kind]; }
Interval** inactive_first_addr(IntervalKind kind) { check_bounds(kind); return &_inactive_first[kind]; }
void append_unsorted(Interval** first, Interval* interval);
void append_sorted(Interval** first, Interval* interval);
void append_to_unhandled(Interval** list, Interval* interval);
@ -733,9 +730,7 @@ class LinearScanWalker : public IntervalWalker {
void free_exclude_active_any();
void free_collect_inactive_fixed(Interval* cur);
void free_collect_inactive_any(Interval* cur);
void free_collect_unhandled(IntervalKind kind, Interval* cur);
void spill_exclude_active_fixed();
void spill_block_unhandled_fixed(Interval* cur);
void spill_block_inactive_fixed(Interval* cur);
void spill_collect_active_any();
void spill_collect_inactive_any(Interval* cur);
@ -753,13 +748,12 @@ class LinearScanWalker : public IntervalWalker {
int find_free_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split);
bool alloc_free_reg(Interval* cur);
int find_locked_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split);
int find_locked_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split);
int find_locked_reg(int reg_needed_until, int interval_to, int ignore_reg, bool* need_split);
int find_locked_double_reg(int reg_needed_until, int interval_to, bool* need_split);
void split_and_spill_intersecting_intervals(int reg, int regHi);
void alloc_locked_reg(Interval* cur);
bool no_allocation_possible(Interval* cur);
void update_phys_reg_range(bool requires_cpu_register);
void init_vars_for_alloc(Interval* cur);
bool pd_init_regs_for_alloc(Interval* cur);