changeset 54056:17a6681a5118

8220420: Cleanup c1_LinearScan Reviewed-by: thartmann, neliasso
author redestad
date Mon, 11 Mar 2019 17:33:55 +0100
parents 289fd6cb7480
children 687e10fefa11
files src/hotspot/share/c1/c1_LinearScan.cpp src/hotspot/share/c1/c1_LinearScan.hpp
diffstat 2 files changed, 47 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/c1/c1_LinearScan.cpp	Mon Mar 11 15:34:16 2019 +0100
+++ b/src/hotspot/share/c1/c1_LinearScan.cpp	Mon Mar 11 17:33:55 2019 +0100
@@ -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 @@
  , _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 @@
 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 @@
 
   // 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 @@
   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 @@
 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 @@
   _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 @@
 #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 @@
     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 @@
   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 @@
 
 #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* 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 @@
 }
 
 
-// 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 @@
   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.append(result);
+    parent->_split_children = new IntervalList(4);
+    parent->_split_children->append(this);
+  }
+  parent->_split_children->append(result);
 
   return result;
 }
@@ -4655,12 +4636,6 @@
 }
 
 
-// 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_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_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 @@
   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 @@
   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 @@
 }
 
 
-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 @@
       // 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 @@
   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 @@
   // 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 @@
   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 @@
       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 @@
           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]);
--- a/src/hotspot/share/c1/c1_LinearScan.hpp	Mon Mar 11 15:34:16 2019 +0100
+++ b/src/hotspot/share/c1/c1_LinearScan.hpp	Mon Mar 11 17:33:55 2019 +0100
@@ -34,7 +34,6 @@
 #include "utilities/align.hpp"
 #include "utilities/macros.hpp"
 
-class DebugInfoCache;
 class FpuStackAllocator;
 class IRScopeDebugInfo;
 class Interval;
@@ -190,15 +189,12 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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 @@
   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);