/*
 * Copyright (c) 2005, 2023, 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.
 *
 * 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_CFGPrinter.hpp"
#include "c1/c1_CodeStubs.hpp"
#include "c1/c1_Compilation.hpp"
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_IR.hpp"
#include "c1/c1_LIRGenerator.hpp"
#include "c1/c1_LinearScan.hpp"
#include "c1/c1_ValueStack.hpp"
#include "code/vmreg.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "utilities/bitMap.inline.hpp"

#ifndef PRODUCT

  static LinearScanStatistic _stat_before_alloc;
  static LinearScanStatistic _stat_after_asign;
  static LinearScanStatistic _stat_final;

  static LinearScanTimers _total_timer;

  // helper macro for short definition of timer
  #define TIME_LINEAR_SCAN(timer_name)  TraceTime _block_timer("", _total_timer.timer(LinearScanTimers::timer_name), TimeLinearScan || TimeEachLinearScan, Verbose);

#else
  #define TIME_LINEAR_SCAN(timer_name)
#endif

#ifdef ASSERT

  // helper macro for short definition of trace-output inside code
  #define TRACE_LINEAR_SCAN(level, code)       \
    if (TraceLinearScanLevel >= level) {       \
      code;                                    \
    }
#else
  #define TRACE_LINEAR_SCAN(level, code)
#endif

// Map BasicType to spill size in 32-bit words, matching VMReg's notion of words
#ifdef _LP64
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 0, 2,  1, 2, 1, -1};
#else
static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, -1, 1, 1, -1};
#endif


// Implementation of LinearScan

LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map)
 : _compilation(ir->compilation())
 , _ir(ir)
 , _gen(gen)
 , _frame_map(frame_map)
 , _cached_blocks(*ir->linear_scan_order())
 , _num_virtual_regs(gen->max_virtual_register_number())
 , _has_fpu_registers(false)
 , _num_calls(-1)
 , _max_spills(0)
 , _unused_spill_slot(-1)
 , _intervals(0)   // initialized later with correct length
 , _new_intervals_from_allocation(nullptr)
 , _sorted_intervals(nullptr)
 , _needs_full_resort(false)
 , _lir_ops(0)     // initialized later with correct length
 , _block_of_op(0) // initialized later with correct length
 , _has_info(0)
 , _has_call(0)
 , _interval_in_loop(0)  // initialized later with correct length
 , _scope_value_cache(0) // initialized later with correct length
#ifdef IA32
 , _fpu_stack_allocator(nullptr)
#endif
{
  assert(this->ir() != nullptr,          "check if valid");
  assert(this->compilation() != nullptr, "check if valid");
  assert(this->gen() != nullptr,         "check if valid");
  assert(this->frame_map() != nullptr,   "check if valid");
}


// ********** functions for converting LIR-Operands to register numbers
//
// Emulate a flat register file comprising physical integer registers,
// physical floating-point registers and virtual registers, in that order.
// Virtual registers already have appropriate numbers, since V0 is
// the number of physical registers.
// Returns -1 for hi word if opr is a single word operand.
//
// Note: the inverse operation (calculating an operand for register numbers)
//       is done in calc_operand_for_interval()

int LinearScan::reg_num(LIR_Opr opr) {
  assert(opr->is_register(), "should not call this otherwise");

  if (opr->is_virtual_register()) {
    assert(opr->vreg_number() >= nof_regs, "found a virtual register with a fixed-register number");
    return opr->vreg_number();
  } else if (opr->is_single_cpu()) {
    return opr->cpu_regnr();
  } else if (opr->is_double_cpu()) {
    return opr->cpu_regnrLo();
#ifdef X86
  } else if (opr->is_single_xmm()) {
    return opr->fpu_regnr() + pd_first_xmm_reg;
  } else if (opr->is_double_xmm()) {
    return opr->fpu_regnrLo() + pd_first_xmm_reg;
#endif
  } else if (opr->is_single_fpu()) {
    return opr->fpu_regnr() + pd_first_fpu_reg;
  } else if (opr->is_double_fpu()) {
    return opr->fpu_regnrLo() + pd_first_fpu_reg;
  } else {
    ShouldNotReachHere();
    return -1;
  }
}

int LinearScan::reg_numHi(LIR_Opr opr) {
  assert(opr->is_register(), "should not call this otherwise");

  if (opr->is_virtual_register()) {
    return -1;
  } else if (opr->is_single_cpu()) {
    return -1;
  } else if (opr->is_double_cpu()) {
    return opr->cpu_regnrHi();
#ifdef X86
  } else if (opr->is_single_xmm()) {
    return -1;
  } else if (opr->is_double_xmm()) {
    return -1;
#endif
  } else if (opr->is_single_fpu()) {
    return -1;
  } else if (opr->is_double_fpu()) {
    return opr->fpu_regnrHi() + pd_first_fpu_reg;
  } else {
    ShouldNotReachHere();
    return -1;
  }
}


// ********** functions for classification of intervals

bool LinearScan::is_precolored_interval(const Interval* i) {
  return i->reg_num() < LinearScan::nof_regs;
}

bool LinearScan::is_virtual_interval(const Interval* i) {
  return i->reg_num() >= LIR_Opr::vreg_base;
}

bool LinearScan::is_precolored_cpu_interval(const Interval* i) {
  return i->reg_num() < LinearScan::nof_cpu_regs;
}

bool LinearScan::is_virtual_cpu_interval(const Interval* i) {
#if defined(__SOFTFP__) || defined(E500V2)
  return i->reg_num() >= LIR_Opr::vreg_base;
#else
  return i->reg_num() >= LIR_Opr::vreg_base && (i->type() != T_FLOAT && i->type() != T_DOUBLE);
#endif // __SOFTFP__ or E500V2
}

bool LinearScan::is_precolored_fpu_interval(const Interval* i) {
  return i->reg_num() >= LinearScan::nof_cpu_regs && i->reg_num() < LinearScan::nof_regs;
}

bool LinearScan::is_virtual_fpu_interval(const Interval* i) {
#if defined(__SOFTFP__) || defined(E500V2)
  return false;
#else
  return i->reg_num() >= LIR_Opr::vreg_base && (i->type() == T_FLOAT || i->type() == T_DOUBLE);
#endif // __SOFTFP__ or E500V2
}

bool LinearScan::is_in_fpu_register(const Interval* i) {
  // fixed intervals not needed for FPU stack allocation
  return i->reg_num() >= nof_regs && pd_first_fpu_reg <= i->assigned_reg() && i->assigned_reg() <= pd_last_fpu_reg;
}

bool LinearScan::is_oop_interval(const Interval* i) {
  // fixed intervals never contain oops
  return i->reg_num() >= nof_regs && i->type() == T_OBJECT;
}


// ********** General helper functions

// compute next unused stack index that can be used for spilling
int LinearScan::allocate_spill_slot(bool double_word) {
  int spill_slot;
  if (double_word) {
    if ((_max_spills & 1) == 1) {
      // alignment of double-word values
      // the hole because of the alignment is filled with the next single-word value
      assert(_unused_spill_slot == -1, "wasting a spill slot");
      _unused_spill_slot = _max_spills;
      _max_spills++;
    }
    spill_slot = _max_spills;
    _max_spills += 2;

  } else if (_unused_spill_slot != -1) {
    // re-use hole that was the result of a previous double-word alignment
    spill_slot = _unused_spill_slot;
    _unused_spill_slot = -1;

  } else {
    spill_slot = _max_spills;
    _max_spills++;
  }

  int result = spill_slot + LinearScan::nof_regs + frame_map()->argcount();

  // if too many slots used, bailout compilation.
  if (result > 2000) {
    bailout("too many stack slots used");
  }

  return result;
}

void LinearScan::assign_spill_slot(Interval* it) {
  // assign the canonical spill slot of the parent (if a part of the interval
  // is already spilled) or allocate a new spill slot
  if (it->canonical_spill_slot() >= 0) {
    it->assign_reg(it->canonical_spill_slot());
  } else {
    int spill = allocate_spill_slot(type2spill_size[it->type()] == 2);
    it->set_canonical_spill_slot(spill);
    it->assign_reg(spill);
  }
}

void LinearScan::propagate_spill_slots() {
  if (!frame_map()->finalize_frame(max_spills())) {
    bailout("frame too large");
  }
}

// create a new interval with a predefined reg_num
// (only used for parent intervals that are created during the building phase)
Interval* LinearScan::create_interval(int reg_num) {
  assert(_intervals.at(reg_num) == nullptr, "overwriting existing interval");

  Interval* interval = new Interval(reg_num);
  _intervals.at_put(reg_num, interval);

  // assign register number for precolored intervals
  if (reg_num < LIR_Opr::vreg_base) {
    interval->assign_reg(reg_num);
  }
  return interval;
}

// assign a new reg_num to the interval and append it to the list of intervals
// (only used for child intervals that are created during register allocation)
void LinearScan::append_interval(Interval* it) {
  it->set_reg_num(_intervals.length());
  _intervals.append(it);
  IntervalList* new_intervals = _new_intervals_from_allocation;
  if (new_intervals == nullptr) {
    new_intervals = _new_intervals_from_allocation = new IntervalList();
  }
  new_intervals->append(it);
}

// copy the vreg-flags if an interval is split
void LinearScan::copy_register_flags(Interval* from, Interval* to) {
  if (gen()->is_vreg_flag_set(from->reg_num(), LIRGenerator::byte_reg)) {
    gen()->set_vreg_flag(to->reg_num(), LIRGenerator::byte_reg);
  }
  if (gen()->is_vreg_flag_set(from->reg_num(), LIRGenerator::callee_saved)) {
    gen()->set_vreg_flag(to->reg_num(), LIRGenerator::callee_saved);
  }

  // Note: do not copy the must_start_in_memory flag because it is not necessary for child
  //       intervals (only the very beginning of the interval must be in memory)
}


// ********** spill move optimization
// eliminate moves from register to stack if stack slot is known to be correct

// called during building of intervals
void LinearScan::change_spill_definition_pos(Interval* interval, int def_pos) {
  assert(interval->is_split_parent(), "can only be called for split parents");

  switch (interval->spill_state()) {
    case noDefinitionFound:
      assert(interval->spill_definition_pos() == -1, "must no be set before");
      interval->set_spill_definition_pos(def_pos);
      interval->set_spill_state(oneDefinitionFound);
      break;

    case oneDefinitionFound:
      assert(def_pos <= interval->spill_definition_pos(), "positions are processed in reverse order when intervals are created");
      if (def_pos < interval->spill_definition_pos() - 2) {
        // second definition found, so no spill optimization possible for this interval
        interval->set_spill_state(noOptimization);
      } else {
        // two consecutive definitions (because of two-operand LIR form)
        assert(block_of_op_with_id(def_pos) == block_of_op_with_id(interval->spill_definition_pos()), "block must be equal");
      }
      break;

    case noOptimization:
      // nothing to do
      break;

    default:
      assert(false, "other states not allowed at this time");
  }
}

// called during register allocation
void LinearScan::change_spill_state(Interval* interval, int spill_pos) {
  switch (interval->spill_state()) {
    case oneDefinitionFound: {
      int def_loop_depth = block_of_op_with_id(interval->spill_definition_pos())->loop_depth();
      int spill_loop_depth = block_of_op_with_id(spill_pos)->loop_depth();

      if (def_loop_depth < spill_loop_depth) {
        // the loop depth of the spilling position is higher then the loop depth
        // at the definition of the interval -> move write to memory out of loop
        // by storing at definitin of the interval
        interval->set_spill_state(storeAtDefinition);
      } else {
        // the interval is currently spilled only once, so for now there is no
        // reason to store the interval at the definition
        interval->set_spill_state(oneMoveInserted);
      }
      break;
    }

    case oneMoveInserted: {
      // the interval is spilled more then once, so it is better to store it to
      // memory at the definition
      interval->set_spill_state(storeAtDefinition);
      break;
    }

    case storeAtDefinition:
    case startInMemory:
    case noOptimization:
    case noDefinitionFound:
      // nothing to do
      break;

    default:
      assert(false, "other states not allowed at this time");
  }
}


bool LinearScan::must_store_at_definition(const Interval* i) {
  return i->is_split_parent() && i->spill_state() == storeAtDefinition;
}

// called once before assignment of register numbers
void LinearScan::eliminate_spill_moves() {
  TIME_LINEAR_SCAN(timer_eliminate_spill_moves);
  TRACE_LINEAR_SCAN(3, tty->print_cr("***** Eliminating unnecessary spill moves"));

  // collect all intervals that must be stored after their definion.
  // the list is sorted by Interval::spill_definition_pos
  Interval* interval;
  Interval* temp_list;
  create_unhandled_lists(&interval, &temp_list, must_store_at_definition, nullptr);

#ifdef ASSERT
  Interval* prev = nullptr;
  Interval* temp = interval;
  while (temp != Interval::end()) {
    assert(temp->spill_definition_pos() > 0, "invalid spill definition pos");
    if (prev != nullptr) {
      assert(temp->from() >= prev->from(), "intervals not sorted");
      assert(temp->spill_definition_pos() >= prev->spill_definition_pos(), "when intervals are sorted by from, then they must also be sorted by spill_definition_pos");
    }

    assert(temp->canonical_spill_slot() >= LinearScan::nof_regs, "interval has no spill slot assigned");
    assert(temp->spill_definition_pos() >= temp->from(), "invalid order");
    assert(temp->spill_definition_pos() <= temp->from() + 2, "only intervals defined once at their start-pos can be optimized");

    TRACE_LINEAR_SCAN(4, tty->print_cr("interval %d (from %d to %d) must be stored at %d", temp->reg_num(), temp->from(), temp->to(), temp->spill_definition_pos()));

    temp = temp->next();
  }
#endif

  LIR_InsertionBuffer insertion_buffer;
  int num_blocks = block_count();
  for (int i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    LIR_OpList* instructions = block->lir()->instructions_list();
    int         num_inst = instructions->length();
    bool        has_new = false;

    // iterate all instructions of the block. skip the first because it is always a label
    for (int j = 1; j < num_inst; j++) {
      LIR_Op* op = instructions->at(j);
      int op_id = op->id();

      if (op_id == -1) {
        // remove move from register to stack if the stack slot is guaranteed to be correct.
        // only moves that have been inserted by LinearScan can be removed.
        assert(op->code() == lir_move, "only moves can have a op_id of -1");
        assert(op->as_Op1() != nullptr, "move must be LIR_Op1");
        assert(op->as_Op1()->result_opr()->is_virtual(), "LinearScan inserts only moves to virtual registers");

        LIR_Op1* op1 = (LIR_Op1*)op;
        Interval* interval = interval_at(op1->result_opr()->vreg_number());

        if (interval->assigned_reg() >= LinearScan::nof_regs && interval->always_in_memory()) {
          // move target is a stack slot that is always correct, so eliminate instruction
          TRACE_LINEAR_SCAN(4, tty->print_cr("eliminating move from interval %d to %d", op1->in_opr()->vreg_number(), op1->result_opr()->vreg_number()));
          instructions->at_put(j, nullptr); // null-instructions are deleted by assign_reg_num
        }

      } else {
        // insert move from register to stack just after the beginning of the interval
        assert(interval == Interval::end() || interval->spill_definition_pos() >= op_id, "invalid order");
        assert(interval == Interval::end() || (interval->is_split_parent() && interval->spill_state() == storeAtDefinition), "invalid interval");

        while (interval != Interval::end() && interval->spill_definition_pos() == op_id) {
          if (!has_new) {
            // prepare insertion buffer (appended when all instructions of the block are processed)
            insertion_buffer.init(block->lir());
            has_new = true;
          }

          LIR_Opr from_opr = operand_for_interval(interval);
          LIR_Opr to_opr = canonical_spill_opr(interval);
          assert(from_opr->is_fixed_cpu() || from_opr->is_fixed_fpu(), "from operand must be a register");
          assert(to_opr->is_stack(), "to operand must be a stack slot");

          insertion_buffer.move(j, from_opr, to_opr);
          TRACE_LINEAR_SCAN(4, tty->print_cr("inserting move after definition of interval %d to stack slot %d at op_id %d", interval->reg_num(), interval->canonical_spill_slot() - LinearScan::nof_regs, op_id));

          interval = interval->next();
        }
      }
    } // end of instruction iteration

    if (has_new) {
      block->lir()->append(&insertion_buffer);
    }
  } // end of block iteration

  assert(interval == Interval::end(), "missed an interval");
}


// ********** Phase 1: number all instructions in all blocks
// Compute depth-first and linear scan block orders, and number LIR_Op nodes for linear scan.

void LinearScan::number_instructions() {
  {
    // dummy-timer to measure the cost of the timer itself
    // (this time is then subtracted from all other timers to get the real value)
    TIME_LINEAR_SCAN(timer_do_nothing);
  }
  TIME_LINEAR_SCAN(timer_number_instructions);

  // Assign IDs to LIR nodes and build a mapping, lir_ops, from ID to LIR_Op node.
  int num_blocks = block_count();
  int num_instructions = 0;
  int i;
  for (i = 0; i < num_blocks; i++) {
    num_instructions += block_at(i)->lir()->instructions_list()->length();
  }

  // initialize with correct length
  _lir_ops = LIR_OpArray(num_instructions, num_instructions, nullptr);
  _block_of_op = BlockBeginArray(num_instructions, num_instructions, nullptr);

  int op_id = 0;
  int idx = 0;

  for (i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    block->set_first_lir_instruction_id(op_id);
    LIR_OpList* instructions = block->lir()->instructions_list();

    int num_inst = instructions->length();
    for (int j = 0; j < num_inst; j++) {
      LIR_Op* op = instructions->at(j);
      op->set_id(op_id);

      _lir_ops.at_put(idx, op);
      _block_of_op.at_put(idx, block);
      assert(lir_op_with_id(op_id) == op, "must match");

      idx++;
      op_id += 2; // numbering of lir_ops by two
    }
    block->set_last_lir_instruction_id(op_id - 2);
  }
  assert(idx == num_instructions, "must match");
  assert(idx * 2 == op_id, "must match");

  _has_call.initialize(num_instructions);
  _has_info.initialize(num_instructions);
}


// ********** Phase 2: compute local live sets separately for each block
// (sets live_gen and live_kill for each block)

void LinearScan::set_live_gen_kill(Value value, LIR_Op* op, BitMap& live_gen, BitMap& live_kill) {
  LIR_Opr opr = value->operand();
  Constant* con = value->as_Constant();

  // check some asumptions about debug information
  assert(!value->type()->is_illegal(), "if this local is used by the interpreter it shouldn't be of indeterminate type");
  assert(con == nullptr || opr->is_virtual() || opr->is_constant() || opr->is_illegal(), "assumption: Constant instructions have only constant operands");
  assert(con != nullptr || opr->is_virtual(), "assumption: non-Constant instructions have only virtual operands");

  if ((con == nullptr || con->is_pinned()) && opr->is_register()) {
    assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
    int reg = opr->vreg_number();
    if (!live_kill.at(reg)) {
      live_gen.set_bit(reg);
      TRACE_LINEAR_SCAN(4, tty->print_cr("  Setting live_gen for value %c%d, LIR op_id %d, register number %d", value->type()->tchar(), value->id(), op->id(), reg));
    }
  }
}


void LinearScan::compute_local_live_sets() {
  TIME_LINEAR_SCAN(timer_compute_local_live_sets);

  int  num_blocks = block_count();
  int  live_size = live_set_size();
  bool local_has_fpu_registers = false;
  int  local_num_calls = 0;
  LIR_OpVisitState visitor;

  BitMap2D local_interval_in_loop = BitMap2D(_num_virtual_regs, num_loops());

  // iterate all blocks
  for (int i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);

    ResourceBitMap live_gen(live_size);
    ResourceBitMap live_kill(live_size);

    if (block->is_set(BlockBegin::exception_entry_flag)) {
      // Phi functions at the begin of an exception handler are
      // implicitly defined (= killed) at the beginning of the block.
      for_each_phi_fun(block, phi,
        if (!phi->is_illegal()) { live_kill.set_bit(phi->operand()->vreg_number()); }
      );
    }

    LIR_OpList* instructions = block->lir()->instructions_list();
    int num_inst = instructions->length();

    // iterate all instructions of the block. skip the first because it is always a label
    assert(visitor.no_operands(instructions->at(0)), "first operation must always be a label");
    for (int j = 1; j < num_inst; j++) {
      LIR_Op* op = instructions->at(j);

      // visit operation to collect all operands
      visitor.visit(op);

      if (visitor.has_call()) {
        _has_call.set_bit(op->id() >> 1);
        local_num_calls++;
      }
      if (visitor.info_count() > 0) {
        _has_info.set_bit(op->id() >> 1);
      }

      // iterate input operands of instruction
      int k, n, reg;
      n = visitor.opr_count(LIR_OpVisitState::inputMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, k);
        assert(opr->is_register(), "visitor should only return register operands");

        if (opr->is_virtual_register()) {
          assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
          reg = opr->vreg_number();
          if (!live_kill.at(reg)) {
            live_gen.set_bit(reg);
            TRACE_LINEAR_SCAN(4, tty->print_cr("  Setting live_gen for register %d at instruction %d", reg, op->id()));
          }
          if (block->loop_index() >= 0) {
            local_interval_in_loop.set_bit(reg, block->loop_index());
          }
          local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu();
        }

#ifdef ASSERT
        // fixed intervals are never live at block boundaries, so
        // they need not be processed in live sets.
        // this is checked by these assertions to be sure about it.
        // the entry block may have incoming values in registers, which is ok.
        if (!opr->is_virtual_register() && block != ir()->start()) {
          reg = reg_num(opr);
          if (is_processed_reg_num(reg)) {
            assert(live_kill.at(reg), "using fixed register that is not defined in this block");
          }
          reg = reg_numHi(opr);
          if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
            assert(live_kill.at(reg), "using fixed register that is not defined in this block");
          }
        }
#endif
      }

      // Add uses of live locals from interpreter's point of view for proper debug information generation
      n = visitor.info_count();
      for (k = 0; k < n; k++) {
        CodeEmitInfo* info = visitor.info_at(k);
        ValueStack* stack = info->stack();
        for_each_state_value(stack, value,
          set_live_gen_kill(value, op, live_gen, live_kill);
          local_has_fpu_registers = local_has_fpu_registers || value->type()->is_float_kind();
        );
      }

      // iterate temp operands of instruction
      n = visitor.opr_count(LIR_OpVisitState::tempMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, k);
        assert(opr->is_register(), "visitor should only return register operands");

        if (opr->is_virtual_register()) {
          assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
          reg = opr->vreg_number();
          live_kill.set_bit(reg);
          if (block->loop_index() >= 0) {
            local_interval_in_loop.set_bit(reg, block->loop_index());
          }
          local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu();
        }

#ifdef ASSERT
        // fixed intervals are never live at block boundaries, so
        // they need not be processed in live sets
        // process them only in debug mode so that this can be checked
        if (!opr->is_virtual_register()) {
          reg = reg_num(opr);
          if (is_processed_reg_num(reg)) {
            live_kill.set_bit(reg_num(opr));
          }
          reg = reg_numHi(opr);
          if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
            live_kill.set_bit(reg);
          }
        }
#endif
      }

      // iterate output operands of instruction
      n = visitor.opr_count(LIR_OpVisitState::outputMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, k);
        assert(opr->is_register(), "visitor should only return register operands");

        if (opr->is_virtual_register()) {
          assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
          reg = opr->vreg_number();
          live_kill.set_bit(reg);
          if (block->loop_index() >= 0) {
            local_interval_in_loop.set_bit(reg, block->loop_index());
          }
          local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu();
        }

#ifdef ASSERT
        // fixed intervals are never live at block boundaries, so
        // they need not be processed in live sets
        // process them only in debug mode so that this can be checked
        if (!opr->is_virtual_register()) {
          reg = reg_num(opr);
          if (is_processed_reg_num(reg)) {
            live_kill.set_bit(reg_num(opr));
          }
          reg = reg_numHi(opr);
          if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
            live_kill.set_bit(reg);
          }
        }
#endif
      }
    } // end of instruction iteration

    block->set_live_gen (live_gen);
    block->set_live_kill(live_kill);
    block->set_live_in  (ResourceBitMap(live_size));
    block->set_live_out (ResourceBitMap(live_size));

    TRACE_LINEAR_SCAN(4, tty->print("live_gen  B%d ", block->block_id()); print_bitmap(block->live_gen()));
    TRACE_LINEAR_SCAN(4, tty->print("live_kill B%d ", block->block_id()); print_bitmap(block->live_kill()));
  } // end of block iteration

  // propagate local calculated information into LinearScan object
  _has_fpu_registers = local_has_fpu_registers;
  compilation()->set_has_fpu_code(local_has_fpu_registers);

  _num_calls = local_num_calls;
  _interval_in_loop = local_interval_in_loop;
}


// ********** Phase 3: perform a backward dataflow analysis to compute global live sets
// (sets live_in and live_out for each block)

void LinearScan::compute_global_live_sets() {
  TIME_LINEAR_SCAN(timer_compute_global_live_sets);

  int  num_blocks = block_count();
  bool change_occurred;
  bool change_occurred_in_block;
  int  iteration_count = 0;
  ResourceBitMap live_out(live_set_size()); // scratch set for calculations

  // Perform a backward dataflow analysis to compute live_out and live_in for each block.
  // The loop is executed until a fixpoint is reached (no changes in an iteration)
  // Exception handlers must be processed because not all live values are
  // present in the state array, e.g. because of global value numbering
  do {
    change_occurred = false;

    // iterate all blocks in reverse order
    for (int i = num_blocks - 1; i >= 0; i--) {
      BlockBegin* block = block_at(i);

      change_occurred_in_block = false;

      // live_out(block) is the union of live_in(sux), for successors sux of block
      int n = block->number_of_sux();
      int e = block->number_of_exception_handlers();
      if (n + e > 0) {
        // block has successors
        if (n > 0) {
          live_out.set_from(block->sux_at(0)->live_in());
          for (int j = 1; j < n; j++) {
            live_out.set_union(block->sux_at(j)->live_in());
          }
        } else {
          live_out.clear();
        }
        for (int j = 0; j < e; j++) {
          live_out.set_union(block->exception_handler_at(j)->live_in());
        }

        if (!block->live_out().is_same(live_out)) {
          // A change occurred.  Swap the old and new live out sets to avoid copying.
          ResourceBitMap temp = block->live_out();
          block->set_live_out(live_out);
          live_out = temp;

          change_occurred = true;
          change_occurred_in_block = true;
        }
      }

      if (iteration_count == 0 || change_occurred_in_block) {
        // live_in(block) is the union of live_gen(block) with (live_out(block) & !live_kill(block))
        // note: live_in has to be computed only in first iteration or if live_out has changed!
        ResourceBitMap live_in = block->live_in();
        live_in.set_from(block->live_out());
        live_in.set_difference(block->live_kill());
        live_in.set_union(block->live_gen());
      }

#ifdef ASSERT
      if (TraceLinearScanLevel >= 4) {
        char c = ' ';
        if (iteration_count == 0 || change_occurred_in_block) {
          c = '*';
        }
        tty->print("(%d) live_in%c  B%d ", iteration_count, c, block->block_id()); print_bitmap(block->live_in());
        tty->print("(%d) live_out%c B%d ", iteration_count, c, block->block_id()); print_bitmap(block->live_out());
      }
#endif
    }
    iteration_count++;

    if (change_occurred && iteration_count > 50) {
      BAILOUT("too many iterations in compute_global_live_sets");
    }
  } while (change_occurred);


#ifdef ASSERT
  // check that fixed intervals are not live at block boundaries
  // (live set must be empty at fixed intervals)
  for (int i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    for (int j = 0; j < LIR_Opr::vreg_base; j++) {
      assert(block->live_in().at(j)  == false, "live_in  set of fixed register must be empty");
      assert(block->live_out().at(j) == false, "live_out set of fixed register must be empty");
      assert(block->live_gen().at(j) == false, "live_gen set of fixed register must be empty");
    }
  }
#endif

  // check that the live_in set of the first block is empty
  ResourceBitMap live_in_args(ir()->start()->live_in().size());
  if (!ir()->start()->live_in().is_same(live_in_args)) {
#ifdef ASSERT
    tty->print_cr("Error: live_in set of first block must be empty (when this fails, virtual registers are used before they are defined)");
    tty->print_cr("affected registers:");
    print_bitmap(ir()->start()->live_in());

    // print some additional information to simplify debugging
    for (unsigned int i = 0; i < ir()->start()->live_in().size(); i++) {
      if (ir()->start()->live_in().at(i)) {
        Instruction* instr = gen()->instruction_for_vreg(i);
        tty->print_cr("* vreg %d (HIR instruction %c%d)", i, instr == nullptr ? ' ' : instr->type()->tchar(), instr == nullptr ? 0 : instr->id());

        for (int j = 0; j < num_blocks; j++) {
          BlockBegin* block = block_at(j);
          if (block->live_gen().at(i)) {
            tty->print_cr("  used in block B%d", block->block_id());
          }
          if (block->live_kill().at(i)) {
            tty->print_cr("  defined in block B%d", block->block_id());
          }
        }
      }
    }

#endif
    // when this fails, virtual registers are used before they are defined.
    assert(false, "live_in set of first block must be empty");
    // bailout of if this occurs in product mode.
    bailout("live_in set of first block not empty");
  }
}


// ********** Phase 4: build intervals
// (fills the list _intervals)

void LinearScan::add_use(Value value, int from, int to, IntervalUseKind use_kind) {
  assert(!value->type()->is_illegal(), "if this value is used by the interpreter it shouldn't be of indeterminate type");
  LIR_Opr opr = value->operand();
  Constant* con = value->as_Constant();

  if ((con == nullptr || con->is_pinned()) && opr->is_register()) {
    assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
    add_use(opr, from, to, use_kind);
  }
}


void LinearScan::add_def(LIR_Opr opr, int def_pos, IntervalUseKind use_kind) {
  TRACE_LINEAR_SCAN(2, tty->print(" def "); opr->print(tty); tty->print_cr(" def_pos %d (%d)", def_pos, use_kind));
  assert(opr->is_register(), "should not be called otherwise");

  if (opr->is_virtual_register()) {
    assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
    add_def(opr->vreg_number(), def_pos, use_kind, opr->type_register());

  } else {
    int reg = reg_num(opr);
    if (is_processed_reg_num(reg)) {
      add_def(reg, def_pos, use_kind, opr->type_register());
    }
    reg = reg_numHi(opr);
    if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
      add_def(reg, def_pos, use_kind, opr->type_register());
    }
  }
}

void LinearScan::add_use(LIR_Opr opr, int from, int to, IntervalUseKind use_kind) {
  TRACE_LINEAR_SCAN(2, tty->print(" use "); opr->print(tty); tty->print_cr(" from %d to %d (%d)", from, to, use_kind));
  assert(opr->is_register(), "should not be called otherwise");

  if (opr->is_virtual_register()) {
    assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
    add_use(opr->vreg_number(), from, to, use_kind, opr->type_register());

  } else {
    int reg = reg_num(opr);
    if (is_processed_reg_num(reg)) {
      add_use(reg, from, to, use_kind, opr->type_register());
    }
    reg = reg_numHi(opr);
    if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
      add_use(reg, from, to, use_kind, opr->type_register());
    }
  }
}

void LinearScan::add_temp(LIR_Opr opr, int temp_pos, IntervalUseKind use_kind) {
  TRACE_LINEAR_SCAN(2, tty->print(" temp "); opr->print(tty); tty->print_cr(" temp_pos %d (%d)", temp_pos, use_kind));
  assert(opr->is_register(), "should not be called otherwise");

  if (opr->is_virtual_register()) {
    assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below");
    add_temp(opr->vreg_number(), temp_pos, use_kind, opr->type_register());

  } else {
    int reg = reg_num(opr);
    if (is_processed_reg_num(reg)) {
      add_temp(reg, temp_pos, use_kind, opr->type_register());
    }
    reg = reg_numHi(opr);
    if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) {
      add_temp(reg, temp_pos, use_kind, opr->type_register());
    }
  }
}


void LinearScan::add_def(int reg_num, int def_pos, IntervalUseKind use_kind, BasicType type) {
  Interval* interval = interval_at(reg_num);
  if (interval != nullptr) {
    assert(interval->reg_num() == reg_num, "wrong interval");

    if (type != T_ILLEGAL) {
      interval->set_type(type);
    }

    Range* r = interval->first();
    if (r->from() <= def_pos) {
      // Update the starting point (when a range is first created for a use, its
      // start is the beginning of the current block until a def is encountered.)
      r->set_from(def_pos);
      interval->add_use_pos(def_pos, use_kind);

    } else {
      // Dead value - make vacuous interval
      // also add use_kind for dead intervals
      interval->add_range(def_pos, def_pos + 1);
      interval->add_use_pos(def_pos, use_kind);
      TRACE_LINEAR_SCAN(2, tty->print_cr("Warning: def of reg %d at %d occurs without use", reg_num, def_pos));
    }

  } else {
    // Dead value - make vacuous interval
    // also add use_kind for dead intervals
    interval = create_interval(reg_num);
    if (type != T_ILLEGAL) {
      interval->set_type(type);
    }

    interval->add_range(def_pos, def_pos + 1);
    interval->add_use_pos(def_pos, use_kind);
    TRACE_LINEAR_SCAN(2, tty->print_cr("Warning: dead value %d at %d in live intervals", reg_num, def_pos));
  }

  change_spill_definition_pos(interval, def_pos);
  if (use_kind == noUse && interval->spill_state() <= startInMemory) {
        // detection of method-parameters and roundfp-results
        // TODO: move this directly to position where use-kind is computed
    interval->set_spill_state(startInMemory);
  }
}

void LinearScan::add_use(int reg_num, int from, int to, IntervalUseKind use_kind, BasicType type) {
  Interval* interval = interval_at(reg_num);
  if (interval == nullptr) {
    interval = create_interval(reg_num);
  }
  assert(interval->reg_num() == reg_num, "wrong interval");

  if (type != T_ILLEGAL) {
    interval->set_type(type);
  }

  interval->add_range(from, to);
  interval->add_use_pos(to, use_kind);
}

void LinearScan::add_temp(int reg_num, int temp_pos, IntervalUseKind use_kind, BasicType type) {
  Interval* interval = interval_at(reg_num);
  if (interval == nullptr) {
    interval = create_interval(reg_num);
  }
  assert(interval->reg_num() == reg_num, "wrong interval");

  if (type != T_ILLEGAL) {
    interval->set_type(type);
  }

  interval->add_range(temp_pos, temp_pos + 1);
  interval->add_use_pos(temp_pos, use_kind);
}


// the results of this functions are used for optimizing spilling and reloading
// if the functions return shouldHaveRegister and the interval is spilled,
// it is not reloaded to a register.
IntervalUseKind LinearScan::use_kind_of_output_operand(LIR_Op* op, LIR_Opr opr) {
  if (op->code() == lir_move) {
    assert(op->as_Op1() != nullptr, "lir_move must be LIR_Op1");
    LIR_Op1* move = (LIR_Op1*)op;
    LIR_Opr res = move->result_opr();
    bool result_in_memory = res->is_virtual() && gen()->is_vreg_flag_set(res->vreg_number(), LIRGenerator::must_start_in_memory);

    if (result_in_memory) {
      // Begin of an interval with must_start_in_memory set.
      // This interval will always get a stack slot first, so return noUse.
      return noUse;

    } else if (move->in_opr()->is_stack()) {
      // method argument (condition must be equal to handle_method_arguments)
      return noUse;

    } else if (move->in_opr()->is_register() && move->result_opr()->is_register()) {
      // Move from register to register
      if (block_of_op_with_id(op->id())->is_set(BlockBegin::osr_entry_flag)) {
        // special handling of phi-function moves inside osr-entry blocks
        // input operand must have a register instead of output operand (leads to better register allocation)
        return shouldHaveRegister;
      }
    }
  }

  if (opr->is_virtual() &&
      gen()->is_vreg_flag_set(opr->vreg_number(), LIRGenerator::must_start_in_memory)) {
    // result is a stack-slot, so prevent immediate reloading
    return noUse;
  }

  // all other operands require a register
  return mustHaveRegister;
}

IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
  if (op->code() == lir_move) {
    assert(op->as_Op1() != nullptr, "lir_move must be LIR_Op1");
    LIR_Op1* move = (LIR_Op1*)op;
    LIR_Opr res = move->result_opr();
    bool result_in_memory = res->is_virtual() && gen()->is_vreg_flag_set(res->vreg_number(), LIRGenerator::must_start_in_memory);

    if (result_in_memory) {
      // Move to an interval with must_start_in_memory set.
      // To avoid moves from stack to stack (not allowed) force the input operand to a register
      return mustHaveRegister;

    } else if (move->in_opr()->is_register() && move->result_opr()->is_register()) {
      // Move from register to register
      if (block_of_op_with_id(op->id())->is_set(BlockBegin::osr_entry_flag)) {
        // special handling of phi-function moves inside osr-entry blocks
        // input operand must have a register instead of output operand (leads to better register allocation)
        return mustHaveRegister;
      }

      // The input operand is not forced to a register (moves from stack to register are allowed),
      // but it is faster if the input operand is in a register
      return shouldHaveRegister;
    }
  }


#if defined(X86) || defined(S390)
  if (op->code() == lir_cmove) {
    // conditional moves can handle stack operands
    assert(op->result_opr()->is_register(), "result must always be in a register");
    return shouldHaveRegister;
  }

  // optimizations for second input operand of arithmehtic operations on Intel
  // this operand is allowed to be on the stack in some cases
  BasicType opr_type = opr->type_register();
  if (opr_type == T_FLOAT || opr_type == T_DOUBLE) {
    if (IA32_ONLY( (UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2 ) NOT_IA32( true )) {
      // SSE float instruction (T_DOUBLE only supported with SSE2)
      switch (op->code()) {
        case lir_cmp:
        case lir_add:
        case lir_sub:
        case lir_mul:
        case lir_div:
        {
          assert(op->as_Op2() != nullptr, "must be LIR_Op2");
          LIR_Op2* op2 = (LIR_Op2*)op;
          if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) {
            assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register");
            return shouldHaveRegister;
          }
        }
        default:
          break;
      }
    } else {
      // FPU stack float instruction
      switch (op->code()) {
        case lir_add:
        case lir_sub:
        case lir_mul:
        case lir_div:
        {
          assert(op->as_Op2() != nullptr, "must be LIR_Op2");
          LIR_Op2* op2 = (LIR_Op2*)op;
          if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) {
            assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register");
            return shouldHaveRegister;
          }
        }
        default:
          break;
      }
    }
    // We want to sometimes use logical operations on pointers, in particular in GC barriers.
    // Since 64bit logical operations do not current support operands on stack, we have to make sure
    // T_OBJECT doesn't get spilled along with T_LONG.
  } else if (opr_type != T_LONG LP64_ONLY(&& opr_type != T_OBJECT)) {
    // integer instruction (note: long operands must always be in register)
    switch (op->code()) {
      case lir_cmp:
      case lir_add:
      case lir_sub:
      case lir_logic_and:
      case lir_logic_or:
      case lir_logic_xor:
      {
        assert(op->as_Op2() != nullptr, "must be LIR_Op2");
        LIR_Op2* op2 = (LIR_Op2*)op;
        if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) {
          assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register");
          return shouldHaveRegister;
        }
      }
      default:
        break;
    }
  }
#endif // X86 || S390

  // all other operands require a register
  return mustHaveRegister;
}


void LinearScan::handle_method_arguments(LIR_Op* op) {
  // special handling for method arguments (moves from stack to virtual register):
  // the interval gets no register assigned, but the stack slot.
  // it is split before the first use by the register allocator.

  if (op->code() == lir_move) {
    assert(op->as_Op1() != nullptr, "must be LIR_Op1");
    LIR_Op1* move = (LIR_Op1*)op;

    if (move->in_opr()->is_stack()) {
#ifdef ASSERT
      int arg_size = compilation()->method()->arg_size();
      LIR_Opr o = move->in_opr();
      if (o->is_single_stack()) {
        assert(o->single_stack_ix() >= 0 && o->single_stack_ix() < arg_size, "out of range");
      } else if (o->is_double_stack()) {
        assert(o->double_stack_ix() >= 0 && o->double_stack_ix() < arg_size, "out of range");
      } else {
        ShouldNotReachHere();
      }

      assert(move->id() > 0, "invalid id");
      assert(block_of_op_with_id(move->id())->number_of_preds() == 0, "move from stack must be in first block");
      assert(move->result_opr()->is_virtual(), "result of move must be a virtual register");

      TRACE_LINEAR_SCAN(4, tty->print_cr("found move from stack slot %d to vreg %d", o->is_single_stack() ? o->single_stack_ix() : o->double_stack_ix(), reg_num(move->result_opr())));
#endif

      Interval* interval = interval_at(reg_num(move->result_opr()));

      int stack_slot = LinearScan::nof_regs + (move->in_opr()->is_single_stack() ? move->in_opr()->single_stack_ix() : move->in_opr()->double_stack_ix());
      interval->set_canonical_spill_slot(stack_slot);
      interval->assign_reg(stack_slot);
    }
  }
}

void LinearScan::handle_doubleword_moves(LIR_Op* op) {
  // special handling for doubleword move from memory to register:
  // in this case the registers of the input address and the result
  // registers must not overlap -> add a temp range for the input registers
  if (op->code() == lir_move) {
    assert(op->as_Op1() != nullptr, "must be LIR_Op1");
    LIR_Op1* move = (LIR_Op1*)op;

    if (move->result_opr()->is_double_cpu() && move->in_opr()->is_pointer()) {
      LIR_Address* address = move->in_opr()->as_address_ptr();
      if (address != nullptr) {
        if (address->base()->is_valid()) {
          add_temp(address->base(), op->id(), noUse);
        }
        if (address->index()->is_valid()) {
          add_temp(address->index(), op->id(), noUse);
        }
      }
    }
  }
}

void LinearScan::add_register_hints(LIR_Op* op) {
  switch (op->code()) {
    case lir_move:      // fall through
    case lir_convert: {
      assert(op->as_Op1() != nullptr, "lir_move, lir_convert must be LIR_Op1");
      LIR_Op1* move = (LIR_Op1*)op;

      LIR_Opr move_from = move->in_opr();
      LIR_Opr move_to = move->result_opr();

      if (move_to->is_register() && move_from->is_register()) {
        Interval* from = interval_at(reg_num(move_from));
        Interval* to = interval_at(reg_num(move_to));
        if (from != nullptr && to != nullptr) {
          to->set_register_hint(from);
          TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", move->id(), from->reg_num(), to->reg_num()));
        }
      }
      break;
    }
    case lir_cmove: {
      assert(op->as_Op4() != nullptr, "lir_cmove must be LIR_Op4");
      LIR_Op4* cmove = (LIR_Op4*)op;

      LIR_Opr move_from = cmove->in_opr1();
      LIR_Opr move_to   = cmove->result_opr();

      if (move_to->is_register() && move_from->is_register()) {
        Interval* from = interval_at(reg_num(move_from));
        Interval* to = interval_at(reg_num(move_to));
        if (from != nullptr && to != nullptr) {
          to->set_register_hint(from);
          TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", cmove->id(), from->reg_num(), to->reg_num()));
        }
      }
      break;
    }
    default:
      break;
  }
}


void LinearScan::build_intervals() {
  TIME_LINEAR_SCAN(timer_build_intervals);

  // initialize interval list with expected number of intervals
  // (32 is added to have some space for split children without having to resize the list)
  _intervals = IntervalList(num_virtual_regs() + 32);
  // initialize all slots that are used by build_intervals
  _intervals.at_put_grow(num_virtual_regs() - 1, nullptr, nullptr);

  // create a list with all caller-save registers (cpu, fpu, xmm)
  // when an instruction is a call, a temp range is created for all these registers
  int num_caller_save_registers = 0;
  int caller_save_registers[LinearScan::nof_regs];

  int i;
  for (i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) {
    LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i);
    assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands");
    assert(reg_numHi(opr) == -1, "missing addition of range for hi-register");
    caller_save_registers[num_caller_save_registers++] = reg_num(opr);
  }

  // temp ranges for fpu registers are only created when the method has
  // virtual fpu operands. Otherwise no allocation for fpu registers is
  // performed and so the temp ranges would be useless
  if (has_fpu_registers()) {
#ifdef X86
    if (UseSSE < 2) {
#endif // X86
      for (i = 0; i < FrameMap::nof_caller_save_fpu_regs; i++) {
        LIR_Opr opr = FrameMap::caller_save_fpu_reg_at(i);
        assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands");
        assert(reg_numHi(opr) == -1, "missing addition of range for hi-register");
        caller_save_registers[num_caller_save_registers++] = reg_num(opr);
      }
#ifdef X86
    }
#endif // X86

#ifdef X86
    if (UseSSE > 0) {
      int num_caller_save_xmm_regs = FrameMap::get_num_caller_save_xmms();
      for (i = 0; i < num_caller_save_xmm_regs; i ++) {
        LIR_Opr opr = FrameMap::caller_save_xmm_reg_at(i);
        assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands");
        assert(reg_numHi(opr) == -1, "missing addition of range for hi-register");
        caller_save_registers[num_caller_save_registers++] = reg_num(opr);
      }
    }
#endif // X86
  }
  assert(num_caller_save_registers <= LinearScan::nof_regs, "out of bounds");


  LIR_OpVisitState visitor;

  // iterate all blocks in reverse order
  for (i = block_count() - 1; i >= 0; i--) {
    BlockBegin* block = block_at(i);
    LIR_OpList* instructions = block->lir()->instructions_list();
    int         block_from =   block->first_lir_instruction_id();
    int         block_to =     block->last_lir_instruction_id();

    assert(block_from == instructions->at(0)->id(), "must be");
    assert(block_to   == instructions->at(instructions->length() - 1)->id(), "must be");

    // Update intervals for registers live at the end of this block;
    ResourceBitMap& live = block->live_out();
    auto updater = [&](BitMap::idx_t index) {
      int number = static_cast<int>(index);
      assert(number >= LIR_Opr::vreg_base, "fixed intervals must not be live on block bounds");
      TRACE_LINEAR_SCAN(2, tty->print_cr("live in %d to %d", number, block_to + 2));

      add_use(number, block_from, block_to + 2, noUse, T_ILLEGAL);

      // add special use positions for loop-end blocks when the
      // interval is used anywhere inside this loop.  It's possible
      // that the block was part of a non-natural loop, so it might
      // have an invalid loop index.
      if (block->is_set(BlockBegin::linear_scan_loop_end_flag) &&
          block->loop_index() != -1 &&
          is_interval_in_loop(number, block->loop_index())) {
        interval_at(number)->add_use_pos(block_to + 1, loopEndMarker);
      }
    };
    live.iterate(updater);

    // iterate all instructions of the block in reverse order.
    // skip the first instruction because it is always a label
    // definitions of intervals are processed before uses
    assert(visitor.no_operands(instructions->at(0)), "first operation must always be a label");
    for (int j = instructions->length() - 1; j >= 1; j--) {
      LIR_Op* op = instructions->at(j);
      int op_id = op->id();

      // visit operation to collect all operands
      visitor.visit(op);

      // add a temp range for each register if operation destroys caller-save registers
      if (visitor.has_call()) {
        for (int k = 0; k < num_caller_save_registers; k++) {
          add_temp(caller_save_registers[k], op_id, noUse, T_ILLEGAL);
        }
        TRACE_LINEAR_SCAN(4, tty->print_cr("operation destroys all caller-save registers"));
      }

      // Add any platform dependent temps
      pd_add_temps(op);

      // visit definitions (output and temp operands)
      int k, n;
      n = visitor.opr_count(LIR_OpVisitState::outputMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, k);
        assert(opr->is_register(), "visitor should only return register operands");
        add_def(opr, op_id, use_kind_of_output_operand(op, opr));
      }

      n = visitor.opr_count(LIR_OpVisitState::tempMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, k);
        assert(opr->is_register(), "visitor should only return register operands");
        add_temp(opr, op_id, mustHaveRegister);
      }

      // visit uses (input operands)
      n = visitor.opr_count(LIR_OpVisitState::inputMode);
      for (k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, k);
        assert(opr->is_register(), "visitor should only return register operands");
        add_use(opr, block_from, op_id, use_kind_of_input_operand(op, opr));
      }

      // Add uses of live locals from interpreter's point of view for proper
      // debug information generation
      // Treat these operands as temp values (if the life range is extended
      // to a call site, the value would be in a register at the call otherwise)
      n = visitor.info_count();
      for (k = 0; k < n; k++) {
        CodeEmitInfo* info = visitor.info_at(k);
        ValueStack* stack = info->stack();
        for_each_state_value(stack, value,
          add_use(value, block_from, op_id + 1, noUse);
        );
      }

      // special steps for some instructions (especially moves)
      handle_method_arguments(op);
      handle_doubleword_moves(op);
      add_register_hints(op);

    } // end of instruction iteration
  } // end of block iteration


  // add the range [0, 1[ to all fixed intervals
  // -> the register allocator need not handle unhandled fixed intervals
  for (int n = 0; n < LinearScan::nof_regs; n++) {
    Interval* interval = interval_at(n);
    if (interval != nullptr) {
      interval->add_range(0, 1);
    }
  }
}


// ********** Phase 5: actual register allocation

int LinearScan::interval_cmp(Interval** a, Interval** b) {
  if (*a != nullptr) {
    if (*b != nullptr) {
      return (*a)->from() - (*b)->from();
    } else {
      return -1;
    }
  } else {
    if (*b != nullptr) {
      return 1;
    } else {
      return 0;
    }
  }
}

#ifndef PRODUCT
int interval_cmp(Interval* const& l, Interval* const& r) {
  return l->from() - r->from();
}

bool find_interval(Interval* interval, IntervalArray* intervals) {
  bool found;
  int idx = intervals->find_sorted<Interval*, interval_cmp>(interval, found);

  if (!found) {
    return false;
  }

  int from = interval->from();

  // The index we've found using binary search is pointing to an interval
  // that is defined in the same place as the interval we were looking for.
  // So now we have to look around that index and find exact interval.
  for (int i = idx; i >= 0; i--) {
    if (intervals->at(i) == interval) {
      return true;
    }
    if (intervals->at(i)->from() != from) {
      break;
    }
  }

  for (int i = idx + 1; i < intervals->length(); i++) {
    if (intervals->at(i) == interval) {
      return true;
    }
    if (intervals->at(i)->from() != from) {
      break;
    }
  }

  return false;
}

bool LinearScan::is_sorted(IntervalArray* intervals) {
  int from = -1;
  int null_count = 0;

  for (int i = 0; i < intervals->length(); i++) {
    Interval* it = intervals->at(i);
    if (it != nullptr) {
      assert(from <= it->from(), "Intervals are unordered");
      from = it->from();
    } else {
      null_count++;
    }
  }

  assert(null_count == 0, "Sorted intervals should not contain nulls");

  null_count = 0;

  for (int i = 0; i < interval_count(); i++) {
    Interval* interval = interval_at(i);
    if (interval != nullptr) {
      assert(find_interval(interval, intervals), "Lists do not contain same intervals");
    } else {
      null_count++;
    }
  }

  assert(interval_count() - null_count == intervals->length(),
      "Sorted list should contain the same amount of non-null intervals as unsorted list");

  return true;
}
#endif

void LinearScan::add_to_list(Interval** first, Interval** prev, Interval* interval) {
  if (*prev != nullptr) {
    (*prev)->set_next(interval);
  } else {
    *first = interval;
  }
  *prev = interval;
}

void LinearScan::create_unhandled_lists(Interval** list1, Interval** list2, bool (is_list1)(const Interval* i), bool (is_list2)(const Interval* i)) {
  assert(is_sorted(_sorted_intervals), "interval list is not sorted");

  *list1 = *list2 = Interval::end();

  Interval* list1_prev = nullptr;
  Interval* list2_prev = nullptr;
  Interval* v;

  const int n = _sorted_intervals->length();
  for (int i = 0; i < n; i++) {
    v = _sorted_intervals->at(i);
    if (v == nullptr) continue;

    if (is_list1(v)) {
      add_to_list(list1, &list1_prev, v);
    } else if (is_list2 == nullptr || is_list2(v)) {
      add_to_list(list2, &list2_prev, v);
    }
  }

  if (list1_prev != nullptr) list1_prev->set_next(Interval::end());
  if (list2_prev != nullptr) list2_prev->set_next(Interval::end());

  assert(list1_prev == nullptr || list1_prev->next() == Interval::end(), "linear list ends not with sentinel");
  assert(list2_prev == nullptr || list2_prev->next() == Interval::end(), "linear list ends not with sentinel");
}


void LinearScan::sort_intervals_before_allocation() {
  TIME_LINEAR_SCAN(timer_sort_intervals_before);

  if (_needs_full_resort) {
    // There is no known reason why this should occur but just in case...
    assert(false, "should never occur");
    // Re-sort existing interval list because an Interval::from() has changed
    _sorted_intervals->sort(interval_cmp);
    _needs_full_resort = false;
  }

  IntervalList* unsorted_list = &_intervals;
  int unsorted_len = unsorted_list->length();
  int sorted_len = 0;
  int unsorted_idx;
  int sorted_idx = 0;
  int sorted_from_max = -1;

  // calc number of items for sorted list (sorted list must not contain null values)
  for (unsorted_idx = 0; unsorted_idx < unsorted_len; unsorted_idx++) {
    if (unsorted_list->at(unsorted_idx) != nullptr) {
      sorted_len++;
    }
  }
  IntervalArray* sorted_list = new IntervalArray(sorted_len, sorted_len, nullptr);

  // special sorting algorithm: the original interval-list is almost sorted,
  // only some intervals are swapped. So this is much faster than a complete QuickSort
  for (unsorted_idx = 0; unsorted_idx < unsorted_len; unsorted_idx++) {
    Interval* cur_interval = unsorted_list->at(unsorted_idx);

    if (cur_interval != nullptr) {
      int cur_from = cur_interval->from();

      if (sorted_from_max <= cur_from) {
        sorted_list->at_put(sorted_idx++, cur_interval);
        sorted_from_max = cur_interval->from();
      } else {
        // the assumption that the intervals are already sorted failed,
        // so this interval must be sorted in manually
        int j;
        for (j = sorted_idx - 1; j >= 0 && cur_from < sorted_list->at(j)->from(); j--) {
          sorted_list->at_put(j + 1, sorted_list->at(j));
        }
        sorted_list->at_put(j + 1, cur_interval);
        sorted_idx++;
      }
    }
  }
  _sorted_intervals = sorted_list;
  assert(is_sorted(_sorted_intervals), "intervals unsorted");
}

void LinearScan::sort_intervals_after_allocation() {
  TIME_LINEAR_SCAN(timer_sort_intervals_after);

  if (_needs_full_resort) {
    // Re-sort existing interval list because an Interval::from() has changed
    _sorted_intervals->sort(interval_cmp);
    _needs_full_resort = false;
  }

  IntervalArray* old_list = _sorted_intervals;
  IntervalList* new_list = _new_intervals_from_allocation;
  int old_len = old_list->length();
  int new_len = new_list == nullptr ? 0 : new_list->length();

  if (new_len == 0) {
    // no intervals have been added during allocation, so sorted list is already up to date
    assert(is_sorted(_sorted_intervals), "intervals unsorted");
    return;
  }

  // conventional sort-algorithm for new intervals
  new_list->sort(interval_cmp);

  // merge old and new list (both already sorted) into one combined list
  int combined_list_len = old_len + new_len;
  IntervalArray* combined_list = new IntervalArray(combined_list_len, combined_list_len, nullptr);
  int old_idx = 0;
  int new_idx = 0;

  while (old_idx + new_idx < old_len + new_len) {
    if (new_idx >= new_len || (old_idx < old_len && old_list->at(old_idx)->from() <= new_list->at(new_idx)->from())) {
      combined_list->at_put(old_idx + new_idx, old_list->at(old_idx));
      old_idx++;
    } else {
      combined_list->at_put(old_idx + new_idx, new_list->at(new_idx));
      new_idx++;
    }
  }

  _sorted_intervals = combined_list;
  assert(is_sorted(_sorted_intervals), "intervals unsorted");
}


void LinearScan::allocate_registers() {
  TIME_LINEAR_SCAN(timer_allocate_registers);

  Interval* precolored_cpu_intervals, *not_precolored_cpu_intervals;
  Interval* precolored_fpu_intervals, *not_precolored_fpu_intervals;

  // collect cpu intervals
  create_unhandled_lists(&precolored_cpu_intervals, &not_precolored_cpu_intervals,
                         is_precolored_cpu_interval, is_virtual_cpu_interval);

  // collect fpu intervals
  create_unhandled_lists(&precolored_fpu_intervals, &not_precolored_fpu_intervals,
                         is_precolored_fpu_interval, is_virtual_fpu_interval);
  // this fpu interval collection cannot be moved down below with the allocation section as
  // the cpu_lsw.walk() changes interval positions.

  if (!has_fpu_registers()) {
#ifdef ASSERT
    assert(not_precolored_fpu_intervals == Interval::end(), "missed an uncolored fpu interval");
#else
    if (not_precolored_fpu_intervals != Interval::end()) {
      BAILOUT("missed an uncolored fpu interval");
    }
#endif
  }

  // allocate cpu registers
  LinearScanWalker cpu_lsw(this, precolored_cpu_intervals, not_precolored_cpu_intervals);
  cpu_lsw.walk();
  cpu_lsw.finish_allocation();

  if (has_fpu_registers()) {
    // allocate fpu registers
    LinearScanWalker fpu_lsw(this, precolored_fpu_intervals, not_precolored_fpu_intervals);
    fpu_lsw.walk();
    fpu_lsw.finish_allocation();
  }
}


// ********** Phase 6: resolve data flow
// (insert moves at edges between blocks if intervals have been split)

// wrapper for Interval::split_child_at_op_id that performs a bailout in product mode
// instead of returning null
Interval* LinearScan::split_child_at_op_id(Interval* interval, int op_id, LIR_OpVisitState::OprMode mode) {
  Interval* result = interval->split_child_at_op_id(op_id, mode);
  if (result != nullptr) {
    return result;
  }

  assert(false, "must find an interval, but do a clean bailout in product mode");
  result = new Interval(LIR_Opr::vreg_base);
  result->assign_reg(0);
  result->set_type(T_INT);
  BAILOUT_("LinearScan: interval is null", result);
}


Interval* LinearScan::interval_at_block_begin(BlockBegin* block, int reg_num) {
  assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds");
  assert(interval_at(reg_num) != nullptr, "no interval found");

  return split_child_at_op_id(interval_at(reg_num), block->first_lir_instruction_id(), LIR_OpVisitState::outputMode);
}

Interval* LinearScan::interval_at_block_end(BlockBegin* block, int reg_num) {
  assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds");
  assert(interval_at(reg_num) != nullptr, "no interval found");

  return split_child_at_op_id(interval_at(reg_num), block->last_lir_instruction_id() + 1, LIR_OpVisitState::outputMode);
}

Interval* LinearScan::interval_at_op_id(int reg_num, int op_id) {
  assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds");
  assert(interval_at(reg_num) != nullptr, "no interval found");

  return split_child_at_op_id(interval_at(reg_num), op_id, LIR_OpVisitState::inputMode);
}


void LinearScan::resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver) {
  DEBUG_ONLY(move_resolver.check_empty());

  // visit all registers where the live_at_edge bit is set
  const ResourceBitMap& live_at_edge = to_block->live_in();
  auto visitor = [&](BitMap::idx_t index) {
    int r = static_cast<int>(index);
    assert(r < num_virtual_regs(), "live information set for not existing 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);
    Interval* to_interval = interval_at_block_begin(to_block, r);

    if (from_interval != to_interval && (from_interval->assigned_reg() != to_interval->assigned_reg() || from_interval->assigned_regHi() != to_interval->assigned_regHi())) {
      // need to insert move instruction
      move_resolver.add_mapping(from_interval, to_interval);
    }
  };
  live_at_edge.iterate(visitor, 0, live_set_size());
}


void LinearScan::resolve_find_insert_pos(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver) {
  if (from_block->number_of_sux() <= 1) {
    TRACE_LINEAR_SCAN(4, tty->print_cr("inserting moves at end of from_block B%d", from_block->block_id()));

    LIR_OpList* instructions = from_block->lir()->instructions_list();
    LIR_OpBranch* branch = instructions->last()->as_OpBranch();
    if (branch != nullptr) {
      // insert moves before branch
      assert(branch->cond() == lir_cond_always, "block does not end with an unconditional jump");
      move_resolver.set_insert_position(from_block->lir(), instructions->length() - 2);
    } else {
      move_resolver.set_insert_position(from_block->lir(), instructions->length() - 1);
    }

  } else {
    TRACE_LINEAR_SCAN(4, tty->print_cr("inserting moves at beginning of to_block B%d", to_block->block_id()));
#ifdef ASSERT
    assert(from_block->lir()->instructions_list()->at(0)->as_OpLabel() != nullptr, "block does not start with a label");

    // because the number of predecessor edges matches the number of
    // successor edges, blocks which are reached by switch statements
    // may have be more than one predecessor but it will be guaranteed
    // that all predecessors will be the same.
    for (int i = 0; i < to_block->number_of_preds(); i++) {
      assert(from_block == to_block->pred_at(i), "all critical edges must be broken");
    }
#endif

    move_resolver.set_insert_position(to_block->lir(), 0);
  }
}


// insert necessary moves (spilling or reloading) at edges between blocks if interval has been split
void LinearScan::resolve_data_flow() {
  TIME_LINEAR_SCAN(timer_resolve_data_flow);

  int num_blocks = block_count();
  MoveResolver move_resolver(this);
  ResourceBitMap block_completed(num_blocks);
  ResourceBitMap already_resolved(num_blocks);

  int i;
  for (i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);

    // check if block has only one predecessor and only one successor
    if (block->number_of_preds() == 1 && block->number_of_sux() == 1 && block->number_of_exception_handlers() == 0) {
      LIR_OpList* instructions = block->lir()->instructions_list();
      assert(instructions->at(0)->code() == lir_label, "block must start with label");
      assert(instructions->last()->code() == lir_branch, "block with successors must end with branch");
      assert(instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block with successor must end with unconditional branch");

      // check if block is empty (only label and branch)
      if (instructions->length() == 2) {
        BlockBegin* pred = block->pred_at(0);
        BlockBegin* sux = block->sux_at(0);

        // prevent optimization of two consecutive blocks
        if (!block_completed.at(pred->linear_scan_number()) && !block_completed.at(sux->linear_scan_number())) {
          TRACE_LINEAR_SCAN(3, tty->print_cr("**** optimizing empty block B%d (pred: B%d, sux: B%d)", block->block_id(), pred->block_id(), sux->block_id()));
          block_completed.set_bit(block->linear_scan_number());

          // directly resolve between pred and sux (without looking at the empty block between)
          resolve_collect_mappings(pred, sux, move_resolver);
          if (move_resolver.has_mappings()) {
            move_resolver.set_insert_position(block->lir(), 0);
            move_resolver.resolve_and_append_moves();
          }
        }
      }
    }
  }


  for (i = 0; i < num_blocks; i++) {
    if (!block_completed.at(i)) {
      BlockBegin* from_block = block_at(i);
      already_resolved.set_from(block_completed);

      int num_sux = from_block->number_of_sux();
      for (int s = 0; s < num_sux; s++) {
        BlockBegin* to_block = from_block->sux_at(s);

        // check for duplicate edges between the same blocks (can happen with switch blocks)
        if (!already_resolved.at(to_block->linear_scan_number())) {
          TRACE_LINEAR_SCAN(3, tty->print_cr("**** processing edge between B%d and B%d", from_block->block_id(), to_block->block_id()));
          already_resolved.set_bit(to_block->linear_scan_number());

          // collect all intervals that have been split between from_block and to_block
          resolve_collect_mappings(from_block, to_block, move_resolver);
          if (move_resolver.has_mappings()) {
            resolve_find_insert_pos(from_block, to_block, move_resolver);
            move_resolver.resolve_and_append_moves();
          }
        }
      }
    }
  }
}


void LinearScan::resolve_exception_entry(BlockBegin* block, int reg_num, MoveResolver &move_resolver) {
  if (interval_at(reg_num) == nullptr) {
    // if a phi function is never used, no interval is created -> ignore this
    return;
  }

  Interval* interval = interval_at_block_begin(block, reg_num);
  int reg = interval->assigned_reg();
  int regHi = interval->assigned_regHi();

  if ((reg < nof_regs && interval->always_in_memory()) ||
      (use_fpu_stack_allocation() && reg >= pd_first_fpu_reg && reg <= pd_last_fpu_reg)) {
    // the interval is split to get a short range that is located on the stack
    // in the following two cases:
    // * the interval started in memory (e.g. method parameter), but is currently in a register
    //   this is an optimization for exception handling that reduces the number of moves that
    //   are necessary for resolving the states when an exception uses this exception handler
    // * the interval would be on the fpu stack at the begin of the exception handler
    //   this is not allowed because of the complicated fpu stack handling on Intel

    // range that will be spilled to memory
    int from_op_id = block->first_lir_instruction_id();
    int to_op_id = from_op_id + 1;  // short live range of length 1
    assert(interval->from() <= from_op_id && interval->to() >= to_op_id,
           "no split allowed between exception entry and first instruction");

    if (interval->from() != from_op_id) {
      // the part before from_op_id is unchanged
      interval = interval->split(from_op_id);
      interval->assign_reg(reg, regHi);
      append_interval(interval);
    } else {
      _needs_full_resort = true;
    }
    assert(interval->from() == from_op_id, "must be true now");

    Interval* spilled_part = interval;
    if (interval->to() != to_op_id) {
      // the part after to_op_id is unchanged
      spilled_part = interval->split_from_start(to_op_id);
      append_interval(spilled_part);
      move_resolver.add_mapping(spilled_part, interval);
    }
    assign_spill_slot(spilled_part);

    assert(spilled_part->from() == from_op_id && spilled_part->to() == to_op_id, "just checking");
  }
}

void LinearScan::resolve_exception_entry(BlockBegin* block, MoveResolver &move_resolver) {
  assert(block->is_set(BlockBegin::exception_entry_flag), "should not call otherwise");
  DEBUG_ONLY(move_resolver.check_empty());

  // visit all registers where the live_in bit is set
  auto resolver = [&](BitMap::idx_t index) {
    int r = static_cast<int>(index);
    resolve_exception_entry(block, r, move_resolver);
  };
  block->live_in().iterate(resolver, 0, live_set_size());

  // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately
  for_each_phi_fun(block, phi,
    if (!phi->is_illegal()) { resolve_exception_entry(block, phi->operand()->vreg_number(), move_resolver); }
  );

  if (move_resolver.has_mappings()) {
    // insert moves after first instruction
    move_resolver.set_insert_position(block->lir(), 0);
    move_resolver.resolve_and_append_moves();
  }
}


void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, int reg_num, Phi* phi, MoveResolver &move_resolver) {
  if (interval_at(reg_num) == nullptr) {
    // if a phi function is never used, no interval is created -> ignore this
    return;
  }

  // the computation of to_interval is equal to resolve_collect_mappings,
  // but from_interval is more complicated because of phi functions
  BlockBegin* to_block = handler->entry_block();
  Interval* to_interval = interval_at_block_begin(to_block, reg_num);

  if (phi != nullptr) {
    // phi function of the exception entry block
    // no moves are created for this phi function in the LIR_Generator, so the
    // interval at the throwing instruction must be searched using the operands
    // of the phi function
    Value from_value = phi->operand_at(handler->phi_operand());
    if (from_value == nullptr) {
      // We have reached here in a kotlin application running with JVMTI
      // capability "can_access_local_variables".
      // The illegal state is not yet propagated to this phi. Do it here.
      phi->make_illegal();
      // We can skip the illegal phi edge.
      return;
    }

    // with phi functions it can happen that the same from_value is used in
    // multiple mappings, so notify move-resolver that this is allowed
    move_resolver.set_multiple_reads_allowed();

    Constant* con = from_value->as_Constant();
    if (con != nullptr && (!con->is_pinned() || con->operand()->is_constant())) {
      // Need a mapping from constant to interval if unpinned (may have no register) or if the operand is a constant (no register).
      move_resolver.add_mapping(LIR_OprFact::value_type(con->type()), to_interval);
    } else {
      // search split child at the throwing op_id
      Interval* from_interval = interval_at_op_id(from_value->operand()->vreg_number(), throwing_op_id);
      move_resolver.add_mapping(from_interval, to_interval);
    }
  } else {
    // no phi function, so use reg_num also for from_interval
    // search split child at the throwing op_id
    Interval* from_interval = interval_at_op_id(reg_num, throwing_op_id);
    if (from_interval != to_interval) {
      // optimization to reduce number of moves: when to_interval is on stack and
      // the stack slot is known to be always correct, then no move is necessary
      if (!from_interval->always_in_memory() || from_interval->canonical_spill_slot() != to_interval->assigned_reg()) {
        move_resolver.add_mapping(from_interval, to_interval);
      }
    }
  }
}

void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, MoveResolver &move_resolver) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("resolving exception handler B%d: throwing_op_id=%d", handler->entry_block()->block_id(), throwing_op_id));

  DEBUG_ONLY(move_resolver.check_empty());
  assert(handler->lir_op_id() == -1, "already processed this xhandler");
  DEBUG_ONLY(handler->set_lir_op_id(throwing_op_id));
  assert(handler->entry_code() == nullptr, "code already present");

  // visit all registers where the live_in bit is set
  BlockBegin* block = handler->entry_block();
  auto resolver = [&](BitMap::idx_t index) {
    int r = static_cast<int>(index);
    resolve_exception_edge(handler, throwing_op_id, r, nullptr, move_resolver);
  };
  block->live_in().iterate(resolver, 0, live_set_size());

  // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately
  for_each_phi_fun(block, phi,
    if (!phi->is_illegal()) { resolve_exception_edge(handler, throwing_op_id, phi->operand()->vreg_number(), phi, move_resolver); }
  );

  if (move_resolver.has_mappings()) {
    LIR_List* entry_code = new LIR_List(compilation());
    move_resolver.set_insert_position(entry_code, 0);
    move_resolver.resolve_and_append_moves();

    entry_code->jump(handler->entry_block());
    handler->set_entry_code(entry_code);
  }
}


void LinearScan::resolve_exception_handlers() {
  MoveResolver move_resolver(this);
  LIR_OpVisitState visitor;
  int num_blocks = block_count();

  int i;
  for (i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    if (block->is_set(BlockBegin::exception_entry_flag)) {
      resolve_exception_entry(block, move_resolver);
    }
  }

  for (i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    LIR_List* ops = block->lir();
    int num_ops = ops->length();

    // iterate all instructions of the block. skip the first because it is always a label
    assert(visitor.no_operands(ops->at(0)), "first operation must always be a label");
    for (int j = 1; j < num_ops; j++) {
      LIR_Op* op = ops->at(j);
      int op_id = op->id();

      if (op_id != -1 && has_info(op_id)) {
        // visit operation to collect all operands
        visitor.visit(op);
        assert(visitor.info_count() > 0, "should not visit otherwise");

        XHandlers* xhandlers = visitor.all_xhandler();
        int n = xhandlers->length();
        for (int k = 0; k < n; k++) {
          resolve_exception_edge(xhandlers->handler_at(k), op_id, move_resolver);
        }

#ifdef ASSERT
      } else {
        visitor.visit(op);
        assert(visitor.all_xhandler()->length() == 0, "missed exception handler");
#endif
      }
    }
  }
}


// ********** Phase 7: assign register numbers back to LIR
// (includes computation of debug information and oop maps)

VMReg LinearScan::vm_reg_for_interval(Interval* interval) {
  VMReg reg = interval->cached_vm_reg();
  if (!reg->is_valid() ) {
    reg = vm_reg_for_operand(operand_for_interval(interval));
    interval->set_cached_vm_reg(reg);
  }
  assert(reg == vm_reg_for_operand(operand_for_interval(interval)), "wrong cached value");
  return reg;
}

VMReg LinearScan::vm_reg_for_operand(LIR_Opr opr) {
  assert(opr->is_oop(), "currently only implemented for oop operands");
  return frame_map()->regname(opr);
}


LIR_Opr LinearScan::operand_for_interval(Interval* interval) {
  LIR_Opr opr = interval->cached_opr();
  if (opr->is_illegal()) {
    opr = calc_operand_for_interval(interval);
    interval->set_cached_opr(opr);
  }

  assert(opr == calc_operand_for_interval(interval), "wrong cached value");
  return opr;
}

LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) {
  int assigned_reg = interval->assigned_reg();
  BasicType type = interval->type();

  if (assigned_reg >= nof_regs) {
    // stack slot
    assert(interval->assigned_regHi() == any_reg, "must not have hi register");
    return LIR_OprFact::stack(assigned_reg - nof_regs, type);

  } else {
    // register
    switch (type) {
      case T_OBJECT: {
        assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register");
        return LIR_OprFact::single_cpu_oop(assigned_reg);
      }

      case T_ADDRESS: {
        assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register");
        return LIR_OprFact::single_cpu_address(assigned_reg);
      }

      case T_METADATA: {
        assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register");
        return LIR_OprFact::single_cpu_metadata(assigned_reg);
      }

#ifdef __SOFTFP__
      case T_FLOAT:  // fall through
#endif // __SOFTFP__
      case T_INT: {
        assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register");
        return LIR_OprFact::single_cpu(assigned_reg);
      }

#ifdef __SOFTFP__
      case T_DOUBLE:  // fall through
#endif // __SOFTFP__
      case T_LONG: {
        int assigned_regHi = interval->assigned_regHi();
        assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register");
        assert(num_physical_regs(T_LONG) == 1 ||
               (assigned_regHi >= pd_first_cpu_reg && assigned_regHi <= pd_last_cpu_reg), "no cpu register");

        assert(assigned_reg != assigned_regHi, "invalid allocation");
        assert(num_physical_regs(T_LONG) == 1 || assigned_reg < assigned_regHi,
               "register numbers must be sorted (ensure that e.g. a move from eax,ebx to ebx,eax can not occur)");
        assert((assigned_regHi != any_reg) ^ (num_physical_regs(T_LONG) == 1), "must be match");
        if (requires_adjacent_regs(T_LONG)) {
          assert(assigned_reg % 2 == 0 && assigned_reg + 1 == assigned_regHi, "must be sequential and even");
        }

#ifdef _LP64
        return LIR_OprFact::double_cpu(assigned_reg, assigned_reg);
#else
        return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi);
#endif // LP64
      }

#ifndef __SOFTFP__
      case T_FLOAT: {
#ifdef X86
        if (UseSSE >= 1) {
          int last_xmm_reg = pd_last_xmm_reg;
#ifdef _LP64
          if (UseAVX < 3) {
            last_xmm_reg = pd_first_xmm_reg + (pd_nof_xmm_regs_frame_map / 2) - 1;
          }
#endif // LP64
          assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= last_xmm_reg, "no xmm register");
          assert(interval->assigned_regHi() == any_reg, "must not have hi register");
          return LIR_OprFact::single_xmm(assigned_reg - pd_first_xmm_reg);
        }
#endif // X86

        assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register");
        return LIR_OprFact::single_fpu(assigned_reg - pd_first_fpu_reg);
      }

      case T_DOUBLE: {
#ifdef X86
        if (UseSSE >= 2) {
          int last_xmm_reg = pd_last_xmm_reg;
#ifdef _LP64
          if (UseAVX < 3) {
            last_xmm_reg = pd_first_xmm_reg + (pd_nof_xmm_regs_frame_map / 2) - 1;
          }
#endif // LP64
          assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= last_xmm_reg, "no xmm register");
          assert(interval->assigned_regHi() == any_reg, "must not have hi register (double xmm values are stored in one register)");
          return LIR_OprFact::double_xmm(assigned_reg - pd_first_xmm_reg);
        }
#endif // X86

#if defined(ARM32)
        assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register");
        assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register");
        assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even");
        LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg, interval->assigned_regHi() - pd_first_fpu_reg);
#else
        assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register");
        assert(interval->assigned_regHi() == any_reg, "must not have hi register (double fpu values are stored in one register on Intel)");
        LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg);
#endif
        return result;
      }
#endif // __SOFTFP__

      default: {
        ShouldNotReachHere();
        return LIR_OprFact::illegalOpr;
      }
    }
  }
}

LIR_Opr LinearScan::canonical_spill_opr(Interval* interval) {
  assert(interval->canonical_spill_slot() >= nof_regs, "canonical spill slot not set");
  return LIR_OprFact::stack(interval->canonical_spill_slot() - nof_regs, interval->type());
}

LIR_Opr LinearScan::color_lir_opr(LIR_Opr opr, int op_id, LIR_OpVisitState::OprMode mode) {
  assert(opr->is_virtual(), "should not call this otherwise");

  Interval* interval = interval_at(opr->vreg_number());
  assert(interval != nullptr, "interval must exist");

  if (op_id != -1) {
#ifdef ASSERT
    BlockBegin* block = block_of_op_with_id(op_id);
    if (block->number_of_sux() <= 1 && op_id == block->last_lir_instruction_id()) {
      // check if spill moves could have been appended at the end of this block, but
      // before the branch instruction. So the split child information for this branch would
      // be incorrect.
      LIR_OpBranch* branch = block->lir()->instructions_list()->last()->as_OpBranch();
      if (branch != nullptr) {
        if (block->live_out().at(opr->vreg_number())) {
          assert(branch->cond() == lir_cond_always, "block does not end with an unconditional jump");
          assert(false, "can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolve_data_flow)");
        }
      }
    }
#endif

    // operands are not changed when an interval is split during allocation,
    // so search the right interval here
    interval = split_child_at_op_id(interval, op_id, mode);
  }

  LIR_Opr res = operand_for_interval(interval);

#ifdef X86
  // new semantic for is_last_use: not only set on definite end of interval,
  // but also before hole
  // This may still miss some cases (e.g. for dead values), but it is not necessary that the
  // last use information is completely correct
  // information is only needed for fpu stack allocation
  if (res->is_fpu_register()) {
    if (opr->is_last_use() || op_id == interval->to() || (op_id != -1 && interval->has_hole_between(op_id, op_id + 1))) {
      assert(op_id == -1 || !is_block_begin(op_id), "holes at begin of block may also result from control flow");
      res = res->make_last_use();
    }
  }
#endif

  assert(!gen()->is_vreg_flag_set(opr->vreg_number(), LIRGenerator::callee_saved) || !FrameMap::is_caller_save_register(res), "bad allocation");

  return res;
}


#ifdef ASSERT
// some methods used to check correctness of debug information

void assert_no_register_values(GrowableArray<ScopeValue*>* values) {
  if (values == nullptr) {
    return;
  }

  for (int i = 0; i < values->length(); i++) {
    ScopeValue* value = values->at(i);

    if (value->is_location()) {
      Location location = ((LocationValue*)value)->location();
      assert(location.where() == Location::on_stack, "value is in register");
    }
  }
}

void assert_no_register_values(GrowableArray<MonitorValue*>* values) {
  if (values == nullptr) {
    return;
  }

  for (int i = 0; i < values->length(); i++) {
    MonitorValue* value = values->at(i);

    if (value->owner()->is_location()) {
      Location location = ((LocationValue*)value->owner())->location();
      assert(location.where() == Location::on_stack, "owner is in register");
    }
    assert(value->basic_lock().where() == Location::on_stack, "basic_lock is in register");
  }
}

void assert_equal(Location l1, Location l2) {
  assert(l1.where() == l2.where() && l1.type() == l2.type() && l1.offset() == l2.offset(), "");
}

void assert_equal(ScopeValue* v1, ScopeValue* v2) {
  if (v1->is_location()) {
    assert(v2->is_location(), "");
    assert_equal(((LocationValue*)v1)->location(), ((LocationValue*)v2)->location());
  } else if (v1->is_constant_int()) {
    assert(v2->is_constant_int(), "");
    assert(((ConstantIntValue*)v1)->value() == ((ConstantIntValue*)v2)->value(), "");
  } else if (v1->is_constant_double()) {
    assert(v2->is_constant_double(), "");
    assert(((ConstantDoubleValue*)v1)->value() == ((ConstantDoubleValue*)v2)->value(), "");
  } else if (v1->is_constant_long()) {
    assert(v2->is_constant_long(), "");
    assert(((ConstantLongValue*)v1)->value() == ((ConstantLongValue*)v2)->value(), "");
  } else if (v1->is_constant_oop()) {
    assert(v2->is_constant_oop(), "");
    assert(((ConstantOopWriteValue*)v1)->value() == ((ConstantOopWriteValue*)v2)->value(), "");
  } else {
    ShouldNotReachHere();
  }
}

void assert_equal(MonitorValue* m1, MonitorValue* m2) {
  assert_equal(m1->owner(), m2->owner());
  assert_equal(m1->basic_lock(), m2->basic_lock());
}

void assert_equal(IRScopeDebugInfo* d1, IRScopeDebugInfo* d2) {
  assert(d1->scope() == d2->scope(), "not equal");
  assert(d1->bci() == d2->bci(), "not equal");

  if (d1->locals() != nullptr) {
    assert(d1->locals() != nullptr && d2->locals() != nullptr, "not equal");
    assert(d1->locals()->length() == d2->locals()->length(), "not equal");
    for (int i = 0; i < d1->locals()->length(); i++) {
      assert_equal(d1->locals()->at(i), d2->locals()->at(i));
    }
  } else {
    assert(d1->locals() == nullptr && d2->locals() == nullptr, "not equal");
  }

  if (d1->expressions() != nullptr) {
    assert(d1->expressions() != nullptr && d2->expressions() != nullptr, "not equal");
    assert(d1->expressions()->length() == d2->expressions()->length(), "not equal");
    for (int i = 0; i < d1->expressions()->length(); i++) {
      assert_equal(d1->expressions()->at(i), d2->expressions()->at(i));
    }
  } else {
    assert(d1->expressions() == nullptr && d2->expressions() == nullptr, "not equal");
  }

  if (d1->monitors() != nullptr) {
    assert(d1->monitors() != nullptr && d2->monitors() != nullptr, "not equal");
    assert(d1->monitors()->length() == d2->monitors()->length(), "not equal");
    for (int i = 0; i < d1->monitors()->length(); i++) {
      assert_equal(d1->monitors()->at(i), d2->monitors()->at(i));
    }
  } else {
    assert(d1->monitors() == nullptr && d2->monitors() == nullptr, "not equal");
  }

  if (d1->caller() != nullptr) {
    assert(d1->caller() != nullptr && d2->caller() != nullptr, "not equal");
    assert_equal(d1->caller(), d2->caller());
  } else {
    assert(d1->caller() == nullptr && d2->caller() == nullptr, "not equal");
  }
}

void check_stack_depth(CodeEmitInfo* info, int stack_end) {
  if (info->stack()->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) {
    Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci());
    switch (code) {
      case Bytecodes::_ifnull    : // fall through
      case Bytecodes::_ifnonnull : // fall through
      case Bytecodes::_ifeq      : // fall through
      case Bytecodes::_ifne      : // fall through
      case Bytecodes::_iflt      : // fall through
      case Bytecodes::_ifge      : // fall through
      case Bytecodes::_ifgt      : // fall through
      case Bytecodes::_ifle      : // fall through
      case Bytecodes::_if_icmpeq : // fall through
      case Bytecodes::_if_icmpne : // fall through
      case Bytecodes::_if_icmplt : // fall through
      case Bytecodes::_if_icmpge : // fall through
      case Bytecodes::_if_icmpgt : // fall through
      case Bytecodes::_if_icmple : // fall through
      case Bytecodes::_if_acmpeq : // fall through
      case Bytecodes::_if_acmpne :
        assert(stack_end >= -Bytecodes::depth(code), "must have non-empty expression stack at if bytecode");
        break;
      default:
        break;
    }
  }
}

#endif // ASSERT


IntervalWalker* LinearScan::init_compute_oop_maps() {
  // setup lists of potential oops for walking
  Interval* oop_intervals;
  Interval* non_oop_intervals;

  create_unhandled_lists(&oop_intervals, &non_oop_intervals, is_oop_interval, nullptr);

  // intervals that have no oops inside need not to be processed
  // to ensure a walking until the last instruction id, add a dummy interval
  // with a high operation id
  non_oop_intervals = new Interval(any_reg);
  non_oop_intervals->add_range(max_jint - 2, max_jint - 1);

  return new IntervalWalker(this, oop_intervals, non_oop_intervals);
}


OopMap* LinearScan::compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo* info, bool is_call_site) {
  TRACE_LINEAR_SCAN(3, tty->print_cr("creating oop map at op_id %d", op->id()));

  // walk before the current operation -> intervals that start at
  // the operation (= output operands of the operation) are not
  // included in the oop map
  iw->walk_before(op->id());

  int frame_size = frame_map()->framesize();
  int arg_count = frame_map()->oop_map_arg_count();
  OopMap* map = new OopMap(frame_size, arg_count);

  // Iterate through active intervals
  for (Interval* interval = iw->active_first(fixedKind); interval != Interval::end(); interval = interval->next()) {
    int assigned_reg = interval->assigned_reg();

    assert(interval->current_from() <= op->id() && op->id() <= interval->current_to(), "interval should not be active otherwise");
    assert(interval->assigned_regHi() == any_reg, "oop must be single word");
    assert(interval->reg_num() >= LIR_Opr::vreg_base, "fixed interval found");

    // Check if this range covers the instruction. Intervals that
    // start or end at the current operation are not included in the
    // oop map, except in the case of patching moves.  For patching
    // moves, any intervals which end at this instruction are included
    // in the oop map since we may safepoint while doing the patch
    // before we've consumed the inputs.
    if (op->is_patching() || op->id() < interval->current_to()) {

      // caller-save registers must not be included into oop-maps at calls
      assert(!is_call_site || assigned_reg >= nof_regs || !is_caller_save(assigned_reg), "interval is in a caller-save register at a call -> register will be overwritten");

      VMReg name = vm_reg_for_interval(interval);
      set_oop(map, name);

      // Spill optimization: when the stack value is guaranteed to be always correct,
      // then it must be added to the oop map even if the interval is currently in a register
      if (interval->always_in_memory() &&
          op->id() > interval->spill_definition_pos() &&
          interval->assigned_reg() != interval->canonical_spill_slot()) {
        assert(interval->spill_definition_pos() > 0, "position not set correctly");
        assert(interval->canonical_spill_slot() >= LinearScan::nof_regs, "no spill slot assigned");
        assert(interval->assigned_reg() < LinearScan::nof_regs, "interval is on stack, so stack slot is registered twice");

        set_oop(map, frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs));
      }
    }
  }

  // add oops from lock stack
  assert(info->stack() != nullptr, "CodeEmitInfo must always have a stack");
  int locks_count = info->stack()->total_locks_size();
  for (int i = 0; i < locks_count; i++) {
    set_oop(map, frame_map()->monitor_object_regname(i));
  }

  return map;
}


void LinearScan::compute_oop_map(IntervalWalker* iw, const LIR_OpVisitState &visitor, LIR_Op* op) {
  assert(visitor.info_count() > 0, "no oop map needed");

  // compute oop_map only for first CodeEmitInfo
  // because it is (in most cases) equal for all other infos of the same operation
  CodeEmitInfo* first_info = visitor.info_at(0);
  OopMap* first_oop_map = compute_oop_map(iw, op, first_info, visitor.has_call());

  for (int i = 0; i < visitor.info_count(); i++) {
    CodeEmitInfo* info = visitor.info_at(i);
    OopMap* oop_map = first_oop_map;

    // compute worst case interpreter size in case of a deoptimization
    _compilation->update_interpreter_frame_size(info->interpreter_frame_size());

    if (info->stack()->locks_size() != first_info->stack()->locks_size()) {
      // this info has a different number of locks then the precomputed oop map
      // (possible for lock and unlock instructions) -> compute oop map with
      // correct lock information
      oop_map = compute_oop_map(iw, op, info, visitor.has_call());
    }

    if (info->_oop_map == nullptr) {
      info->_oop_map = oop_map;
    } else {
      // a CodeEmitInfo can not be shared between different LIR-instructions
      // because interval splitting can occur anywhere between two instructions
      // and so the oop maps must be different
      // -> check if the already set oop_map is exactly the one calculated for this operation
      assert(info->_oop_map == oop_map, "same CodeEmitInfo used for multiple LIR instructions");
    }
  }
}


// frequently used constants
// Allocate them with new so they are never destroyed (otherwise, a
// forced exit could destroy these objects while they are still in
// use).
ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (mtCompiler) ConstantOopWriteValue(nullptr);
ConstantIntValue*      LinearScan::_int_m1_scope_value = new (mtCompiler) ConstantIntValue(-1);
ConstantIntValue*      LinearScan::_int_0_scope_value =  new (mtCompiler) ConstantIntValue((jint)0);
ConstantIntValue*      LinearScan::_int_1_scope_value =  new (mtCompiler) ConstantIntValue(1);
ConstantIntValue*      LinearScan::_int_2_scope_value =  new (mtCompiler) ConstantIntValue(2);
LocationValue*         _illegal_value = new (mtCompiler) LocationValue(Location());

void LinearScan::init_compute_debug_info() {
  // cache for frequently used scope values
  // (cpu registers and stack slots)
  int cache_size = (LinearScan::nof_cpu_regs + frame_map()->argcount() + max_spills()) * 2;
  _scope_value_cache = ScopeValueArray(cache_size, cache_size, nullptr);
}

MonitorValue* LinearScan::location_for_monitor_index(int monitor_index) {
  Location loc;
  if (!frame_map()->location_for_monitor_object(monitor_index, &loc)) {
    bailout("too large frame");
  }
  ScopeValue* object_scope_value = new LocationValue(loc);

  if (!frame_map()->location_for_monitor_lock(monitor_index, &loc)) {
    bailout("too large frame");
  }
  return new MonitorValue(object_scope_value, loc);
}

LocationValue* LinearScan::location_for_name(int name, Location::Type loc_type) {
  Location loc;
  if (!frame_map()->locations_for_slot(name, loc_type, &loc)) {
    bailout("too large frame");
  }
  return new LocationValue(loc);
}


int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values) {
  assert(opr->is_constant(), "should not be called otherwise");

  LIR_Const* c = opr->as_constant_ptr();
  BasicType t = c->type();
  switch (t) {
    case T_OBJECT: {
      jobject value = c->as_jobject();
      if (value == nullptr) {
        scope_values->append(_oop_null_scope_value);
      } else {
        scope_values->append(new ConstantOopWriteValue(c->as_jobject()));
      }
      return 1;
    }

    case T_INT: // fall through
    case T_FLOAT: {
      int value = c->as_jint_bits();
      switch (value) {
        case -1: scope_values->append(_int_m1_scope_value); break;
        case 0:  scope_values->append(_int_0_scope_value); break;
        case 1:  scope_values->append(_int_1_scope_value); break;
        case 2:  scope_values->append(_int_2_scope_value); break;
        default: scope_values->append(new ConstantIntValue(c->as_jint_bits())); break;
      }
      return 1;
    }

    case T_LONG: // fall through
    case T_DOUBLE: {
#ifdef _LP64
      scope_values->append(_int_0_scope_value);
      scope_values->append(new ConstantLongValue(c->as_jlong_bits()));
#else
      if (hi_word_offset_in_bytes > lo_word_offset_in_bytes) {
        scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
        scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
      } else {
        scope_values->append(new ConstantIntValue(c->as_jint_lo_bits()));
        scope_values->append(new ConstantIntValue(c->as_jint_hi_bits()));
      }
#endif
      return 2;
    }

    case T_ADDRESS: {
#ifdef _LP64
      scope_values->append(new ConstantLongValue(c->as_jint()));
#else
      scope_values->append(new ConstantIntValue(c->as_jint()));
#endif
      return 1;
    }

    default:
      ShouldNotReachHere();
      return -1;
  }
}

int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values) {
  if (opr->is_single_stack()) {
    int stack_idx = opr->single_stack_ix();
    bool is_oop = opr->is_oop_register();
    int cache_idx = (stack_idx + LinearScan::nof_cpu_regs) * 2 + (is_oop ? 1 : 0);

    ScopeValue* sv = _scope_value_cache.at(cache_idx);
    if (sv == nullptr) {
      Location::Type loc_type = is_oop ? Location::oop : Location::normal;
      sv = location_for_name(stack_idx, loc_type);
      _scope_value_cache.at_put(cache_idx, sv);
    }

    // check if cached value is correct
    DEBUG_ONLY(assert_equal(sv, location_for_name(stack_idx, is_oop ? Location::oop : Location::normal)));

    scope_values->append(sv);
    return 1;

  } else if (opr->is_single_cpu()) {
    bool is_oop = opr->is_oop_register();
    int cache_idx = opr->cpu_regnr() * 2 + (is_oop ? 1 : 0);
    Location::Type int_loc_type = NOT_LP64(Location::normal) LP64_ONLY(Location::int_in_long);

    ScopeValue* sv = _scope_value_cache.at(cache_idx);
    if (sv == nullptr) {
      Location::Type loc_type = is_oop ? Location::oop : int_loc_type;
      VMReg rname = frame_map()->regname(opr);
      sv = new LocationValue(Location::new_reg_loc(loc_type, rname));
      _scope_value_cache.at_put(cache_idx, sv);
    }

    // check if cached value is correct
    DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : int_loc_type, frame_map()->regname(opr)))));

    scope_values->append(sv);
    return 1;

#ifdef X86
  } else if (opr->is_single_xmm()) {
    VMReg rname = opr->as_xmm_float_reg()->as_VMReg();
    LocationValue* sv = new LocationValue(Location::new_reg_loc(Location::normal, rname));

    scope_values->append(sv);
    return 1;
#endif

  } else if (opr->is_single_fpu()) {
#ifdef IA32
    // the exact location of fpu stack values is only known
    // during fpu stack allocation, so the stack allocator object
    // must be present
    assert(use_fpu_stack_allocation(), "should not have float stack values without fpu stack allocation (all floats must be SSE2)");
    assert(_fpu_stack_allocator != nullptr, "must be present");
    opr = _fpu_stack_allocator->to_fpu_stack(opr);
#elif defined(AMD64)
    assert(false, "FPU not used on x86-64");
#endif

    Location::Type loc_type = float_saved_as_double ? Location::float_in_dbl : Location::normal;
    VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr());
#ifndef __SOFTFP__
#ifndef VM_LITTLE_ENDIAN
    // On S390 a (single precision) float value occupies only the high
    // word of the full double register. So when the double register is
    // stored to memory (e.g. by the RegisterSaver), then the float value
    // is found at offset 0. I.e. the code below is not needed on S390.
#ifndef S390
    if (! float_saved_as_double) {
      // On big endian system, we may have an issue if float registers use only
      // the low half of the (same) double registers.
      // Both the float and the double could have the same regnr but would correspond
      // to two different addresses once saved.

      // get next safely (no assertion checks)
      VMReg next = VMRegImpl::as_VMReg(1+rname->value());
      if (next->is_reg() &&
          (next->as_FloatRegister() == rname->as_FloatRegister())) {
        // the back-end does use the same numbering for the double and the float
        rname = next; // VMReg for the low bits, e.g. the real VMReg for the float
      }
    }
#endif // !S390
#endif
#endif
    LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname));

    scope_values->append(sv);
    return 1;

  } else {
    // double-size operands

    ScopeValue* first;
    ScopeValue* second;

    if (opr->is_double_stack()) {
#ifdef _LP64
      Location loc1;
      Location::Type loc_type = opr->type() == T_LONG ? Location::lng : Location::dbl;
      if (!frame_map()->locations_for_slot(opr->double_stack_ix(), loc_type, &loc1, nullptr)) {
        bailout("too large frame");
      }

      first =  new LocationValue(loc1);
      second = _int_0_scope_value;
#else
      Location loc1, loc2;
      if (!frame_map()->locations_for_slot(opr->double_stack_ix(), Location::normal, &loc1, &loc2)) {
        bailout("too large frame");
      }
      first =  new LocationValue(loc1);
      second = new LocationValue(loc2);
#endif // _LP64

    } else if (opr->is_double_cpu()) {
#ifdef _LP64
      VMReg rname_first = opr->as_register_lo()->as_VMReg();
      first = new LocationValue(Location::new_reg_loc(Location::lng, rname_first));
      second = _int_0_scope_value;
#else
      VMReg rname_first = opr->as_register_lo()->as_VMReg();
      VMReg rname_second = opr->as_register_hi()->as_VMReg();

      if (hi_word_offset_in_bytes < lo_word_offset_in_bytes) {
        // lo/hi and swapped relative to first and second, so swap them
        VMReg tmp = rname_first;
        rname_first = rname_second;
        rname_second = tmp;
      }

      first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
      second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
#endif //_LP64


#ifdef X86
    } else if (opr->is_double_xmm()) {
      assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation");
      VMReg rname_first  = opr->as_xmm_double_reg()->as_VMReg();
#  ifdef _LP64
      first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
      second = _int_0_scope_value;
#  else
      first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
      // %%% This is probably a waste but we'll keep things as they were for now
      if (true) {
        VMReg rname_second = rname_first->next();
        second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
      }
#  endif
#endif

    } else if (opr->is_double_fpu()) {
      // On SPARC, fpu_regnrLo/fpu_regnrHi represents the two halves of
      // the double as float registers in the native ordering. On X86,
      // fpu_regnrLo is a FPU stack slot whose VMReg represents
      // the low-order word of the double and fpu_regnrLo + 1 is the
      // name for the other half.  *first and *second must represent the
      // least and most significant words, respectively.

#ifdef IA32
      // the exact location of fpu stack values is only known
      // during fpu stack allocation, so the stack allocator object
      // must be present
      assert(use_fpu_stack_allocation(), "should not have float stack values without fpu stack allocation (all floats must be SSE2)");
      assert(_fpu_stack_allocator != nullptr, "must be present");
      opr = _fpu_stack_allocator->to_fpu_stack(opr);

      assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrLo is used)");
#endif
#ifdef AMD64
      assert(false, "FPU not used on x86-64");
#endif
#ifdef ARM32
      assert(opr->fpu_regnrHi() == opr->fpu_regnrLo() + 1, "assumed in calculation (only fpu_regnrLo is used)");
#endif

#ifdef VM_LITTLE_ENDIAN
      VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrLo());
#else
      VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi());
#endif

#ifdef _LP64
      first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first));
      second = _int_0_scope_value;
#else
      first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first));
      // %%% This is probably a waste but we'll keep things as they were for now
      if (true) {
        VMReg rname_second = rname_first->next();
        second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second));
      }
#endif

    } else {
      ShouldNotReachHere();
      first = nullptr;
      second = nullptr;
    }

    assert(first != nullptr && second != nullptr, "must be set");
    // The convention the interpreter uses is that the second local
    // holds the first raw word of the native double representation.
    // This is actually reasonable, since locals and stack arrays
    // grow downwards in all implementations.
    // (If, on some machine, the interpreter's Java locals or stack
    // were to grow upwards, the embedded doubles would be word-swapped.)
    scope_values->append(second);
    scope_values->append(first);
    return 2;
  }
}


int LinearScan::append_scope_value(int op_id, Value value, GrowableArray<ScopeValue*>* scope_values) {
  if (value != nullptr) {
    LIR_Opr opr = value->operand();
    Constant* con = value->as_Constant();

    assert(con == nullptr || opr->is_virtual() || opr->is_constant() || opr->is_illegal(), "assumption: Constant instructions have only constant operands (or illegal if constant is optimized away)");
    assert(con != nullptr || opr->is_virtual(), "assumption: non-Constant instructions have only virtual operands");

    if (con != nullptr && !con->is_pinned() && !opr->is_constant()) {
      // Unpinned constants may have a virtual operand for a part of the lifetime
      // or may be illegal when it was optimized away,
      // so always use a constant operand
      opr = LIR_OprFact::value_type(con->type());
    }
    assert(opr->is_virtual() || opr->is_constant(), "other cases not allowed here");

    if (opr->is_virtual()) {
      LIR_OpVisitState::OprMode mode = LIR_OpVisitState::inputMode;

      BlockBegin* block = block_of_op_with_id(op_id);
      if (block->number_of_sux() == 1 && op_id == block->last_lir_instruction_id()) {
        // generating debug information for the last instruction of a block.
        // if this instruction is a branch, spill moves are inserted before this branch
        // and so the wrong operand would be returned (spill moves at block boundaries are not
        // considered in the live ranges of intervals)
        // Solution: use the first op_id of the branch target block instead.
        if (block->lir()->instructions_list()->last()->as_OpBranch() != nullptr) {
          if (block->live_out().at(opr->vreg_number())) {
            op_id = block->sux_at(0)->first_lir_instruction_id();
            mode = LIR_OpVisitState::outputMode;
          }
        }
      }

      // Get current location of operand
      // The operand must be live because debug information is considered when building the intervals
      // if the interval is not live, color_lir_opr will cause an assertion failure
      opr = color_lir_opr(opr, op_id, mode);
      assert(!has_call(op_id) || opr->is_stack() || !is_caller_save(reg_num(opr)), "can not have caller-save register operands at calls");

      // Append to ScopeValue array
      return append_scope_value_for_operand(opr, scope_values);

    } else {
      assert(value->as_Constant() != nullptr, "all other instructions have only virtual operands");
      assert(opr->is_constant(), "operand must be constant");

      return append_scope_value_for_constant(opr, scope_values);
    }
  } else {
    // append a dummy value because real value not needed
    scope_values->append(_illegal_value);
    return 1;
  }
}


IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state) {
  IRScopeDebugInfo* caller_debug_info = nullptr;

  ValueStack* caller_state = cur_state->caller_state();
  if (caller_state != nullptr) {
    // process recursively to compute outermost scope first
    caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state);
  }

  // initialize these to null.
  // If we don't need deopt info or there are no locals, expressions or monitors,
  // then these get recorded as no information and avoids the allocation of 0 length arrays.
  GrowableArray<ScopeValue*>*   locals      = nullptr;
  GrowableArray<ScopeValue*>*   expressions = nullptr;
  GrowableArray<MonitorValue*>* monitors    = nullptr;

  // describe local variable values
  int nof_locals = cur_state->locals_size();
  if (nof_locals > 0) {
    locals = new GrowableArray<ScopeValue*>(nof_locals);

    int pos = 0;
    while (pos < nof_locals) {
      assert(pos < cur_state->locals_size(), "why not?");

      Value local = cur_state->local_at(pos);
      pos += append_scope_value(op_id, local, locals);

      assert(locals->length() == pos, "must match");
    }
    assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals");
    assert(locals->length() == cur_state->locals_size(), "wrong number of locals");
  } else if (cur_scope->method()->max_locals() > 0) {
    assert(cur_state->kind() == ValueStack::EmptyExceptionState, "should be");
    nof_locals = cur_scope->method()->max_locals();
    locals = new GrowableArray<ScopeValue*>(nof_locals);
    for(int i = 0; i < nof_locals; i++) {
      locals->append(_illegal_value);
    }
  }

  // describe expression stack
  int nof_stack = cur_state->stack_size();
  if (nof_stack > 0) {
    expressions = new GrowableArray<ScopeValue*>(nof_stack);

    int pos = 0;
    while (pos < nof_stack) {
      Value expression = cur_state->stack_at_inc(pos);
      append_scope_value(op_id, expression, expressions);

      assert(expressions->length() == pos, "must match");
    }
    assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries");
  }

  // describe monitors
  int nof_locks = cur_state->locks_size();
  if (nof_locks > 0) {
    int lock_offset = cur_state->caller_state() != nullptr ? cur_state->caller_state()->total_locks_size() : 0;
    monitors = new GrowableArray<MonitorValue*>(nof_locks);
    for (int i = 0; i < nof_locks; i++) {
      monitors->append(location_for_monitor_index(lock_offset + i));
    }
  }

  return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info);
}


void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) {
  TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id));

  IRScope* innermost_scope = info->scope();
  ValueStack* innermost_state = info->stack();

  assert(innermost_scope != nullptr && innermost_state != nullptr, "why is it missing?");

  DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size()));

  if (info->_scope_debug_info == nullptr) {
    // compute debug information
    info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state);
  } else {
    // debug information already set. Check that it is correct from the current point of view
    DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state)));
  }
}


void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) {
  LIR_OpVisitState visitor;
  int num_inst = instructions->length();
  bool has_dead = false;

  for (int j = 0; j < num_inst; j++) {
    LIR_Op* op = instructions->at(j);
    if (op == nullptr) { // this can happen when spill-moves are removed in eliminate_spill_moves
      has_dead = true;
      continue;
    }
    int op_id = op->id();

    // visit instruction to get list of operands
    visitor.visit(op);

    // iterate all modes of the visitor and process all virtual operands
    for_each_visitor_mode(mode) {
      int n = visitor.opr_count(mode);
      for (int k = 0; k < n; k++) {
        LIR_Opr opr = visitor.opr_at(mode, k);
        if (opr->is_virtual_register()) {
          visitor.set_opr_at(mode, k, color_lir_opr(opr, op_id, mode));
        }
      }
    }

    if (visitor.info_count() > 0) {
      // exception handling
      if (compilation()->has_exception_handlers()) {
        XHandlers* xhandlers = visitor.all_xhandler();
        int n = xhandlers->length();
        for (int k = 0; k < n; k++) {
          XHandler* handler = xhandlers->handler_at(k);
          if (handler->entry_code() != nullptr) {
            assign_reg_num(handler->entry_code()->instructions_list(), nullptr);
          }
        }
      } else {
        assert(visitor.all_xhandler()->length() == 0, "missed exception handler");
      }

      // compute oop map
      assert(iw != nullptr, "needed for compute_oop_map");
      compute_oop_map(iw, visitor, op);

      // compute debug information
      if (!use_fpu_stack_allocation()) {
        // compute debug information if fpu stack allocation is not needed.
        // when fpu stack allocation is needed, the debug information can not
        // be computed here because the exact location of fpu operands is not known
        // -> debug information is created inside the fpu stack allocator
        int n = visitor.info_count();
        for (int k = 0; k < n; k++) {
          compute_debug_info(visitor.info_at(k), op_id);
        }
      }
    }

#ifdef ASSERT
    // make sure we haven't made the op invalid.
    op->verify();
#endif

    // remove useless moves
    if (op->code() == lir_move) {
      assert(op->as_Op1() != nullptr, "move must be LIR_Op1");
      LIR_Op1* move = (LIR_Op1*)op;
      LIR_Opr src = move->in_opr();
      LIR_Opr dst = move->result_opr();
      if (dst == src ||
          (!dst->is_pointer() && !src->is_pointer() &&
           src->is_same_register(dst))) {
        instructions->at_put(j, nullptr);
        has_dead = true;
      }
    }
  }

  if (has_dead) {
    // iterate all instructions of the block and remove all null-values.
    int insert_point = 0;
    for (int j = 0; j < num_inst; j++) {
      LIR_Op* op = instructions->at(j);
      if (op != nullptr) {
        if (insert_point != j) {
          instructions->at_put(insert_point, op);
        }
        insert_point++;
      }
    }
    instructions->trunc_to(insert_point);
  }
}

void LinearScan::assign_reg_num() {
  TIME_LINEAR_SCAN(timer_assign_reg_num);

  init_compute_debug_info();
  IntervalWalker* iw = init_compute_oop_maps();

  int num_blocks = block_count();
  for (int i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    assign_reg_num(block->lir()->instructions_list(), iw);
  }
}


void LinearScan::do_linear_scan() {
  NOT_PRODUCT(_total_timer.begin_method());

  number_instructions();

  NOT_PRODUCT(print_lir(1, "Before Register Allocation"));

  compute_local_live_sets();
  compute_global_live_sets();
  CHECK_BAILOUT();

  build_intervals();
  CHECK_BAILOUT();
  sort_intervals_before_allocation();

  NOT_PRODUCT(print_intervals("Before Register Allocation"));
  NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_before_alloc));

  allocate_registers();
  CHECK_BAILOUT();

  resolve_data_flow();
  if (compilation()->has_exception_handlers()) {
    resolve_exception_handlers();
  }
  // fill in number of spill slots into frame_map
  propagate_spill_slots();
  CHECK_BAILOUT();

  NOT_PRODUCT(print_intervals("After Register Allocation"));
  NOT_PRODUCT(print_lir(2, "LIR after register allocation:"));

  sort_intervals_after_allocation();

  DEBUG_ONLY(verify());

  eliminate_spill_moves();
  assign_reg_num();
  CHECK_BAILOUT();

  NOT_PRODUCT(print_lir(2, "LIR after assignment of register numbers:"));
  NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_after_asign));

  { TIME_LINEAR_SCAN(timer_allocate_fpu_stack);

    if (use_fpu_stack_allocation()) {
      allocate_fpu_stack(); // Only has effect on Intel
      NOT_PRODUCT(print_lir(2, "LIR after FPU stack allocation:"));
    }
  }

#ifndef RISCV
  // Disable these optimizations on riscv temporarily, because it does not
  // work when the comparison operands are bound to branches or cmoves.
  { TIME_LINEAR_SCAN(timer_optimize_lir);

    EdgeMoveOptimizer::optimize(ir()->code());
    ControlFlowOptimizer::optimize(ir()->code());
    // check that cfg is still correct after optimizations
    ir()->verify();
  }
#endif

  NOT_PRODUCT(print_lir(1, "Before Code Generation", false));
  NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_final));
  NOT_PRODUCT(_total_timer.end_method(this));
}


// ********** Printing functions

#ifndef PRODUCT

void LinearScan::print_timers(double total) {
  _total_timer.print(total);
}

void LinearScan::print_statistics() {
  _stat_before_alloc.print("before allocation");
  _stat_after_asign.print("after assignment of register");
  _stat_final.print("after optimization");
}

void LinearScan::print_bitmap(BitMap& b) {
  for (unsigned int i = 0; i < b.size(); i++) {
    if (b.at(i)) tty->print("%d ", i);
  }
  tty->cr();
}

void LinearScan::print_intervals(const char* label) {
  if (TraceLinearScanLevel >= 1) {
    int i;
    tty->cr();
    tty->print_cr("%s", label);

    for (i = 0; i < interval_count(); i++) {
      Interval* interval = interval_at(i);
      if (interval != nullptr) {
        interval->print();
      }
    }

    tty->cr();
    tty->print_cr("--- Basic Blocks ---");
    for (i = 0; i < block_count(); i++) {
      BlockBegin* block = block_at(i);
      tty->print("B%d [%d, %d, %d, %d] ", block->block_id(), block->first_lir_instruction_id(), block->last_lir_instruction_id(), block->loop_index(), block->loop_depth());
    }
    tty->cr();
    tty->cr();
  }

  if (PrintCFGToFile) {
    CFGPrinter::print_intervals(&_intervals, label);
  }
}

void LinearScan::print_lir(int level, const char* label, bool hir_valid) {
  if (TraceLinearScanLevel >= level) {
    tty->cr();
    tty->print_cr("%s", label);
    print_LIR(ir()->linear_scan_order());
    tty->cr();
  }

  if (level == 1 && PrintCFGToFile) {
    CFGPrinter::print_cfg(ir()->linear_scan_order(), label, hir_valid, true);
  }
}

void LinearScan::print_reg_num(outputStream* out, int reg_num) {
  if (reg_num == -1) {
    out->print("[ANY]");
    return;
  } else if (reg_num >= LIR_Opr::vreg_base) {
    out->print("[VREG %d]", reg_num);
    return;
  }

  LIR_Opr opr = get_operand(reg_num);
  assert(opr->is_valid(), "unknown register");
  opr->print(out);
}

LIR_Opr LinearScan::get_operand(int reg_num) {
  LIR_Opr opr = LIR_OprFact::illegal();

#ifdef X86
  int last_xmm_reg = pd_last_xmm_reg;
#ifdef _LP64
  if (UseAVX < 3) {
    last_xmm_reg = pd_first_xmm_reg + (pd_nof_xmm_regs_frame_map / 2) - 1;
  }
#endif
#endif
  if (reg_num >= pd_first_cpu_reg && reg_num <= pd_last_cpu_reg) {
    opr = LIR_OprFact::single_cpu(reg_num);
  } else if (reg_num >= pd_first_fpu_reg && reg_num <= pd_last_fpu_reg) {
    opr = LIR_OprFact::single_fpu(reg_num - pd_first_fpu_reg);
#ifdef X86
  } else if (reg_num >= pd_first_xmm_reg && reg_num <= last_xmm_reg) {
    opr = LIR_OprFact::single_xmm(reg_num - pd_first_xmm_reg);
#endif
  } else {
    // reg_num == -1 or a virtual register, return the illegal operand
  }
  return opr;
}

Interval* LinearScan::find_interval_at(int reg_num) const {
  if (reg_num < 0 || reg_num >= _intervals.length()) {
    return nullptr;
  }
  return interval_at(reg_num);
}

#endif // PRODUCT


// ********** verification functions for allocation
// (check that all intervals have a correct register and that no registers are overwritten)
#ifdef ASSERT

void LinearScan::verify() {
  TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying intervals ******************************************"));
  verify_intervals();

  TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying that no oops are in fixed intervals ****************"));
  verify_no_oops_in_fixed_intervals();

  TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying that unpinned constants are not alive across block boundaries"));
  verify_constants();

  TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying register allocation ********************************"));
  verify_registers();

  TRACE_LINEAR_SCAN(2, tty->print_cr("********* no errors found **********************************************"));
}

void LinearScan::verify_intervals() {
  int len = interval_count();
  bool has_error = false;

  for (int i = 0; i < len; i++) {
    Interval* i1 = interval_at(i);
    if (i1 == nullptr) continue;

    i1->check_split_children();

    if (i1->reg_num() != i) {
      tty->print_cr("Interval %d is on position %d in list", i1->reg_num(), i); i1->print(); tty->cr();
      has_error = true;
    }

    if (i1->reg_num() >= LIR_Opr::vreg_base && i1->type() == T_ILLEGAL) {
      tty->print_cr("Interval %d has no type assigned", i1->reg_num()); i1->print(); tty->cr();
      has_error = true;
    }

    if (i1->assigned_reg() == any_reg) {
      tty->print_cr("Interval %d has no register assigned", i1->reg_num()); i1->print(); tty->cr();
      has_error = true;
    }

    if (i1->assigned_reg() == i1->assigned_regHi()) {
      tty->print_cr("Interval %d: low and high register equal", i1->reg_num()); i1->print(); tty->cr();
      has_error = true;
    }

    if (!is_processed_reg_num(i1->assigned_reg())) {
      tty->print_cr("Can not have an Interval for an ignored register"); i1->print(); tty->cr();
      has_error = true;
    }

    // special intervals that are created in MoveResolver
    // -> ignore them because the range information has no meaning there
    if (i1->from() == 1 && i1->to() == 2) continue;

    if (i1->first() == Range::end()) {
      tty->print_cr("Interval %d has no Range", i1->reg_num()); i1->print(); tty->cr();
      has_error = true;
    }

    for (Range* r = i1->first(); r != Range::end(); r = r->next()) {
      if (r->from() >= r->to()) {
        tty->print_cr("Interval %d has zero length range", i1->reg_num()); i1->print(); tty->cr();
        has_error = true;
      }
    }

    for (int j = i + 1; j < len; j++) {
      Interval* i2 = interval_at(j);
      if (i2 == nullptr || (i2->from() == 1 && i2->to() == 2)) continue;

      int r1 = i1->assigned_reg();
      int r1Hi = i1->assigned_regHi();
      int r2 = i2->assigned_reg();
      int r2Hi = i2->assigned_regHi();
      if ((r1 == r2 || r1 == r2Hi || (r1Hi != any_reg && (r1Hi == r2 || r1Hi == r2Hi))) && i1->intersects(i2)) {
        tty->print_cr("Intervals %d and %d overlap and have the same register assigned", i1->reg_num(), i2->reg_num());
        i1->print(); tty->cr();
        i2->print(); tty->cr();
        has_error = true;
      }
    }
  }

  assert(has_error == false, "register allocation invalid");
}


void LinearScan::verify_no_oops_in_fixed_intervals() {
  Interval* fixed_intervals;
  Interval* other_intervals;
  create_unhandled_lists(&fixed_intervals, &other_intervals, is_precolored_cpu_interval, nullptr);

  // to ensure a walking until the last instruction id, add a dummy interval
  // with a high operation id
  other_intervals = new Interval(any_reg);
  other_intervals->add_range(max_jint - 2, max_jint - 1);
  IntervalWalker* iw = new IntervalWalker(this, fixed_intervals, other_intervals);

  LIR_OpVisitState visitor;
  for (int i = 0; i < block_count(); i++) {
    BlockBegin* block = block_at(i);

    LIR_OpList* instructions = block->lir()->instructions_list();

    for (int j = 0; j < instructions->length(); j++) {
      LIR_Op* op = instructions->at(j);
      int op_id = op->id();

      visitor.visit(op);

      if (visitor.info_count() > 0) {
        iw->walk_before(op->id());
        bool check_live = true;
        if (op->code() == lir_move) {
          LIR_Op1* move = (LIR_Op1*)op;
          check_live = (move->patch_code() == lir_patch_none);
        }
        LIR_OpBranch* branch = op->as_OpBranch();
        if (branch != nullptr && branch->stub() != nullptr && branch->stub()->is_exception_throw_stub()) {
          // Don't bother checking the stub in this case since the
          // exception stub will never return to normal control flow.
          check_live = false;
        }

        // Make sure none of the fixed registers is live across an
        // oopmap since we can't handle that correctly.
        if (check_live) {
          for (Interval* interval = iw->active_first(fixedKind);
               interval != Interval::end();
               interval = interval->next()) {
            if (interval->current_to() > op->id() + 1) {
              // This interval is live out of this op so make sure
              // that this interval represents some value that's
              // referenced by this op either as an input or output.
              bool ok = false;
              for_each_visitor_mode(mode) {
                int n = visitor.opr_count(mode);
                for (int k = 0; k < n; k++) {
                  LIR_Opr opr = visitor.opr_at(mode, k);
                  if (opr->is_fixed_cpu()) {
                    if (interval_at(reg_num(opr)) == interval) {
                      ok = true;
                      break;
                    }
                    int hi = reg_numHi(opr);
                    if (hi != -1 && interval_at(hi) == interval) {
                      ok = true;
                      break;
                    }
                  }
                }
              }
              assert(ok, "fixed intervals should never be live across an oopmap point");
            }
          }
        }
      }

      // oop-maps at calls do not contain registers, so check is not needed
      if (!visitor.has_call()) {

        for_each_visitor_mode(mode) {
          int n = visitor.opr_count(mode);
          for (int k = 0; k < n; k++) {
            LIR_Opr opr = visitor.opr_at(mode, k);

            if (opr->is_fixed_cpu() && opr->is_oop()) {
              // operand is a non-virtual cpu register and contains an oop
              TRACE_LINEAR_SCAN(4, op->print_on(tty); tty->print("checking operand "); opr->print(); tty->cr());

              Interval* interval = interval_at(reg_num(opr));
              assert(interval != nullptr, "no interval");

              if (mode == LIR_OpVisitState::inputMode) {
                if (interval->to() >= op_id + 1) {
                  assert(interval->to() < op_id + 2 ||
                         interval->has_hole_between(op_id, op_id + 2),
                         "oop input operand live after instruction");
                }
              } else if (mode == LIR_OpVisitState::outputMode) {
                if (interval->from() <= op_id - 1) {
                  assert(interval->has_hole_between(op_id - 1, op_id),
                         "oop input operand live after instruction");
                }
              }
            }
          }
        }
      }
    }
  }
}


void LinearScan::verify_constants() {
  int num_regs = num_virtual_regs();
  int size = live_set_size();
  int num_blocks = block_count();

  for (int i = 0; i < num_blocks; i++) {
    BlockBegin* block = block_at(i);
    ResourceBitMap& live_at_edge = block->live_in();

    // visit all registers where the live_at_edge bit is set
    auto visitor = [&](BitMap::idx_t index) {
      int r = static_cast<int>(index);
      TRACE_LINEAR_SCAN(4, tty->print("checking interval %d of block B%d", r, block->block_id()));

      Value value = gen()->instruction_for_vreg(r);

      assert(value != nullptr, "all intervals live across block boundaries must have Value");
      assert(value->operand()->is_register() && value->operand()->is_virtual(), "value must have virtual operand");
      assert(value->operand()->vreg_number() == r, "register number must match");
      // TKR assert(value->as_Constant() == nullptr || value->is_pinned(), "only pinned constants can be alive across block boundaries");
    };
    live_at_edge.iterate(visitor, 0, size);
  }
}


class RegisterVerifier: public StackObj {
 private:
  LinearScan*   _allocator;
  BlockList     _work_list;      // all blocks that must be processed
  IntervalsList _saved_states;   // saved information of previous check

  // simplified access to methods of LinearScan
  Compilation*  compilation() const              { return _allocator->compilation(); }
  Interval*     interval_at(int reg_num) const   { return _allocator->interval_at(reg_num); }
  int           reg_num(LIR_Opr opr) const       { return _allocator->reg_num(opr); }

  // currently, only registers are processed
  int           state_size()                     { return LinearScan::nof_regs; }

  // accessors
  IntervalList* state_for_block(BlockBegin* block) { return _saved_states.at(block->block_id()); }
  void          set_state_for_block(BlockBegin* block, IntervalList* saved_state) { _saved_states.at_put(block->block_id(), saved_state); }
  void          add_to_work_list(BlockBegin* block) { if (!_work_list.contains(block)) _work_list.append(block); }

  // helper functions
  IntervalList* copy(IntervalList* input_state);
  void          state_put(IntervalList* input_state, int reg, Interval* interval);
  bool          check_state(IntervalList* input_state, int reg, Interval* interval);

  void process_block(BlockBegin* block);
  void process_xhandler(XHandler* xhandler, IntervalList* input_state);
  void process_successor(BlockBegin* block, IntervalList* input_state);
  void process_operations(LIR_List* ops, IntervalList* input_state);

 public:
  RegisterVerifier(LinearScan* allocator)
    : _allocator(allocator)
    , _work_list(16)
    , _saved_states(BlockBegin::number_of_blocks(), BlockBegin::number_of_blocks(), nullptr)
  { }

  void verify(BlockBegin* start);
};


// entry function from LinearScan that starts the verification
void LinearScan::verify_registers() {
  RegisterVerifier verifier(this);
  verifier.verify(block_at(0));
}


void RegisterVerifier::verify(BlockBegin* start) {
  // setup input registers (method arguments) for first block
  int input_state_len = state_size();
  IntervalList* input_state = new IntervalList(input_state_len, input_state_len, nullptr);
  CallingConvention* args = compilation()->frame_map()->incoming_arguments();
  for (int n = 0; n < args->length(); n++) {
    LIR_Opr opr = args->at(n);
    if (opr->is_register()) {
      Interval* interval = interval_at(reg_num(opr));

      if (interval->assigned_reg() < state_size()) {
        input_state->at_put(interval->assigned_reg(), interval);
      }
      if (interval->assigned_regHi() != LinearScan::any_reg && interval->assigned_regHi() < state_size()) {
        input_state->at_put(interval->assigned_regHi(), interval);
      }
    }
  }

  set_state_for_block(start, input_state);
  add_to_work_list(start);

  // main loop for verification
  do {
    BlockBegin* block = _work_list.at(0);
    _work_list.remove_at(0);

    process_block(block);
  } while (!_work_list.is_empty());
}

void RegisterVerifier::process_block(BlockBegin* block) {
  TRACE_LINEAR_SCAN(2, tty->cr(); tty->print_cr("process_block B%d", block->block_id()));

  // must copy state because it is modified
  IntervalList* input_state = copy(state_for_block(block));

  if (TraceLinearScanLevel >= 4) {
    tty->print_cr("Input-State of intervals:");
    tty->print("    ");
    for (int i = 0; i < state_size(); i++) {
      if (input_state->at(i) != nullptr) {
        tty->print(" %4d", input_state->at(i)->reg_num());
      } else {
        tty->print("   __");
      }
    }
    tty->cr();
    tty->cr();
  }

  // process all operations of the block
  process_operations(block->lir(), input_state);

  // iterate all successors
  for (int i = 0; i < block->number_of_sux(); i++) {
    process_successor(block->sux_at(i), input_state);
  }
}

void RegisterVerifier::process_xhandler(XHandler* xhandler, IntervalList* input_state) {
  TRACE_LINEAR_SCAN(2, tty->print_cr("process_xhandler B%d", xhandler->entry_block()->block_id()));

  // must copy state because it is modified
  input_state = copy(input_state);

  if (xhandler->entry_code() != nullptr) {
    process_operations(xhandler->entry_code(), input_state);
  }
  process_successor(xhandler->entry_block(), input_state);
}

void RegisterVerifier::process_successor(BlockBegin* block, IntervalList* input_state) {
  IntervalList* saved_state = state_for_block(block);

  if (saved_state != nullptr) {
    // this block was already processed before.
    // check if new input_state is consistent with saved_state

    bool saved_state_correct = true;
    for (int i = 0; i < state_size(); i++) {
      if (input_state->at(i) != saved_state->at(i)) {
        // current input_state and previous saved_state assume a different
        // interval in this register -> assume that this register is invalid
        if (saved_state->at(i) != nullptr) {
          // invalidate old calculation only if it assumed that
          // register was valid. when the register was already invalid,
          // then the old calculation was correct.
          saved_state_correct = false;
          saved_state->at_put(i, nullptr);

          TRACE_LINEAR_SCAN(4, tty->print_cr("process_successor B%d: invalidating slot %d", block->block_id(), i));
        }
      }
    }

    if (saved_state_correct) {
      // already processed block with correct input_state
      TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: previous visit already correct", block->block_id()));
    } else {
      // must re-visit this block
      TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: must re-visit because input state changed", block->block_id()));
      add_to_work_list(block);
    }

  } else {
    // block was not processed before, so set initial input_state
    TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: initial visit", block->block_id()));

    set_state_for_block(block, copy(input_state));
    add_to_work_list(block);
  }
}


IntervalList* RegisterVerifier::copy(IntervalList* input_state) {
  IntervalList* copy_state = new IntervalList(input_state->length());
  copy_state->appendAll(input_state);
  return copy_state;
}

void RegisterVerifier::state_put(IntervalList* input_state, int reg, Interval* interval) {
  if (reg != LinearScan::any_reg && reg < state_size()) {
    if (interval != nullptr) {
      TRACE_LINEAR_SCAN(4, tty->print_cr("        reg[%d] = %d", reg, interval->reg_num()));
    } else if (input_state->at(reg) != nullptr) {
      TRACE_LINEAR_SCAN(4, tty->print_cr("        reg[%d] = null", reg));
    }

    input_state->at_put(reg, interval);
  }
}

bool RegisterVerifier::check_state(IntervalList* input_state, int reg, Interval* interval) {
  if (reg != LinearScan::any_reg && reg < state_size()) {
    if (input_state->at(reg) != interval) {
      tty->print_cr("!! Error in register allocation: register %d does not contain interval %d", reg, interval->reg_num());
      return true;
    }
  }
  return false;
}

void RegisterVerifier::process_operations(LIR_List* ops, IntervalList* input_state) {
  // visit all instructions of the block
  LIR_OpVisitState visitor;
  bool has_error = false;

  for (int i = 0; i < ops->length(); i++) {
    LIR_Op* op = ops->at(i);
    visitor.visit(op);

    TRACE_LINEAR_SCAN(4, op->print_on(tty));

    // check if input operands are correct
    int j;
    int n = visitor.opr_count(LIR_OpVisitState::inputMode);
    for (j = 0; j < n; j++) {
      LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, j);
      if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) {
        Interval* interval = interval_at(reg_num(opr));
        if (op->id() != -1) {
          interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::inputMode);
        }

        has_error |= check_state(input_state, interval->assigned_reg(),   interval->split_parent());
        has_error |= check_state(input_state, interval->assigned_regHi(), interval->split_parent());

        // When an operand is marked with is_last_use, then the fpu stack allocator
        // removes the register from the fpu stack -> the register contains no value
        if (opr->is_last_use()) {
          state_put(input_state, interval->assigned_reg(),   nullptr);
          state_put(input_state, interval->assigned_regHi(), nullptr);
        }
      }
    }

    // invalidate all caller save registers at calls
    if (visitor.has_call()) {
      for (j = 0; j < FrameMap::nof_caller_save_cpu_regs(); j++) {
        state_put(input_state, reg_num(FrameMap::caller_save_cpu_reg_at(j)), nullptr);
      }
      for (j = 0; j < FrameMap::nof_caller_save_fpu_regs; j++) {
        state_put(input_state, reg_num(FrameMap::caller_save_fpu_reg_at(j)), nullptr);
      }

#ifdef X86
      int num_caller_save_xmm_regs = FrameMap::get_num_caller_save_xmms();
      for (j = 0; j < num_caller_save_xmm_regs; j++) {
        state_put(input_state, reg_num(FrameMap::caller_save_xmm_reg_at(j)), nullptr);
      }
#endif
    }

    // process xhandler before output and temp operands
    XHandlers* xhandlers = visitor.all_xhandler();
    n = xhandlers->length();
    for (int k = 0; k < n; k++) {
      process_xhandler(xhandlers->handler_at(k), input_state);
    }

    // set temp operands (some operations use temp operands also as output operands, so can't set them null)
    n = visitor.opr_count(LIR_OpVisitState::tempMode);
    for (j = 0; j < n; j++) {
      LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, j);
      if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) {
        Interval* interval = interval_at(reg_num(opr));
        if (op->id() != -1) {
          interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::tempMode);
        }

        state_put(input_state, interval->assigned_reg(),   interval->split_parent());
        state_put(input_state, interval->assigned_regHi(), interval->split_parent());
      }
    }

    // set output operands
    n = visitor.opr_count(LIR_OpVisitState::outputMode);
    for (j = 0; j < n; j++) {
      LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, j);
      if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) {
        Interval* interval = interval_at(reg_num(opr));
        if (op->id() != -1) {
          interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::outputMode);
        }

        state_put(input_state, interval->assigned_reg(),   interval->split_parent());
        state_put(input_state, interval->assigned_regHi(), interval->split_parent());
      }
    }
  }
  assert(has_error == false, "Error in register allocation");
}

#endif // ASSERT



// **** Implementation of MoveResolver ******************************

MoveResolver::MoveResolver(LinearScan* allocator) :
  _allocator(allocator),
  _insert_list(nullptr),
  _insert_idx(-1),
  _insertion_buffer(),
  _mapping_from(8),
  _mapping_from_opr(8),
  _mapping_to(8),
  _multiple_reads_allowed(false)
{
  for (int i = 0; i < LinearScan::nof_regs; i++) {
    _register_blocked[i] = 0;
  }
  DEBUG_ONLY(check_empty());
}


#ifdef ASSERT

void MoveResolver::check_empty() {
  assert(_mapping_from.length() == 0 && _mapping_from_opr.length() == 0 && _mapping_to.length() == 0, "list must be empty before and after processing");
  for (int i = 0; i < LinearScan::nof_regs; i++) {
    assert(register_blocked(i) == 0, "register map must be empty before and after processing");
  }
  assert(_multiple_reads_allowed == false, "must have default value");
}

void MoveResolver::verify_before_resolve() {
  assert(_mapping_from.length() == _mapping_from_opr.length(), "length must be equal");
  assert(_mapping_from.length() == _mapping_to.length(), "length must be equal");
  assert(_insert_list != nullptr && _insert_idx != -1, "insert position not set");

  int i, j;
  if (!_multiple_reads_allowed) {
    for (i = 0; i < _mapping_from.length(); i++) {
      for (j = i + 1; j < _mapping_from.length(); j++) {
        assert(_mapping_from.at(i) == nullptr || _mapping_from.at(i) != _mapping_from.at(j), "cannot read from same interval twice");
      }
    }
  }

  for (i = 0; i < _mapping_to.length(); i++) {
    for (j = i + 1; j < _mapping_to.length(); j++) {
      assert(_mapping_to.at(i) != _mapping_to.at(j), "cannot write to same interval twice");
    }
  }


  ResourceBitMap used_regs(LinearScan::nof_regs + allocator()->frame_map()->argcount() + allocator()->max_spills());
  if (!_multiple_reads_allowed) {
    for (i = 0; i < _mapping_from.length(); i++) {
      Interval* it = _mapping_from.at(i);
      if (it != nullptr) {
        assert(!used_regs.at(it->assigned_reg()), "cannot read from same register twice");
        used_regs.set_bit(it->assigned_reg());

        if (it->assigned_regHi() != LinearScan::any_reg) {
          assert(!used_regs.at(it->assigned_regHi()), "cannot read from same register twice");
          used_regs.set_bit(it->assigned_regHi());
        }
      }
    }
  }

  used_regs.clear();
  for (i = 0; i < _mapping_to.length(); i++) {
    Interval* it = _mapping_to.at(i);
    assert(!used_regs.at(it->assigned_reg()), "cannot write to same register twice");
    used_regs.set_bit(it->assigned_reg());

    if (it->assigned_regHi() != LinearScan::any_reg) {
      assert(!used_regs.at(it->assigned_regHi()), "cannot write to same register twice");
      used_regs.set_bit(it->assigned_regHi());
    }
  }

  used_regs.clear();
  for (i = 0; i < _mapping_from.length(); i++) {
    Interval* it = _mapping_from.at(i);
    if (it != nullptr && it->assigned_reg() >= LinearScan::nof_regs) {
      used_regs.set_bit(it->assigned_reg());
    }
  }
  for (i = 0; i < _mapping_to.length(); i++) {
    Interval* it = _mapping_to.at(i);
    assert(!used_regs.at(it->assigned_reg()) || it->assigned_reg() == _mapping_from.at(i)->assigned_reg(), "stack slots used in _mapping_from must be disjoint to _mapping_to");
  }
}

#endif // ASSERT


// mark assigned_reg and assigned_regHi of the interval as blocked
void MoveResolver::block_registers(Interval* it) {
  int reg = it->assigned_reg();
  if (reg < LinearScan::nof_regs) {
    assert(_multiple_reads_allowed || register_blocked(reg) == 0, "register already marked as used");
    set_register_blocked(reg, 1);
  }
  reg = it->assigned_regHi();
  if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) {
    assert(_multiple_reads_allowed || register_blocked(reg) == 0, "register already marked as used");
    set_register_blocked(reg, 1);
  }
}

// mark assigned_reg and assigned_regHi of the interval as unblocked
void MoveResolver::unblock_registers(Interval* it) {
  int reg = it->assigned_reg();
  if (reg < LinearScan::nof_regs) {
    assert(register_blocked(reg) > 0, "register already marked as unused");
    set_register_blocked(reg, -1);
  }
  reg = it->assigned_regHi();
  if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) {
    assert(register_blocked(reg) > 0, "register already marked as unused");
    set_register_blocked(reg, -1);
  }
}

// check if assigned_reg and assigned_regHi of the to-interval are not blocked (or only blocked by from)
bool MoveResolver::save_to_process_move(Interval* from, Interval* to) {
  int from_reg = -1;
  int from_regHi = -1;
  if (from != nullptr) {
    from_reg = from->assigned_reg();
    from_regHi = from->assigned_regHi();
  }

  int reg = to->assigned_reg();
  if (reg < LinearScan::nof_regs) {
    if (register_blocked(reg) > 1 || (register_blocked(reg) == 1 && reg != from_reg && reg != from_regHi)) {
      return false;
    }
  }
  reg = to->assigned_regHi();
  if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) {
    if (register_blocked(reg) > 1 || (register_blocked(reg) == 1 && reg != from_reg && reg != from_regHi)) {
      return false;
    }
  }

  return true;
}


void MoveResolver::create_insertion_buffer(LIR_List* list) {
  assert(!_insertion_buffer.initialized(), "overwriting existing buffer");
  _insertion_buffer.init(list);
}

void MoveResolver::append_insertion_buffer() {
  if (_insertion_buffer.initialized()) {
    _insertion_buffer.lir_list()->append(&_insertion_buffer);
  }
  assert(!_insertion_buffer.initialized(), "must be uninitialized now");

  _insert_list = nullptr;
  _insert_idx = -1;
}

void MoveResolver::insert_move(Interval* from_interval, Interval* to_interval) {
  assert(from_interval->reg_num() != to_interval->reg_num(), "from and to interval equal");
  assert(from_interval->type() == to_interval->type(), "move between different types");
  assert(_insert_list != nullptr && _insert_idx != -1, "must setup insert position first");
  assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");

  LIR_Opr from_opr = get_virtual_register(from_interval);
  LIR_Opr to_opr = get_virtual_register(to_interval);

  if (!_multiple_reads_allowed) {
    // the last_use flag is an optimization for FPU stack allocation. When the same
    // input interval is used in more than one move, then it is too difficult to determine
    // if this move is really the last use.
    from_opr = from_opr->make_last_use();
  }
  _insertion_buffer.move(_insert_idx, from_opr, to_opr);

  TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: inserted move from register %d (%d, %d) to %d (%d, %d)", from_interval->reg_num(), from_interval->assigned_reg(), from_interval->assigned_regHi(), to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));
}

void MoveResolver::insert_move(LIR_Opr from_opr, Interval* to_interval) {
  assert(from_opr->type() == to_interval->type(), "move between different types");
  assert(_insert_list != nullptr && _insert_idx != -1, "must setup insert position first");
  assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer");

  LIR_Opr to_opr = get_virtual_register(to_interval);
  _insertion_buffer.move(_insert_idx, from_opr, to_opr);

  TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: inserted move from constant "); from_opr->print(); tty->print_cr("  to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));
}

LIR_Opr MoveResolver::get_virtual_register(Interval* interval) {
  // Add a little fudge factor for the bailout since the bailout is only checked periodically. This allows us to hand out
  // a few extra registers before we really run out which helps to avoid to trip over assertions.
  int reg_num = interval->reg_num();
  if (reg_num + 20 >= LIR_Opr::vreg_max) {
    _allocator->bailout("out of virtual registers in linear scan");
    if (reg_num + 2 >= LIR_Opr::vreg_max) {
      // Wrap it around and continue until bailout really happens to avoid hitting assertions.
      reg_num = LIR_Opr::vreg_base;
    }
  }
  LIR_Opr vreg = LIR_OprFact::virtual_register(reg_num, interval->type());
  assert(vreg != LIR_OprFact::illegal(), "ran out of virtual registers");
  return vreg;
}

void MoveResolver::resolve_mappings() {
  TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: resolving mappings for Block B%d, index %d", _insert_list->block() != nullptr ? _insert_list->block()->block_id() : -1, _insert_idx));
  DEBUG_ONLY(verify_before_resolve());

  // Block all registers that are used as input operands of a move.
  // When a register is blocked, no move to this register is emitted.
  // This is necessary for detecting cycles in moves.
  int i;
  for (i = _mapping_from.length() - 1; i >= 0; i--) {
    Interval* from_interval = _mapping_from.at(i);
    if (from_interval != nullptr) {
      block_registers(from_interval);
    }
  }

  int spill_candidate = -1;
  while (_mapping_from.length() > 0) {
    bool processed_interval = false;

    for (i = _mapping_from.length() - 1; i >= 0; i--) {
      Interval* from_interval = _mapping_from.at(i);
      Interval* to_interval = _mapping_to.at(i);

      if (save_to_process_move(from_interval, to_interval)) {
        // this interval can be processed because target is free
        if (from_interval != nullptr) {
          insert_move(from_interval, to_interval);
          unblock_registers(from_interval);
        } else {
          insert_move(_mapping_from_opr.at(i), to_interval);
        }
        _mapping_from.remove_at(i);
        _mapping_from_opr.remove_at(i);
        _mapping_to.remove_at(i);

        processed_interval = true;
      } else if (from_interval != nullptr && from_interval->assigned_reg() < LinearScan::nof_regs) {
        // this interval cannot be processed now because target is not free
        // it starts in a register, so it is a possible candidate for spilling
        spill_candidate = i;
      }
    }

    if (!processed_interval) {
      // no move could be processed because there is a cycle in the move list
      // (e.g. r1 -> r2, r2 -> r1), so one interval must be spilled to memory
      guarantee(spill_candidate != -1, "no interval in register for spilling found");

      // create a new spill interval and assign a stack slot to it
      Interval* from_interval = _mapping_from.at(spill_candidate);
      Interval* spill_interval = new Interval(-1);
      spill_interval->set_type(from_interval->type());

      // add a dummy range because real position is difficult to calculate
      // Note: this range is a special case when the integrity of the allocation is checked
      spill_interval->add_range(1, 2);

      //       do not allocate a new spill slot for temporary interval, but
      //       use spill slot assigned to from_interval. Otherwise moves from
      //       one stack slot to another can happen (not allowed by LIR_Assembler
      int spill_slot = from_interval->canonical_spill_slot();
      if (spill_slot < 0) {
        spill_slot = allocator()->allocate_spill_slot(type2spill_size[spill_interval->type()] == 2);
        from_interval->set_canonical_spill_slot(spill_slot);
      }
      spill_interval->assign_reg(spill_slot);
      allocator()->append_interval(spill_interval);

      TRACE_LINEAR_SCAN(4, tty->print_cr("created new Interval %d for spilling", spill_interval->reg_num()));

      // insert a move from register to stack and update the mapping
      insert_move(from_interval, spill_interval);
      _mapping_from.at_put(spill_candidate, spill_interval);
      unblock_registers(from_interval);
    }
  }

  // reset to default value
  _multiple_reads_allowed = false;

  // check that all intervals have been processed
  DEBUG_ONLY(check_empty());
}


void MoveResolver::set_insert_position(LIR_List* insert_list, int insert_idx) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: setting insert position to Block B%d, index %d", insert_list->block() != nullptr ? insert_list->block()->block_id() : -1, insert_idx));
  assert(_insert_list == nullptr && _insert_idx == -1, "use move_insert_position instead of set_insert_position when data already set");

  create_insertion_buffer(insert_list);
  _insert_list = insert_list;
  _insert_idx = insert_idx;
}

void MoveResolver::move_insert_position(LIR_List* insert_list, int insert_idx) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: moving insert position to Block B%d, index %d", insert_list->block() != nullptr ? insert_list->block()->block_id() : -1, insert_idx));

  if (_insert_list != nullptr && (insert_list != _insert_list || insert_idx != _insert_idx)) {
    // insert position changed -> resolve current mappings
    resolve_mappings();
  }

  if (insert_list != _insert_list) {
    // block changed -> append insertion_buffer because it is
    // bound to a specific block and create a new insertion_buffer
    append_insertion_buffer();
    create_insertion_buffer(insert_list);
  }

  _insert_list = insert_list;
  _insert_idx = insert_idx;
}

void MoveResolver::add_mapping(Interval* from_interval, Interval* to_interval) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: adding mapping from %d (%d, %d) to %d (%d, %d)", from_interval->reg_num(), from_interval->assigned_reg(), from_interval->assigned_regHi(), to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));

  _mapping_from.append(from_interval);
  _mapping_from_opr.append(LIR_OprFact::illegalOpr);
  _mapping_to.append(to_interval);
}


void MoveResolver::add_mapping(LIR_Opr from_opr, Interval* to_interval) {
  TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: adding mapping from "); from_opr->print(); tty->print_cr(" to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi()));
  assert(from_opr->is_constant(), "only for constants");

  _mapping_from.append(nullptr);
  _mapping_from_opr.append(from_opr);
  _mapping_to.append(to_interval);
}

void MoveResolver::resolve_and_append_moves() {
  if (has_mappings()) {
    resolve_mappings();
  }
  append_insertion_buffer();
}



// **** Implementation of Range *************************************

Range::Range(int from, int to, Range* next) :
  _from(from),
  _to(to),
  _next(next)
{
}

// initialize sentinel
Range* Range::_end = nullptr;
void Range::initialize() {
  assert(_end == nullptr, "Range initialized more than once");
  alignas(Range) static uint8_t end_storage[sizeof(Range)];
  _end = ::new(static_cast<void*>(end_storage)) Range(max_jint, max_jint, nullptr);
}

int Range::intersects_at(Range* r2) const {
  const Range* r1 = this;

  assert(r1 != nullptr && r2 != nullptr, "null ranges not allowed");
  assert(r1 != _end && r2 != _end, "empty ranges not allowed");

  do {
    if (r1->from() < r2->from()) {
      if (r1->to() <= r2->from()) {
        r1 = r1->next(); if (r1 == _end) return -1;
      } else {
        return r2->from();
      }
    } else if (r2->from() < r1->from()) {
      if (r2->to() <= r1->from()) {
        r2 = r2->next(); if (r2 == _end) return -1;
      } else {
        return r1->from();
      }
    } else { // r1->from() == r2->from()
      if (r1->from() == r1->to()) {
        r1 = r1->next(); if (r1 == _end) return -1;
      } else if (r2->from() == r2->to()) {
        r2 = r2->next(); if (r2 == _end) return -1;
      } else {
        return r1->from();
      }
    }
  } while (true);
}

#ifndef PRODUCT
void Range::print(outputStream* out) const {
  out->print("[%d, %d[ ", _from, _to);
}
#endif



// **** Implementation of Interval **********************************

// initialize sentinel
Interval* Interval::_end = nullptr;
void Interval::initialize() {
  Range::initialize();
  assert(_end == nullptr, "Interval initialized more than once");
  alignas(Interval) static uint8_t end_storage[sizeof(Interval)];
  _end = ::new(static_cast<void*>(end_storage)) Interval(-1);
}

Interval::Interval(int reg_num) :
  _reg_num(reg_num),
  _type(T_ILLEGAL),
  _first(Range::end()),
  _use_pos_and_kinds(12),
  _current(Range::end()),
  _next(_end),
  _state(invalidState),
  _assigned_reg(LinearScan::any_reg),
  _assigned_regHi(LinearScan::any_reg),
  _cached_to(-1),
  _cached_opr(LIR_OprFact::illegalOpr),
  _cached_vm_reg(VMRegImpl::Bad()),
  _split_children(nullptr),
  _canonical_spill_slot(-1),
  _insert_move_when_activated(false),
  _spill_state(noDefinitionFound),
  _spill_definition_pos(-1),
  _register_hint(nullptr)
{
  _split_parent = this;
  _current_split_child = this;
}

int Interval::calc_to() {
  assert(_first != Range::end(), "interval has no range");

  Range* r = _first;
  while (r->next() != Range::end()) {
    r = r->next();
  }
  return r->to();
}


#ifdef ASSERT
// consistency check of split-children
void Interval::check_split_children() {
  if (_split_children != nullptr && _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);

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

        assert(i1->reg_num() != i2->reg_num(), "same register number");

        if (i1->from() < i2->from()) {
          assert(i1->to() <= i2->from() && i1->to() < i2->to(), "intervals overlapping");
        } else {
          assert(i2->from() < i1->from(), "intervals start at same op_id");
          assert(i2->to() <= i1->from() && i2->to() < i1->to(), "intervals overlapping");
        }
      }
    }
  }
}
#endif // ASSERT

Interval* Interval::register_hint(bool search_split_child) const {
  if (!search_split_child) {
    return _register_hint;
  }

  if (_register_hint != nullptr) {
    assert(_register_hint->is_split_parent(), "only split parents are valid hint registers");

    if (_register_hint->assigned_reg() >= 0 && _register_hint->assigned_reg() < LinearScan::nof_regs) {
      return _register_hint;

    } else if (_register_hint->_split_children != nullptr && _register_hint->_split_children->length() > 0) {
      // search the first split child that has a register assigned
      int len = _register_hint->_split_children->length();
      for (int i = 0; i < len; i++) {
        Interval* cur = _register_hint->_split_children->at(i);

        if (cur->assigned_reg() >= 0 && cur->assigned_reg() < LinearScan::nof_regs) {
          return cur;
        }
      }
    }
  }

  // no hint interval found that has a register assigned
  return nullptr;
}


Interval* Interval::split_child_at_op_id(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)");

  Interval* result;
  if (_split_children == nullptr || _split_children->length() == 0) {
    result = this;
  } else {
    result = nullptr;
    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);
      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);
        }

        // interval found
        result = cur;
        break;
      }
    }

#ifdef ASSERT
    for (i = 0; i < len; 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();
        tmp->print();
        assert(false, "two valid result intervals found");
      }
    }
#endif
  }

  assert(result != nullptr, "no matching interval found");
  assert(result->covers(op_id, mode), "op_id not covered by interval");

  return result;
}


// returns the last split child that ends before the given op_id
Interval* Interval::split_child_before_op_id(int op_id) {
  assert(op_id >= 0, "invalid op_id");

  Interval* parent = split_parent();
  Interval* result = nullptr;

  assert(parent->_split_children != nullptr, "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);
    if (cur->to() <= op_id && (result == nullptr || result->to() < cur->to())) {
      result = cur;
    }
  }

  assert(result != nullptr, "no split child found");
  return result;
}


// 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");

  for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) {
    if (_use_pos_and_kinds.at(i + 1) >= min_use_kind) {
      return _use_pos_and_kinds.at(i);
    }
  }
  return max_jint;
}

int Interval::next_usage(IntervalUseKind min_use_kind, int from) const {
  assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals");

  for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) {
    if (_use_pos_and_kinds.at(i) >= from && _use_pos_and_kinds.at(i + 1) >= min_use_kind) {
      return _use_pos_and_kinds.at(i);
    }
  }
  return max_jint;
}

int Interval::next_usage_exact(IntervalUseKind exact_use_kind, int from) const {
  assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals");

  for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) {
    if (_use_pos_and_kinds.at(i) >= from && _use_pos_and_kinds.at(i + 1) == exact_use_kind) {
      return _use_pos_and_kinds.at(i);
    }
  }
  return max_jint;
}

int Interval::previous_usage(IntervalUseKind min_use_kind, int from) const {
  assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals");

  int prev = 0;
  for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) {
    if (_use_pos_and_kinds.at(i) > from) {
      return prev;
    }
    if (_use_pos_and_kinds.at(i + 1) >= min_use_kind) {
      prev = _use_pos_and_kinds.at(i);
    }
  }
  return prev;
}

void Interval::add_use_pos(int pos, IntervalUseKind use_kind) {
  assert(covers(pos, LIR_OpVisitState::inputMode), "use position not covered by live range");

  // do not add use positions for precolored intervals because
  // they are never used
  if (use_kind != noUse && reg_num() >= LIR_Opr::vreg_base) {
#ifdef ASSERT
    assert(_use_pos_and_kinds.length() % 2 == 0, "must be");
    for (int i = 0; i < _use_pos_and_kinds.length(); i += 2) {
      assert(pos <= _use_pos_and_kinds.at(i), "already added a use-position with lower position");
      assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind");
      if (i > 0) {
        assert(_use_pos_and_kinds.at(i) < _use_pos_and_kinds.at(i - 2), "not sorted descending");
      }
    }
#endif

    // Note: add_use is called in descending order, so list gets sorted
    //       automatically by just appending new use positions
    int len = _use_pos_and_kinds.length();
    if (len == 0 || _use_pos_and_kinds.at(len - 2) > pos) {
      _use_pos_and_kinds.append(pos);
      _use_pos_and_kinds.append(use_kind);
    } else if (_use_pos_and_kinds.at(len - 1) < use_kind) {
      assert(_use_pos_and_kinds.at(len - 2) == pos, "list not sorted correctly");
      _use_pos_and_kinds.at_put(len - 1, use_kind);
    }
  }
}

void Interval::add_range(int from, int to) {
  assert(from < to, "invalid range");
  assert(first() == Range::end() || to < first()->next()->from(), "not inserting at begin of interval");
  assert(from <= first()->to(), "not inserting at begin of interval");

  if (first()->from() <= to) {
    // join intersecting ranges
    first()->set_from(MIN2(from, first()->from()));
    first()->set_to  (MAX2(to,   first()->to()));
  } else {
    // insert new range
    _first = new Range(from, to, first());
  }
}

Interval* Interval::new_split_child() {
  // allocate new interval
  Interval* result = new Interval(-1);
  result->set_type(type());

  Interval* parent = split_parent();
  result->_split_parent = parent;
  result->set_register_hint(parent);

  // insert new interval in children-list of parent
  if (parent->_split_children == nullptr) {
    assert(is_split_parent(), "list must be initialized at first split");

    parent->_split_children = new IntervalList(4);
    parent->_split_children->append(this);
  }
  parent->_split_children->append(result);

  return result;
}

// split this interval at the specified position and return
// the remainder as a new interval.
//
// when an interval is split, a bi-directional link is established between the original interval
// (the split parent) and the intervals that are split off this interval (the split children)
// When a split child is split again, the new created interval is also a direct child
// of the original parent (there is no tree of split children stored, but a flat list)
// All split children are spilled to the same stack slot (stored in _canonical_spill_slot)
//
// Note: The new interval has no valid reg_num
Interval* Interval::split(int split_pos) {
  assert(LinearScan::is_virtual_interval(this), "cannot split fixed intervals");

  // allocate new interval
  Interval* result = new_split_child();

  // split the ranges
  Range* prev = nullptr;
  Range* cur = _first;
  while (cur != Range::end() && cur->to() <= split_pos) {
    prev = cur;
    cur = cur->next();
  }
  assert(cur != Range::end(), "split interval after end of last range");

  if (cur->from() < split_pos) {
    result->_first = new Range(split_pos, cur->to(), cur->next());
    cur->set_to(split_pos);
    cur->set_next(Range::end());

  } else {
    assert(prev != nullptr, "split before start of first range");
    result->_first = cur;
    prev->set_next(Range::end());
  }
  result->_current = result->_first;
  _cached_to = -1; // clear cached value

  // split list of use positions
  int total_len = _use_pos_and_kinds.length();
  int start_idx = total_len - 2;
  while (start_idx >= 0 && _use_pos_and_kinds.at(start_idx) < split_pos) {
    start_idx -= 2;
  }

  intStack new_use_pos_and_kinds(total_len - start_idx);
  int i;
  for (i = start_idx + 2; i < total_len; i++) {
    new_use_pos_and_kinds.append(_use_pos_and_kinds.at(i));
  }

  _use_pos_and_kinds.trunc_to(start_idx + 2);
  result->_use_pos_and_kinds = _use_pos_and_kinds;
  _use_pos_and_kinds = new_use_pos_and_kinds;

#ifdef ASSERT
  assert(_use_pos_and_kinds.length() % 2 == 0, "must have use kind for each use pos");
  assert(result->_use_pos_and_kinds.length() % 2 == 0, "must have use kind for each use pos");
  assert(_use_pos_and_kinds.length() + result->_use_pos_and_kinds.length() == total_len, "missed some entries");

  for (i = 0; i < _use_pos_and_kinds.length(); i += 2) {
    assert(_use_pos_and_kinds.at(i) < split_pos, "must be");
    assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind");
  }
  for (i = 0; i < result->_use_pos_and_kinds.length(); i += 2) {
    assert(result->_use_pos_and_kinds.at(i) >= split_pos, "must be");
    assert(result->_use_pos_and_kinds.at(i + 1) >= firstValidKind && result->_use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind");
  }
#endif

  return result;
}

// split this interval at the specified position and return
// the head as a new interval (the original interval is the tail)
//
// Currently, only the first range can be split, and the new interval
// must not have split positions
Interval* Interval::split_from_start(int split_pos) {
  assert(LinearScan::is_virtual_interval(this), "cannot split fixed intervals");
  assert(split_pos > from() && split_pos < to(), "can only split inside interval");
  assert(split_pos > _first->from() && split_pos <= _first->to(), "can only split inside first range");
  assert(first_usage(noUse) > split_pos, "can not split when use positions are present");

  // allocate new interval
  Interval* result = new_split_child();

  // the new created interval has only one range (checked by assertion above),
  // so the splitting of the ranges is very simple
  result->add_range(_first->from(), split_pos);

  if (split_pos == _first->to()) {
    assert(_first->next() != Range::end(), "must not be at end");
    _first = _first->next();
  } else {
    _first->set_from(split_pos);
  }

  return result;
}


// returns true if the op_id is inside the interval
bool Interval::covers(int op_id, LIR_OpVisitState::OprMode mode) const {
  Range* cur  = _first;

  while (cur != Range::end() && cur->to() < op_id) {
    cur = cur->next();
  }
  if (cur != Range::end()) {
    assert(cur->to() != cur->next()->from(), "ranges not separated");

    if (mode == LIR_OpVisitState::outputMode) {
      return cur->from() <= op_id && op_id < cur->to();
    } else {
      return cur->from() <= op_id && op_id <= cur->to();
    }
  }
  return false;
}

// returns true if the interval has any hole between hole_from and hole_to
// (even if the hole has only the length 1)
bool Interval::has_hole_between(int hole_from, int hole_to) {
  assert(hole_from < hole_to, "check");
  assert(from() <= hole_from && hole_to <= to(), "index out of interval");

  Range* cur  = _first;
  while (cur != Range::end()) {
    assert(cur->to() < cur->next()->from(), "no space between ranges");

    // hole-range starts before this range -> hole
    if (hole_from < cur->from()) {
      return true;

    // hole-range completely inside this range -> no hole
    } else if (hole_to <= cur->to()) {
      return false;

    // overlapping of hole-range with this range -> hole
    } else if (hole_from <= cur->to()) {
      return true;
    }

    cur = cur->next();
  }

  return false;
}

// Check if there is an intersection with any of the split children of 'interval'
bool Interval::intersects_any_children_of(Interval* interval) const {
  if (interval->_split_children != nullptr) {
    for (int i = 0; i < interval->_split_children->length(); i++) {
      if (intersects(interval->_split_children->at(i))) {
        return true;
      }
    }
  }
  return false;
}


#ifndef PRODUCT
void Interval::print_on(outputStream* out, bool is_cfg_printer) const {
  const char* SpillState2Name[] = { "no definition", "no spill store", "one spill store", "store at definition", "start in memory", "no optimization" };
  const char* UseKind2Name[] = { "N", "L", "S", "M" };

  const char* type_name;
  if (reg_num() < LIR_Opr::vreg_base) {
    type_name = "fixed";
  } else {
    type_name = type2name(type());
  }
  out->print("%d %s ", reg_num(), type_name);

  if (is_cfg_printer) {
    // Special version for compatibility with C1 Visualizer.
    LIR_Opr opr = LinearScan::get_operand(reg_num());
    if (opr->is_valid()) {
      out->print("\"");
      opr->print(out);
      out->print("\" ");
    }
  } else {
    // Improved output for normal debugging.
    if (reg_num() < LIR_Opr::vreg_base) {
      LinearScan::print_reg_num(out, assigned_reg());
    } else if (assigned_reg() != -1 && (LinearScan::num_physical_regs(type()) == 1 || assigned_regHi() != -1)) {
      LinearScan::calc_operand_for_interval(this)->print(out);
    } else {
      // Virtual register that has no assigned register yet.
      out->print("[ANY]");
    }
    out->print(" ");
  }
  out->print("%d %d ", split_parent()->reg_num(), (register_hint(false) != nullptr ? register_hint(false)->reg_num() : -1));

  // print ranges
  Range* cur = _first;
  while (cur != Range::end()) {
    cur->print(out);
    cur = cur->next();
    assert(cur != nullptr, "range list not closed with range sentinel");
  }

  // print use positions
  int prev = 0;
  assert(_use_pos_and_kinds.length() % 2 == 0, "must be");
  for (int i =_use_pos_and_kinds.length() - 2; i >= 0; i -= 2) {
    assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind");
    assert(prev < _use_pos_and_kinds.at(i), "use positions not sorted");

    out->print("%d %s ", _use_pos_and_kinds.at(i), UseKind2Name[_use_pos_and_kinds.at(i + 1)]);
    prev = _use_pos_and_kinds.at(i);
  }

  out->print(" \"%s\"", SpillState2Name[spill_state()]);
  out->cr();
}

void Interval::print_parent() const {
  if (_split_parent != this) {
    _split_parent->print_on(tty);
  } else {
    tty->print_cr("Parent: this");
  }
}

void Interval::print_children() const {
  if (_split_children == nullptr) {
    tty->print_cr("Children: []");
  } else {
    tty->print_cr("Children:");
    for (int i = 0; i < _split_children->length(); i++) {
      tty->print("%d: ", i);
      _split_children->at(i)->print_on(tty);
    }
  }
}
#endif // NOT PRODUCT




// **** Implementation of IntervalWalker ****************************

IntervalWalker::IntervalWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first)
 : _compilation(allocator->compilation())
 , _allocator(allocator)
{
  _unhandled_first[fixedKind] = unhandled_fixed_first;
  _unhandled_first[anyKind]   = unhandled_any_first;
  _active_first[fixedKind]    = Interval::end();
  _inactive_first[fixedKind]  = Interval::end();
  _active_first[anyKind]      = Interval::end();
  _inactive_first[anyKind]    = Interval::end();
  _current_position = -1;
  _current = nullptr;
  next_interval();
}


// append interval in order of current range from()
void IntervalWalker::append_sorted(Interval** list, Interval* interval) {
  Interval* prev = nullptr;
  Interval* cur  = *list;
  while (cur->current_from() < interval->current_from()) {
    prev = cur; cur = cur->next();
  }
  if (prev == nullptr) {
    *list = interval;
  } else {
    prev->set_next(interval);
  }
  interval->set_next(cur);
}

void IntervalWalker::append_to_unhandled(Interval** list, Interval* interval) {
  assert(interval->from() >= current()->current_from(), "cannot append new interval before current walk position");

  Interval* prev = nullptr;
  Interval* cur  = *list;
  while (cur->from() < interval->from() || (cur->from() == interval->from() && cur->first_usage(noUse) < interval->first_usage(noUse))) {
    prev = cur; cur = cur->next();
  }
  if (prev == nullptr) {
    *list = interval;
  } else {
    prev->set_next(interval);
  }
  interval->set_next(cur);
}


inline bool IntervalWalker::remove_from_list(Interval** list, Interval* i) {
  while (*list != Interval::end() && *list != i) {
    list = (*list)->next_addr();
  }
  if (*list != Interval::end()) {
    assert(*list == i, "check");
    *list = (*list)->next();
    return true;
  } else {
    return false;
  }
}

void IntervalWalker::remove_from_list(Interval* i) {
  bool deleted;

  if (i->state() == activeState) {
    deleted = remove_from_list(active_first_addr(anyKind), i);
  } else {
    assert(i->state() == inactiveState, "invalid state");
    deleted = remove_from_list(inactive_first_addr(anyKind), i);
  }

  assert(deleted, "interval has not been found in list");
}


void IntervalWalker::walk_to(IntervalState state, int from) {
  assert (state == activeState || state == inactiveState, "wrong state");
  for_each_interval_kind(kind) {
    Interval** prev = state == activeState ? active_first_addr(kind) : inactive_first_addr(kind);
    Interval* next   = *prev;
    while (next->current_from() <= from) {
      Interval* cur = next;
      next = cur->next();

      bool range_has_changed = false;
      while (cur->current_to() <= from) {
        cur->next_range();
        range_has_changed = true;
      }

      // also handle move from inactive list to active list
      range_has_changed = range_has_changed || (state == inactiveState && cur->current_from() <= from);

      if (range_has_changed) {
        // remove cur from list
        *prev = next;
        if (cur->current_at_end()) {
          // move to handled state (not maintained as a list)
          cur->set_state(handledState);
          DEBUG_ONLY(interval_moved(cur, kind, state, handledState);)
        } else if (cur->current_from() <= from){
          // sort into active list
          append_sorted(active_first_addr(kind), cur);
          cur->set_state(activeState);
          if (*prev == cur) {
            assert(state == activeState, "check");
            prev = cur->next_addr();
          }
          DEBUG_ONLY(interval_moved(cur, kind, state, activeState);)
        } else {
          // sort into inactive list
          append_sorted(inactive_first_addr(kind), cur);
          cur->set_state(inactiveState);
          if (*prev == cur) {
            assert(state == inactiveState, "check");
            prev = cur->next_addr();
          }
          DEBUG_ONLY(interval_moved(cur, kind, state, inactiveState);)
        }
      } else {
        prev = cur->next_addr();
        continue;
      }
    }
  }
}


void IntervalWalker::next_interval() {
  IntervalKind kind;
  Interval* any   = _unhandled_first[anyKind];
  Interval* fixed = _unhandled_first[fixedKind];

  if (any != Interval::end()) {
    // intervals may start at same position -> prefer fixed interval
    kind = fixed != Interval::end() && fixed->from() <= any->from() ? fixedKind : anyKind;

    assert (kind == fixedKind && fixed->from() <= any->from() ||
            kind == anyKind   && any->from() <= fixed->from(), "wrong interval!!!");
    assert(any == Interval::end() || fixed == Interval::end() || any->from() != fixed->from() || kind == fixedKind, "if fixed and any-Interval start at same position, fixed must be processed first");

  } else if (fixed != Interval::end()) {
    kind = fixedKind;
  } else {
    _current = nullptr; return;
  }
  _current_kind = kind;
  _current = _unhandled_first[kind];
  _unhandled_first[kind] = _current->next();
  _current->set_next(Interval::end());
  _current->rewind_range();
}


void IntervalWalker::walk_to(int lir_op_id) {
  assert(_current_position <= lir_op_id, "can not walk backwards");
  while (current() != nullptr) {
    bool is_active = current()->from() <= lir_op_id;
    int id = is_active ? current()->from() : lir_op_id;

    TRACE_LINEAR_SCAN(2, if (_current_position < id) { tty->cr(); tty->print_cr("walk_to(%d) **************************************************************", id); })

    // set _current_position prior to call of walk_to
    _current_position = id;

    // call walk_to even if _current_position == id
    walk_to(activeState, id);
    walk_to(inactiveState, id);

    if (is_active) {
      current()->set_state(activeState);
      if (activate_current()) {
        append_sorted(active_first_addr(current_kind()), current());
        DEBUG_ONLY(interval_moved(current(), current_kind(), unhandledState, activeState);)
      }

      next_interval();
    } else {
      return;
    }
  }
}

#ifdef ASSERT
void IntervalWalker::interval_moved(Interval* interval, IntervalKind kind, IntervalState from, IntervalState to) {
  if (TraceLinearScanLevel >= 4) {
    #define print_state(state) \
    switch(state) {\
      case unhandledState: tty->print("unhandled"); break;\
      case activeState: tty->print("active"); break;\
      case inactiveState: tty->print("inactive"); break;\
      case handledState: tty->print("handled"); break;\
      default: ShouldNotReachHere(); \
    }

    print_state(from); tty->print(" to "); print_state(to);
    tty->fill_to(23);
    interval->print();

    #undef print_state
  }
}
#endif // ASSERT

// **** Implementation of LinearScanWalker **************************

LinearScanWalker::LinearScanWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first)
  : IntervalWalker(allocator, unhandled_fixed_first, unhandled_any_first)
  , _move_resolver(allocator)
{
  for (int i = 0; i < LinearScan::nof_regs; i++) {
    _spill_intervals[i] = new IntervalList(2);
  }
}


inline void LinearScanWalker::init_use_lists(bool only_process_use_pos) {
  for (int i = _first_reg; i <= _last_reg; i++) {
    _use_pos[i] = max_jint;

    if (!only_process_use_pos) {
      _block_pos[i] = max_jint;
      _spill_intervals[i]->clear();
    }
  }
}

inline void LinearScanWalker::exclude_from_use(int reg) {
  assert(reg < LinearScan::nof_regs, "interval must have a register assigned (stack slots not allowed)");
  if (reg >= _first_reg && reg <= _last_reg) {
    _use_pos[reg] = 0;
  }
}
inline void LinearScanWalker::exclude_from_use(Interval* i) {
  assert(i->assigned_reg() != any_reg, "interval has no register assigned");

  exclude_from_use(i->assigned_reg());
  exclude_from_use(i->assigned_regHi());
}

inline void LinearScanWalker::set_use_pos(int reg, Interval* i, int use_pos, bool only_process_use_pos) {
  assert(use_pos != 0, "must use exclude_from_use to set use_pos to 0");

  if (reg >= _first_reg && reg <= _last_reg) {
    if (_use_pos[reg] > use_pos) {
      _use_pos[reg] = use_pos;
    }
    if (!only_process_use_pos) {
      _spill_intervals[reg]->append(i);
    }
  }
}
inline void LinearScanWalker::set_use_pos(Interval* i, int use_pos, bool only_process_use_pos) {
  assert(i->assigned_reg() != any_reg, "interval has no register assigned");
  if (use_pos != -1) {
    set_use_pos(i->assigned_reg(), i, use_pos, only_process_use_pos);
    set_use_pos(i->assigned_regHi(), i, use_pos, only_process_use_pos);
  }
}

inline void LinearScanWalker::set_block_pos(int reg, Interval* i, int block_pos) {
  if (reg >= _first_reg && reg <= _last_reg) {
    if (_block_pos[reg] > block_pos) {
      _block_pos[reg] = block_pos;
    }
    if (_use_pos[reg] > block_pos) {
      _use_pos[reg] = block_pos;
    }
  }
}
inline void LinearScanWalker::set_block_pos(Interval* i, int block_pos) {
  assert(i->assigned_reg() != any_reg, "interval has no register assigned");
  if (block_pos != -1) {
    set_block_pos(i->assigned_reg(), i, block_pos);
    set_block_pos(i->assigned_regHi(), i, block_pos);
  }
}


void LinearScanWalker::free_exclude_active_fixed() {
  Interval* list = active_first(fixedKind);
  while (list != Interval::end()) {
    assert(list->assigned_reg() < LinearScan::nof_regs, "active interval must have a register assigned");
    exclude_from_use(list);
    list = list->next();
  }
}

void LinearScanWalker::free_exclude_active_any() {
  Interval* list = active_first(anyKind);
  while (list != Interval::end()) {
    exclude_from_use(list);
    list = list->next();
  }
}

void LinearScanWalker::free_collect_inactive_fixed(Interval* cur) {
  Interval* list = inactive_first(fixedKind);
  while (list != Interval::end()) {
    if (cur->to() <= list->current_from()) {
      assert(list->current_intersects_at(cur) == -1, "must not intersect");
      set_use_pos(list, list->current_from(), true);
    } else {
      set_use_pos(list, list->current_intersects_at(cur), true);
    }
    list = list->next();
  }
}

void LinearScanWalker::free_collect_inactive_any(Interval* cur) {
  Interval* list = inactive_first(anyKind);
  while (list != Interval::end()) {
    set_use_pos(list, list->current_intersects_at(cur), true);
    list = list->next();
  }
}

void LinearScanWalker::spill_exclude_active_fixed() {
  Interval* list = active_first(fixedKind);
  while (list != Interval::end()) {
    exclude_from_use(list);
    list = list->next();
  }
}

void LinearScanWalker::spill_block_inactive_fixed(Interval* cur) {
  Interval* list = inactive_first(fixedKind);
  while (list != Interval::end()) {
    if (cur->to() > list->current_from()) {
      set_block_pos(list, list->current_intersects_at(cur));
    } else {
      assert(list->current_intersects_at(cur) == -1, "invalid optimization: intervals intersect");
    }

    list = list->next();
  }
}

void LinearScanWalker::spill_collect_active_any() {
  Interval* list = active_first(anyKind);
  while (list != Interval::end()) {
    set_use_pos(list, MIN2(list->next_usage(loopEndMarker, _current_position), list->to()), false);
    list = list->next();
  }
}

void LinearScanWalker::spill_collect_inactive_any(Interval* cur) {
  Interval* list = inactive_first(anyKind);
  while (list != Interval::end()) {
    if (list->current_intersects(cur)) {
      set_use_pos(list, MIN2(list->next_usage(loopEndMarker, _current_position), list->to()), false);
    }
    list = list->next();
  }
}


void LinearScanWalker::insert_move(int op_id, Interval* src_it, Interval* dst_it) {
  // output all moves here. When source and target are equal, the move is
  // optimized away later in assign_reg_nums

  op_id = (op_id + 1) & ~1;
  BlockBegin* op_block = allocator()->block_of_op_with_id(op_id);
  assert(op_id > 0 && allocator()->block_of_op_with_id(op_id - 2) == op_block, "cannot insert move at block boundary");

  // calculate index of instruction inside instruction list of current block
  // the minimal index (for a block with no spill moves) can be calculated because the
  // numbering of instructions is known.
  // When the block already contains spill moves, the index must be increased until the
  // correct index is reached.
  LIR_OpList* list = op_block->lir()->instructions_list();
  int index = (op_id - list->at(0)->id()) / 2;
  assert(list->at(index)->id() <= op_id, "error in calculation");

  while (list->at(index)->id() != op_id) {
    index++;
    assert(0 <= index && index < list->length(), "index out of bounds");
  }
  assert(1 <= index && index < list->length(), "index out of bounds");
  assert(list->at(index)->id() == op_id, "error in calculation");

  // insert new instruction before instruction at position index
  _move_resolver.move_insert_position(op_block->lir(), index - 1);
  _move_resolver.add_mapping(src_it, dst_it);
}


int LinearScanWalker::find_optimal_split_pos(BlockBegin* min_block, BlockBegin* max_block, int max_split_pos) {
  int from_block_nr = min_block->linear_scan_number();
  int to_block_nr = max_block->linear_scan_number();

  assert(0 <= from_block_nr && from_block_nr < block_count(), "out of range");
  assert(0 <= to_block_nr && to_block_nr < block_count(), "out of range");
  assert(from_block_nr < to_block_nr, "must cross block boundary");

  // Try to split at end of max_block. If this would be after
  // max_split_pos, then use the begin of max_block
  int optimal_split_pos = max_block->last_lir_instruction_id() + 2;
  if (optimal_split_pos > max_split_pos) {
    optimal_split_pos = max_block->first_lir_instruction_id();
  }

  int min_loop_depth = max_block->loop_depth();
  for (int i = to_block_nr - 1; i >= from_block_nr; i--) {
    BlockBegin* cur = block_at(i);

    if (cur->loop_depth() < min_loop_depth) {
      // block with lower loop-depth found -> split at the end of this block
      min_loop_depth = cur->loop_depth();
      optimal_split_pos = cur->last_lir_instruction_id() + 2;
    }
  }
  assert(optimal_split_pos > allocator()->max_lir_op_id() || allocator()->is_block_begin(optimal_split_pos), "algorithm must move split pos to block boundary");

  return optimal_split_pos;
}


int LinearScanWalker::find_optimal_split_pos(Interval* it, int min_split_pos, int max_split_pos, bool do_loop_optimization) {
  int optimal_split_pos = -1;
  if (min_split_pos == max_split_pos) {
    // trivial case, no optimization of split position possible
    TRACE_LINEAR_SCAN(4, tty->print_cr("      min-pos and max-pos are equal, no optimization possible"));
    optimal_split_pos = min_split_pos;

  } else {
    assert(min_split_pos < max_split_pos, "must be true then");
    assert(min_split_pos > 0, "cannot access min_split_pos - 1 otherwise");

    // reason for using min_split_pos - 1: when the minimal split pos is exactly at the
    // beginning of a block, then min_split_pos is also a possible split position.
    // Use the block before as min_block, because then min_block->last_lir_instruction_id() + 2 == min_split_pos
    BlockBegin* min_block = allocator()->block_of_op_with_id(min_split_pos - 1);

    // reason for using max_split_pos - 1: otherwise there would be an assertion failure
    // when an interval ends at the end of the last block of the method
    // (in this case, max_split_pos == allocator()->max_lir_op_id() + 2, and there is no
    // block at this op_id)
    BlockBegin* max_block = allocator()->block_of_op_with_id(max_split_pos - 1);

    assert(min_block->linear_scan_number() <= max_block->linear_scan_number(), "invalid order");
    if (min_block == max_block) {
      // split position cannot be moved to block boundary, so split as late as possible
      TRACE_LINEAR_SCAN(4, tty->print_cr("      cannot move split pos to block boundary because min_pos and max_pos are in same block"));
      optimal_split_pos = max_split_pos;

    } else if (it->has_hole_between(max_split_pos - 1, max_split_pos) && !allocator()->is_block_begin(max_split_pos)) {
      // Do not move split position if the interval has a hole before max_split_pos.
      // Intervals resulting from Phi-Functions have more than one definition (marked
      // as mustHaveRegister) with a hole before each definition. When the register is needed
      // for the second definition, an earlier reloading is unnecessary.
      TRACE_LINEAR_SCAN(4, tty->print_cr("      interval has hole just before max_split_pos, so splitting at max_split_pos"));
      optimal_split_pos = max_split_pos;

    } else {
      // search optimal block boundary between min_split_pos and max_split_pos
      TRACE_LINEAR_SCAN(4, tty->print_cr("      moving split pos to optimal block boundary between block B%d and B%d", min_block->block_id(), max_block->block_id()));

      if (do_loop_optimization) {
        // Loop optimization: if a loop-end marker is found between min- and max-position,
        // then split before this loop
        int loop_end_pos = it->next_usage_exact(loopEndMarker, min_block->last_lir_instruction_id() + 2);
        TRACE_LINEAR_SCAN(4, tty->print_cr("      loop optimization: loop end found at pos %d", loop_end_pos));

        assert(loop_end_pos > min_split_pos, "invalid order");
        if (loop_end_pos < max_split_pos) {
          // loop-end marker found between min- and max-position
          // if it is not the end marker for the same loop as the min-position, then move
          // the max-position to this loop block.
          // Desired result: uses tagged as shouldHaveRegister inside a loop cause a reloading
          // of the interval (normally, only mustHaveRegister causes a reloading)
          BlockBegin* loop_block = allocator()->block_of_op_with_id(loop_end_pos);

          TRACE_LINEAR_SCAN(4, tty->print_cr("      interval is used in loop that ends in block B%d, so trying to move max_block back from B%d to B%d", loop_block->block_id(), max_block->block_id(), loop_block->block_id()));
          assert(loop_block != min_block, "loop_block and min_block must be different because block boundary is needed between");

          optimal_split_pos = find_optimal_split_pos(min_block, loop_block, loop_block->last_lir_instruction_id() + 2);
          if (optimal_split_pos == loop_block->last_lir_instruction_id() + 2) {
            optimal_split_pos = -1;
            TRACE_LINEAR_SCAN(4, tty->print_cr("      loop optimization not necessary"));
          } else {
            TRACE_LINEAR_SCAN(4, tty->print_cr("      loop optimization successful"));
          }
        }
      }

      if (optimal_split_pos == -1) {
        // not calculated by loop optimization
        optimal_split_pos = find_optimal_split_pos(min_block, max_block, max_split_pos);
      }
    }
  }
  TRACE_LINEAR_SCAN(4, tty->print_cr("      optimal split position: %d", optimal_split_pos));

  return optimal_split_pos;
}


/*
  split an interval at the optimal position between min_split_pos and
  max_split_pos in two parts:
  1) the left part has already a location assigned
  2) the right part is sorted into to the unhandled-list
*/
void LinearScanWalker::split_before_usage(Interval* it, int min_split_pos, int max_split_pos) {
  TRACE_LINEAR_SCAN(2, tty->print   ("----- splitting interval: "); it->print());
  TRACE_LINEAR_SCAN(2, tty->print_cr("      between %d and %d", min_split_pos, max_split_pos));

  assert(it->from() < min_split_pos,         "cannot split at start of interval");
  assert(current_position() < min_split_pos, "cannot split before current position");
  assert(min_split_pos <= max_split_pos,     "invalid order");
  assert(max_split_pos <= it->to(),          "cannot split after end of interval");

  int optimal_split_pos = find_optimal_split_pos(it, min_split_pos, max_split_pos, true);

  assert(min_split_pos <= optimal_split_pos && optimal_split_pos <= max_split_pos, "out of range");
  assert(optimal_split_pos <= it->to(),  "cannot split after end of interval");
  assert(optimal_split_pos > it->from(), "cannot split at start of interval");

  if (optimal_split_pos == it->to() && it->next_usage(mustHaveRegister, min_split_pos) == max_jint) {
    // the split position would be just before the end of the interval
    // -> no split at all necessary
    TRACE_LINEAR_SCAN(4, tty->print_cr("      no split necessary because optimal split position is at end of interval"));
    return;
  }

  // must calculate this before the actual split is performed and before split position is moved to odd op_id
  bool move_necessary = !allocator()->is_block_begin(optimal_split_pos) && !it->has_hole_between(optimal_split_pos - 1, optimal_split_pos);

  if (!allocator()->is_block_begin(optimal_split_pos)) {
    // move position before actual instruction (odd op_id)
    optimal_split_pos = (optimal_split_pos - 1) | 1;
  }

  TRACE_LINEAR_SCAN(4, tty->print_cr("      splitting at position %d", optimal_split_pos));
  assert(allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 1), "split pos must be odd when not on block boundary");
  assert(!allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 0), "split pos must be even on block boundary");

  Interval* split_part = it->split(optimal_split_pos);

  allocator()->append_interval(split_part);
  allocator()->copy_register_flags(it, split_part);
  split_part->set_insert_move_when_activated(move_necessary);
  append_to_unhandled(unhandled_first_addr(anyKind), split_part);

  TRACE_LINEAR_SCAN(2, tty->print_cr("      split interval in two parts (insert_move_when_activated: %d)", move_necessary));
  TRACE_LINEAR_SCAN(2, tty->print   ("      "); it->print());
  TRACE_LINEAR_SCAN(2, tty->print   ("      "); split_part->print());
}

/*
  split an interval at the optimal position between min_split_pos and
  max_split_pos in two parts:
  1) the left part has already a location assigned
  2) the right part is always on the stack and therefore ignored in further processing
*/
void LinearScanWalker::split_for_spilling(Interval* it) {
  // calculate allowed range of splitting position
  int max_split_pos = current_position();
  int min_split_pos = MAX2(it->previous_usage(shouldHaveRegister, max_split_pos) + 1, it->from());

  TRACE_LINEAR_SCAN(2, tty->print   ("----- splitting and spilling interval: "); it->print());
  TRACE_LINEAR_SCAN(2, tty->print_cr("      between %d and %d", min_split_pos, max_split_pos));

  assert(it->state() == activeState,     "why spill interval that is not active?");
  assert(it->from() <= min_split_pos,    "cannot split before start of interval");
  assert(min_split_pos <= max_split_pos, "invalid order");
  assert(max_split_pos < it->to(),       "cannot split at end end of interval");
  assert(current_position() < it->to(),  "interval must not end before current position");

  if (min_split_pos == it->from()) {
    // the whole interval is never used, so spill it entirely to memory
    TRACE_LINEAR_SCAN(2, tty->print_cr("      spilling entire interval because split pos is at beginning of interval"));
    assert(it->first_usage(shouldHaveRegister) > current_position(), "interval must not have use position before current_position");

    allocator()->assign_spill_slot(it);
    allocator()->change_spill_state(it, min_split_pos);

    // Also kick parent intervals out of register to memory when they have no use
    // position. This avoids short interval in register surrounded by intervals in
    // memory -> avoid useless moves from memory to register and back
    Interval* parent = it;
    while (parent != nullptr && parent->is_split_child()) {
      parent = parent->split_child_before_op_id(parent->from());

      if (parent->assigned_reg() < LinearScan::nof_regs) {
        if (parent->first_usage(shouldHaveRegister) == max_jint) {
          // parent is never used, so kick it out of its assigned register
          TRACE_LINEAR_SCAN(4, tty->print_cr("      kicking out interval %d out of its register because it is never used", parent->reg_num()));
          allocator()->assign_spill_slot(parent);
        } else {
          // do not go further back because the register is actually used by the interval
          parent = nullptr;
        }
      }
    }

  } else {
    // search optimal split pos, split interval and spill only the right hand part
    int optimal_split_pos = find_optimal_split_pos(it, min_split_pos, max_split_pos, false);

    assert(min_split_pos <= optimal_split_pos && optimal_split_pos <= max_split_pos, "out of range");
    assert(optimal_split_pos < it->to(), "cannot split at end of interval");
    assert(optimal_split_pos >= it->from(), "cannot split before start of interval");

    if (!allocator()->is_block_begin(optimal_split_pos)) {
      // move position before actual instruction (odd op_id)
      optimal_split_pos = (optimal_split_pos - 1) | 1;
    }

    TRACE_LINEAR_SCAN(4, tty->print_cr("      splitting at position %d", optimal_split_pos));
    assert(allocator()->is_block_begin(optimal_split_pos)  || (optimal_split_pos % 2 == 1), "split pos must be odd when not on block boundary");
    assert(!allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 0), "split pos must be even on block boundary");

    Interval* spilled_part = it->split(optimal_split_pos);
    allocator()->append_interval(spilled_part);
    allocator()->assign_spill_slot(spilled_part);
    allocator()->change_spill_state(spilled_part, optimal_split_pos);

    if (!allocator()->is_block_begin(optimal_split_pos)) {
      TRACE_LINEAR_SCAN(4, tty->print_cr("      inserting move from interval %d to %d", it->reg_num(), spilled_part->reg_num()));
      insert_move(optimal_split_pos, it, spilled_part);
    }

    // the current_split_child is needed later when moves are inserted for reloading
    assert(spilled_part->current_split_child() == it, "overwriting wrong current_split_child");
    spilled_part->make_current_split_child();

    TRACE_LINEAR_SCAN(2, tty->print_cr("      split interval in two parts"));
    TRACE_LINEAR_SCAN(2, tty->print   ("      "); it->print());
    TRACE_LINEAR_SCAN(2, tty->print   ("      "); spilled_part->print());
  }
}


void LinearScanWalker::split_stack_interval(Interval* it) {
  int min_split_pos = current_position() + 1;
  int max_split_pos = MIN2(it->first_usage(shouldHaveRegister), it->to());

  split_before_usage(it, min_split_pos, max_split_pos);
}

void LinearScanWalker::split_when_partial_register_available(Interval* it, int register_available_until) {
  int min_split_pos = MAX2(it->previous_usage(shouldHaveRegister, register_available_until), it->from() + 1);
  int max_split_pos = register_available_until;

  split_before_usage(it, min_split_pos, max_split_pos);
}

void LinearScanWalker::split_and_spill_interval(Interval* it) {
  assert(it->state() == activeState || it->state() == inactiveState, "other states not allowed");

  int current_pos = current_position();
  if (it->state() == inactiveState) {
    // the interval is currently inactive, so no spill slot is needed for now.
    // when the split part is activated, the interval has a new chance to get a register,
    // so in the best case no stack slot is necessary
    assert(it->has_hole_between(current_pos - 1, current_pos + 1), "interval can not be inactive otherwise");
    split_before_usage(it, current_pos + 1, current_pos + 1);

  } else {
    // search the position where the interval must have a register and split
    // at the optimal position before.
    // The new created part is added to the unhandled list and will get a register
    // when it is activated
    int min_split_pos = current_pos + 1;
    int max_split_pos = MIN2(it->next_usage(mustHaveRegister, min_split_pos), it->to());

    split_before_usage(it, min_split_pos, max_split_pos);

    assert(it->next_usage(mustHaveRegister, current_pos) == max_jint, "the remaining part is spilled to stack and therefore has no register");
    split_for_spilling(it);
  }
}

int LinearScanWalker::find_free_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split) {
  int min_full_reg = any_reg;
  int max_partial_reg = any_reg;

  for (int i = _first_reg; i <= _last_reg; i++) {
    if (i == ignore_reg) {
      // this register must be ignored

    } else if (_use_pos[i] >= interval_to) {
      // this register is free for the full interval
      if (min_full_reg == any_reg || i == hint_reg || (_use_pos[i] < _use_pos[min_full_reg] && min_full_reg != hint_reg)) {
        min_full_reg = i;
      }
    } else if (_use_pos[i] > reg_needed_until) {
      // this register is at least free until reg_needed_until
      if (max_partial_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_partial_reg] && max_partial_reg != hint_reg)) {
        max_partial_reg = i;
      }
    }
  }

  if (min_full_reg != any_reg) {
    return min_full_reg;
  } else if (max_partial_reg != any_reg) {
    *need_split = true;
    return max_partial_reg;
  } else {
    return any_reg;
  }
}

int LinearScanWalker::find_free_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split) {
  assert((_last_reg - _first_reg + 1) % 2 == 0, "adjust algorithm");

  int min_full_reg = any_reg;
  int max_partial_reg = any_reg;

  for (int i = _first_reg; i < _last_reg; i+=2) {
    if (_use_pos[i] >= interval_to && _use_pos[i + 1] >= interval_to) {
      // this register is free for the full interval
      if (min_full_reg == any_reg || i == hint_reg || (_use_pos[i] < _use_pos[min_full_reg] && min_full_reg != hint_reg)) {
        min_full_reg = i;
      }
    } else if (_use_pos[i] > reg_needed_until && _use_pos[i + 1] > reg_needed_until) {
      // this register is at least free until reg_needed_until
      if (max_partial_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_partial_reg] && max_partial_reg != hint_reg)) {
        max_partial_reg = i;
      }
    }
  }

  if (min_full_reg != any_reg) {
    return min_full_reg;
  } else if (max_partial_reg != any_reg) {
    *need_split = true;
    return max_partial_reg;
  } else {
    return any_reg;
  }
}

bool LinearScanWalker::alloc_free_reg(Interval* cur) {
  TRACE_LINEAR_SCAN(2, tty->print("trying to find free register for "); cur->print());

  init_use_lists(true);
  free_exclude_active_fixed();
  free_exclude_active_any();
  free_collect_inactive_fixed(cur);
  free_collect_inactive_any(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
  // (either as a fixed register or a normal allocated register in the past)
  // only intervals overlapping with cur are processed, non-overlapping invervals can be ignored safely
#ifdef ASSERT
  if (TraceLinearScanLevel >= 4) {
    tty->print_cr("      state of registers:");
    for (int i = _first_reg; i <= _last_reg; i++) {
      tty->print("      reg %d (", i);
      LinearScan::print_reg_num(i);
      tty->print_cr("): use_pos: %d", _use_pos[i]);
    }
  }
#endif

  int hint_reg, hint_regHi;
  Interval* register_hint = cur->register_hint();
  if (register_hint != nullptr) {
    hint_reg = register_hint->assigned_reg();
    hint_regHi = register_hint->assigned_regHi();

    if (_num_phys_regs == 2 && allocator()->is_precolored_cpu_interval(register_hint)) {
      assert(hint_reg != any_reg && hint_regHi == any_reg, "must be for fixed intervals");
      hint_regHi = hint_reg + 1;  // connect e.g. eax-edx
    }
#ifdef ASSERT
    if (TraceLinearScanLevel >= 4) {
      tty->print("      hint registers %d (", hint_reg);
      LinearScan::print_reg_num(hint_reg);
      tty->print("), %d (", hint_regHi);
      LinearScan::print_reg_num(hint_regHi);
      tty->print(") from interval ");
      register_hint->print();
    }
#endif
  } else {
    hint_reg = any_reg;
    hint_regHi = any_reg;
  }
  assert(hint_reg == any_reg || hint_reg != hint_regHi, "hint reg and regHi equal");
  assert(cur->assigned_reg() == any_reg && cur->assigned_regHi() == any_reg, "register already assigned to interval");

  // the register must be free at least until this position
  int reg_needed_until = cur->from() + 1;
  int interval_to = cur->to();

  bool need_split = false;
  int split_pos;
  int reg;
  int regHi = any_reg;

  if (_adjacent_regs) {
    reg = find_free_double_reg(reg_needed_until, interval_to, hint_reg, &need_split);
    regHi = reg + 1;
    if (reg == any_reg) {
      return false;
    }
    split_pos = MIN2(_use_pos[reg], _use_pos[regHi]);

  } else {
    reg = find_free_reg(reg_needed_until, interval_to, hint_reg, any_reg, &need_split);
    if (reg == any_reg) {
      return false;
    }
    split_pos = _use_pos[reg];

    if (_num_phys_regs == 2) {
      regHi = find_free_reg(reg_needed_until, interval_to, hint_regHi, reg, &need_split);

      if (_use_pos[reg] < interval_to && regHi == any_reg) {
        // do not split interval if only one register can be assigned until the split pos
        // (when one register is found for the whole interval, split&spill is only
        // performed for the hi register)
        return false;

      } else if (regHi != any_reg) {
        split_pos = MIN2(split_pos, _use_pos[regHi]);

        // sort register numbers to prevent e.g. a move from eax,ebx to ebx,eax
        if (reg > regHi) {
          int temp = reg;
          reg = regHi;
          regHi = temp;
        }
      }
    }
  }

  cur->assign_reg(reg, regHi);
#ifdef ASSERT
  if (TraceLinearScanLevel >= 2) {
    tty->print("      selected registers %d (", reg);
    LinearScan::print_reg_num(reg);
    tty->print("), %d (", regHi);
    LinearScan::print_reg_num(regHi);
    tty->print_cr(")");
  }
#endif
  assert(split_pos > 0, "invalid split_pos");
  if (need_split) {
    // register not available for full interval, so split it
    split_when_partial_register_available(cur, split_pos);
  }

  // only return true if interval is completely assigned
  return _num_phys_regs == 1 || regHi != any_reg;
}


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++) {
    if (i == ignore_reg) {
      // this register must be ignored

    } else if (_use_pos[i] > reg_needed_until) {
      if (max_reg == any_reg || _use_pos[i] > _use_pos[max_reg]) {
        max_reg = i;
      }
    }
  }

  if (max_reg != any_reg && _block_pos[max_reg] <= interval_to) {
    *need_split = true;
  }

  return max_reg;
}

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;

  for (int i = _first_reg; i < _last_reg; i+=2) {
    if (_use_pos[i] > reg_needed_until && _use_pos[i + 1] > reg_needed_until) {
      if (max_reg == any_reg || _use_pos[i] > _use_pos[max_reg]) {
        max_reg = i;
      }
    }
  }

  if (max_reg != any_reg &&
      (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to)) {
    *need_split = true;
  }

  return max_reg;
}

void LinearScanWalker::split_and_spill_intersecting_intervals(int reg, int regHi) {
  assert(reg != any_reg, "no register assigned");

  for (int i = 0; i < _spill_intervals[reg]->length(); i++) {
    Interval* it = _spill_intervals[reg]->at(i);
    remove_from_list(it);
    split_and_spill_interval(it);
  }

  if (regHi != any_reg) {
    IntervalList* processed = _spill_intervals[reg];
    for (int i = 0; i < _spill_intervals[regHi]->length(); i++) {
      Interval* it = _spill_intervals[regHi]->at(i);
      if (processed->find(it) == -1) {
        remove_from_list(it);
        split_and_spill_interval(it);
      }
    }
  }
}


// Split an Interval and spill it to memory so that cur can be placed in a register
void LinearScanWalker::alloc_locked_reg(Interval* cur) {
  TRACE_LINEAR_SCAN(2, tty->print("need to split and spill to get register for "); cur->print());

  // collect current usage of registers
  init_use_lists(false);
  spill_exclude_active_fixed();
  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();
  spill_collect_inactive_any(cur);

#ifdef ASSERT
  if (TraceLinearScanLevel >= 4) {
    tty->print_cr("      state of registers:");
    for (int i = _first_reg; i <= _last_reg; i++) {
      tty->print("      reg %d(", i);
      LinearScan::print_reg_num(i);
      tty->print("): use_pos: %d, block_pos: %d, intervals: ", _use_pos[i], _block_pos[i]);
      for (int j = 0; j < _spill_intervals[i]->length(); j++) {
        tty->print("%d ", _spill_intervals[i]->at(j)->reg_num());
      }
      tty->cr();
    }
  }
#endif

  // the register must be free at least until this position
  int reg_needed_until = MIN2(cur->first_usage(mustHaveRegister), cur->from() + 1);
  int interval_to = cur->to();
  assert (reg_needed_until > 0 && reg_needed_until < max_jint, "interval has no use");

  int split_pos = 0;
  int use_pos = 0;
  bool need_split = false;
  int reg, regHi;

  if (_adjacent_regs) {
    reg = find_locked_double_reg(reg_needed_until, interval_to, &need_split);
    regHi = reg + 1;

    if (reg != any_reg) {
      use_pos = MIN2(_use_pos[reg], _use_pos[regHi]);
      split_pos = MIN2(_block_pos[reg], _block_pos[regHi]);
    }
  } else {
    reg = find_locked_reg(reg_needed_until, interval_to, cur->assigned_reg(), &need_split);
    regHi = any_reg;

    if (reg != any_reg) {
      use_pos = _use_pos[reg];
      split_pos = _block_pos[reg];

      if (_num_phys_regs == 2) {
        if (cur->assigned_reg() != any_reg) {
          regHi = reg;
          reg = cur->assigned_reg();
        } else {
          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]);
          }
        }

        if (regHi != any_reg && reg > regHi) {
          // sort register numbers to prevent e.g. a move from eax,ebx to ebx,eax
          int temp = reg;
          reg = regHi;
          regHi = temp;
        }
      }
    }
  }

  if (reg == any_reg || (_num_phys_regs == 2 && regHi == any_reg) || use_pos <= cur->first_usage(mustHaveRegister)) {
    // the first use of cur is later than the spilling position -> spill cur
    TRACE_LINEAR_SCAN(4, tty->print_cr("able to spill current interval. first_usage(register): %d, use_pos: %d", cur->first_usage(mustHaveRegister), use_pos));

    if (cur->first_usage(mustHaveRegister) <= cur->from() + 1) {
      assert(false, "cannot spill interval that is used in first instruction (possible reason: no register found)");
      // assign a reasonable register and do a bailout in product mode to avoid errors
      allocator()->assign_spill_slot(cur);
      BAILOUT("LinearScan: no register found");
    }

    split_and_spill_interval(cur);
  } else {
#ifdef ASSERT
    if (TraceLinearScanLevel >= 4) {
      tty->print("decided to use register %d (", reg);
      LinearScan::print_reg_num(reg);
      tty->print("), %d (", regHi);
      LinearScan::print_reg_num(regHi);
      tty->print_cr(")");
    }
#endif
    assert(reg != any_reg && (_num_phys_regs == 1 || regHi != any_reg), "no register found");
    assert(split_pos > 0, "invalid split_pos");
    assert(need_split == false || split_pos > cur->from(), "splitting interval at from");

    cur->assign_reg(reg, regHi);
    if (need_split) {
      // register not available for full interval, so split it
      split_when_partial_register_available(cur, split_pos);
    }

    // perform splitting and spilling for all affected intervals
    split_and_spill_intersecting_intervals(reg, regHi);
  }
}

bool LinearScanWalker::no_allocation_possible(Interval* cur) {
#ifdef X86
  // fast calculation of intervals that can never get a register because the
  // the next instruction is a call that blocks all registers
  // Note: this does not work if callee-saved registers are available (e.g. on Sparc)

  // check if this interval is the result of a split operation
  // (an interval got a register until this position)
  int pos = cur->from();
  if ((pos & 1) == 1) {
    // the current instruction is a call that blocks all registers
    if (pos < allocator()->max_lir_op_id() && allocator()->has_call(pos + 1)) {
      TRACE_LINEAR_SCAN(4, tty->print_cr("      free register cannot be available because all registers blocked by following call"));

      // safety check that there is really no register available
      assert(alloc_free_reg(cur) == false, "found a register for this interval");
      return true;
    }

  }
#endif
  return false;
}

void LinearScanWalker::init_vars_for_alloc(Interval* cur) {
  BasicType type = cur->type();
  _num_phys_regs = LinearScan::num_physical_regs(type);
  _adjacent_regs = LinearScan::requires_adjacent_regs(type);

  if (pd_init_regs_for_alloc(cur)) {
    // the appropriate register range was selected.
  } else if (type == T_FLOAT || type == T_DOUBLE) {
    _first_reg = pd_first_fpu_reg;
    _last_reg = pd_last_fpu_reg;
  } else {
    _first_reg = pd_first_cpu_reg;
    _last_reg = FrameMap::last_cpu_reg();
  }

  assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range");
  assert(0 <= _last_reg && _last_reg < LinearScan::nof_regs, "out of range");
}


bool LinearScanWalker::is_move(LIR_Op* op, Interval* from, Interval* to) {
  if (op->code() != lir_move) {
    return false;
  }
  assert(op->as_Op1() != nullptr, "move must be LIR_Op1");

  LIR_Opr in = ((LIR_Op1*)op)->in_opr();
  LIR_Opr res = ((LIR_Op1*)op)->result_opr();
  return in->is_virtual() && res->is_virtual() && in->vreg_number() == from->reg_num() && res->vreg_number() == to->reg_num();
}

// optimization (especially for phi functions of nested loops):
// assign same spill slot to non-intersecting intervals
void LinearScanWalker::combine_spilled_intervals(Interval* cur) {
  if (cur->is_split_child()) {
    // optimization is only suitable for split parents
    return;
  }

  Interval* register_hint = cur->register_hint(false);
  if (register_hint == nullptr) {
    // cur is not the target of a move, otherwise register_hint would be set
    return;
  }
  assert(register_hint->is_split_parent(), "register hint must be split parent");

  if (cur->spill_state() != noOptimization || register_hint->spill_state() != noOptimization) {
    // combining the stack slots for intervals where spill move optimization is applied
    // is not benefitial and would cause problems
    return;
  }

  int begin_pos = cur->from();
  int end_pos = cur->to();
  if (end_pos > allocator()->max_lir_op_id() || (begin_pos & 1) != 0 || (end_pos & 1) != 0) {
    // safety check that lir_op_with_id is allowed
    return;
  }

  if (!is_move(allocator()->lir_op_with_id(begin_pos), register_hint, cur) || !is_move(allocator()->lir_op_with_id(end_pos), cur, register_hint)) {
    // cur and register_hint are not connected with two moves
    return;
  }

  Interval* begin_hint = register_hint->split_child_at_op_id(begin_pos, LIR_OpVisitState::inputMode);
  Interval* end_hint = register_hint->split_child_at_op_id(end_pos, LIR_OpVisitState::outputMode);
  if (begin_hint == end_hint || begin_hint->to() != begin_pos || end_hint->from() != end_pos) {
    // register_hint must be split, otherwise the re-writing of use positions does not work
    return;
  }

  assert(begin_hint->assigned_reg() != any_reg, "must have register assigned");
  assert(end_hint->assigned_reg() == any_reg, "must not have register assigned");
  assert(cur->first_usage(mustHaveRegister) == begin_pos, "must have use position at begin of interval because of move");
  assert(end_hint->first_usage(mustHaveRegister) == end_pos, "must have use position at begin of interval because of move");

  if (begin_hint->assigned_reg() < LinearScan::nof_regs) {
    // register_hint is not spilled at begin_pos, so it would not be benefitial to immediately spill cur
    return;
  }
  assert(register_hint->canonical_spill_slot() != -1, "must be set when part of interval was spilled");
  assert(!cur->intersects(register_hint), "cur should not intersect register_hint");

  if (cur->intersects_any_children_of(register_hint)) {
    // Bail out if cur intersects any split children of register_hint, which have the same spill slot as their parent. An overlap of two intervals with
    // the same spill slot could result in a situation where both intervals are spilled at the same time to the same stack location which is not correct.
    return;
  }

  // modify intervals such that cur gets the same stack slot as register_hint
  // delete use positions to prevent the intervals to get a register at beginning
  cur->set_canonical_spill_slot(register_hint->canonical_spill_slot());
  cur->remove_first_use_pos();
  end_hint->remove_first_use_pos();
}


// allocate a physical register or memory location to an interval
bool LinearScanWalker::activate_current() {
  Interval* cur = current();
  bool result = true;

  TRACE_LINEAR_SCAN(2, tty->print   ("+++++ activating interval "); cur->print());
  TRACE_LINEAR_SCAN(4, tty->print_cr("      split_parent: %d, insert_move_when_activated: %d", cur->split_parent()->reg_num(), cur->insert_move_when_activated()));

  if (cur->assigned_reg() >= LinearScan::nof_regs) {
    // activating an interval that has a stack slot assigned -> split it at first use position
    // used for method parameters
    TRACE_LINEAR_SCAN(4, tty->print_cr("      interval has spill slot assigned (method parameter) -> split it before first use"));

    split_stack_interval(cur);
    result = false;

  } else if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::must_start_in_memory)) {
    // activating an interval that must start in a stack slot, but may get a register later
    // used for lir_roundfp: rounding is done by store to stack and reload later
    TRACE_LINEAR_SCAN(4, tty->print_cr("      interval must start in stack slot -> split it before first use"));
    assert(cur->assigned_reg() == any_reg && cur->assigned_regHi() == any_reg, "register already assigned");

    allocator()->assign_spill_slot(cur);
    split_stack_interval(cur);
    result = false;

  } else if (cur->assigned_reg() == any_reg) {
    // interval has not assigned register -> normal allocation
    // (this is the normal case for most intervals)
    TRACE_LINEAR_SCAN(4, tty->print_cr("      normal allocation of register"));

    // assign same spill slot to non-intersecting intervals
    combine_spilled_intervals(cur);

    init_vars_for_alloc(cur);
    if (no_allocation_possible(cur) || !alloc_free_reg(cur)) {
      // no empty register available.
      // split and spill another interval so that this interval gets a register
      alloc_locked_reg(cur);
    }

    // spilled intervals need not be move to active-list
    if (cur->assigned_reg() >= LinearScan::nof_regs) {
      result = false;
    }
  }

  // load spilled values that become active from stack slot to register
  if (cur->insert_move_when_activated()) {
    assert(cur->is_split_child(), "must be");
    assert(cur->current_split_child() != nullptr, "must be");
    assert(cur->current_split_child()->reg_num() != cur->reg_num(), "cannot insert move between same interval");
    TRACE_LINEAR_SCAN(4, tty->print_cr("Inserting move from interval %d to %d because insert_move_when_activated is set", cur->current_split_child()->reg_num(), cur->reg_num()));

    insert_move(cur->from(), cur->current_split_child(), cur);
  }
  cur->make_current_split_child();

  return result; // true = interval is moved to active list
}


// Implementation of EdgeMoveOptimizer

EdgeMoveOptimizer::EdgeMoveOptimizer() :
  _edge_instructions(4),
  _edge_instructions_idx(4)
{
}

void EdgeMoveOptimizer::optimize(BlockList* code) {
  EdgeMoveOptimizer optimizer = EdgeMoveOptimizer();

  // ignore the first block in the list (index 0 is not processed)
  for (int i = code->length() - 1; i >= 1; i--) {
    BlockBegin* block = code->at(i);

    if (block->number_of_preds() > 1 && !block->is_set(BlockBegin::exception_entry_flag)) {
      optimizer.optimize_moves_at_block_end(block);
    }
    if (block->number_of_sux() == 2) {
      optimizer.optimize_moves_at_block_begin(block);
    }
  }
}


// clear all internal data structures
void EdgeMoveOptimizer::init_instructions() {
  _edge_instructions.clear();
  _edge_instructions_idx.clear();
}

// append a lir-instruction-list and the index of the current operation in to the list
void EdgeMoveOptimizer::append_instructions(LIR_OpList* instructions, int instructions_idx) {
  _edge_instructions.append(instructions);
  _edge_instructions_idx.append(instructions_idx);
}

// return the current operation of the given edge (predecessor or successor)
LIR_Op* EdgeMoveOptimizer::instruction_at(int edge) {
  LIR_OpList* instructions = _edge_instructions.at(edge);
  int idx = _edge_instructions_idx.at(edge);

  if (idx < instructions->length()) {
    return instructions->at(idx);
  } else {
    return nullptr;
  }
}

// removes the current operation of the given edge (predecessor or successor)
void EdgeMoveOptimizer::remove_cur_instruction(int edge, bool decrement_index) {
  LIR_OpList* instructions = _edge_instructions.at(edge);
  int idx = _edge_instructions_idx.at(edge);
  instructions->remove_at(idx);

  if (decrement_index) {
    _edge_instructions_idx.at_put(edge, idx - 1);
  }
}


bool EdgeMoveOptimizer::operations_different(LIR_Op* op1, LIR_Op* op2) {
  if (op1 == nullptr || op2 == nullptr) {
    // at least one block is already empty -> no optimization possible
    return true;
  }

  if (op1->code() == lir_move && op2->code() == lir_move) {
    assert(op1->as_Op1() != nullptr, "move must be LIR_Op1");
    assert(op2->as_Op1() != nullptr, "move must be LIR_Op1");
    LIR_Op1* move1 = (LIR_Op1*)op1;
    LIR_Op1* move2 = (LIR_Op1*)op2;
    if (move1->info() == move2->info() && move1->in_opr() == move2->in_opr() && move1->result_opr() == move2->result_opr()) {
      // these moves are exactly equal and can be optimized
      return false;
    }

  } else if (op1->code() == lir_fxch && op2->code() == lir_fxch) {
    assert(op1->as_Op1() != nullptr, "fxch must be LIR_Op1");
    assert(op2->as_Op1() != nullptr, "fxch must be LIR_Op1");
    LIR_Op1* fxch1 = (LIR_Op1*)op1;
    LIR_Op1* fxch2 = (LIR_Op1*)op2;
    if (fxch1->in_opr()->as_jint() == fxch2->in_opr()->as_jint()) {
      // equal FPU stack operations can be optimized
      return false;
    }

  } else if (op1->code() == lir_fpop_raw && op2->code() == lir_fpop_raw) {
    // equal FPU stack operations can be optimized
    return false;
  }

  // no optimization possible
  return true;
}

void EdgeMoveOptimizer::optimize_moves_at_block_end(BlockBegin* block) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("optimizing moves at end of block B%d", block->block_id()));

  if (block->is_predecessor(block)) {
    // currently we can't handle this correctly.
    return;
  }

  init_instructions();
  int num_preds = block->number_of_preds();
  assert(num_preds > 1, "do not call otherwise");
  assert(!block->is_set(BlockBegin::exception_entry_flag), "exception handlers not allowed");

  // setup a list with the lir-instructions of all predecessors
  int i;
  for (i = 0; i < num_preds; i++) {
    BlockBegin* pred = block->pred_at(i);
    LIR_OpList* pred_instructions = pred->lir()->instructions_list();

    if (pred->number_of_sux() != 1) {
      // this can happen with switch-statements where multiple edges are between
      // the same blocks.
      return;
    }

    assert(pred->number_of_sux() == 1, "can handle only one successor");
    assert(pred->sux_at(0) == block, "invalid control flow");
    assert(pred_instructions->last()->code() == lir_branch, "block with successor must end with branch");
    assert(pred_instructions->last()->as_OpBranch() != nullptr, "branch must be LIR_OpBranch");
    assert(pred_instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block must end with unconditional branch");

    if (pred_instructions->last()->info() != nullptr) {
      // can not optimize instructions when debug info is needed
      return;
    }

    // ignore the unconditional branch at the end of the block
    append_instructions(pred_instructions, pred_instructions->length() - 2);
  }


  // process lir-instructions while all predecessors end with the same instruction
  while (true) {
    LIR_Op* op = instruction_at(0);
    for (i = 1; i < num_preds; i++) {
      if (operations_different(op, instruction_at(i))) {
        // these instructions are different and cannot be optimized ->
        // no further optimization possible
        return;
      }
    }

    TRACE_LINEAR_SCAN(4, tty->print("found instruction that is equal in all %d predecessors: ", num_preds); op->print());

    // insert the instruction at the beginning of the current block
    block->lir()->insert_before(1, op);

    // delete the instruction at the end of all predecessors
    for (i = 0; i < num_preds; i++) {
      remove_cur_instruction(i, true);
    }
  }
}


void EdgeMoveOptimizer::optimize_moves_at_block_begin(BlockBegin* block) {
  TRACE_LINEAR_SCAN(4, tty->print_cr("optimization moves at begin of block B%d", block->block_id()));

  init_instructions();
  int num_sux = block->number_of_sux();

  LIR_OpList* cur_instructions = block->lir()->instructions_list();

  assert(num_sux == 2, "method should not be called otherwise");
  assert(cur_instructions->last()->code() == lir_branch, "block with successor must end with branch");
  assert(cur_instructions->last()->as_OpBranch() != nullptr, "branch must be LIR_OpBranch");
  assert(cur_instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block must end with unconditional branch");

  if (cur_instructions->last()->info() != nullptr) {
    // can no optimize instructions when debug info is needed
    return;
  }

  LIR_Op* branch = cur_instructions->at(cur_instructions->length() - 2);
  if (branch->info() != nullptr || (branch->code() != lir_branch && branch->code() != lir_cond_float_branch)) {
    // not a valid case for optimization
    // currently, only blocks that end with two branches (conditional branch followed
    // by unconditional branch) are optimized
    return;
  }

  // now it is guaranteed that the block ends with two branch instructions.
  // the instructions are inserted at the end of the block before these two branches
  int insert_idx = cur_instructions->length() - 2;

  int i;
#ifdef ASSERT
  for (i = insert_idx - 1; i >= 0; i--) {
    LIR_Op* op = cur_instructions->at(i);
    if ((op->code() == lir_branch || op->code() == lir_cond_float_branch) && ((LIR_OpBranch*)op)->block() != nullptr) {
      assert(false, "block with two successors can have only two branch instructions");
    }
  }
#endif

  // setup a list with the lir-instructions of all successors
  for (i = 0; i < num_sux; i++) {
    BlockBegin* sux = block->sux_at(i);
    LIR_OpList* sux_instructions = sux->lir()->instructions_list();

    assert(sux_instructions->at(0)->code() == lir_label, "block must start with label");

    if (sux->number_of_preds() != 1) {
      // this can happen with switch-statements where multiple edges are between
      // the same blocks.
      return;
    }
    assert(sux->pred_at(0) == block, "invalid control flow");
    assert(!sux->is_set(BlockBegin::exception_entry_flag), "exception handlers not allowed");

    // ignore the label at the beginning of the block
    append_instructions(sux_instructions, 1);
  }

  // process lir-instructions while all successors begin with the same instruction
  while (true) {
    LIR_Op* op = instruction_at(0);
    for (i = 1; i < num_sux; i++) {
      if (operations_different(op, instruction_at(i))) {
        // these instructions are different and cannot be optimized ->
        // no further optimization possible
        return;
      }
    }

    TRACE_LINEAR_SCAN(4, tty->print("----- found instruction that is equal in all %d successors: ", num_sux); op->print());

    // insert instruction at end of current block
    block->lir()->insert_before(insert_idx, op);
    insert_idx++;

    // delete the instructions at the beginning of all successors
    for (i = 0; i < num_sux; i++) {
      remove_cur_instruction(i, false);
    }
  }
}


// Implementation of ControlFlowOptimizer

ControlFlowOptimizer::ControlFlowOptimizer() :
  _original_preds(4)
{
}

void ControlFlowOptimizer::optimize(BlockList* code) {
  ControlFlowOptimizer optimizer = ControlFlowOptimizer();

  // push the OSR entry block to the end so that we're not jumping over it.
  BlockBegin* osr_entry = code->at(0)->end()->as_Base()->osr_entry();
  if (osr_entry) {
    int index = osr_entry->linear_scan_number();
    assert(code->at(index) == osr_entry, "wrong index");
    code->remove_at(index);
    code->append(osr_entry);
  }

  optimizer.reorder_short_loops(code);
  optimizer.delete_empty_blocks(code);
  optimizer.delete_unnecessary_jumps(code);
  optimizer.delete_jumps_to_return(code);
}

void ControlFlowOptimizer::reorder_short_loop(BlockList* code, BlockBegin* header_block, int header_idx) {
  int i = header_idx + 1;
  int max_end = MIN2(header_idx + ShortLoopSize, code->length());
  while (i < max_end && code->at(i)->loop_depth() >= header_block->loop_depth()) {
    i++;
  }

  if (i == code->length() || code->at(i)->loop_depth() < header_block->loop_depth()) {
    int end_idx = i - 1;
    BlockBegin* end_block = code->at(end_idx);

    if (end_block->number_of_sux() == 1 && end_block->sux_at(0) == header_block) {
      // short loop from header_idx to end_idx found -> reorder blocks such that
      // the header_block is the last block instead of the first block of the loop
      TRACE_LINEAR_SCAN(1, tty->print_cr("Reordering short loop: length %d, header B%d, end B%d",
                                         end_idx - header_idx + 1,
                                         header_block->block_id(), end_block->block_id()));

      for (int j = header_idx; j < end_idx; j++) {
        code->at_put(j, code->at(j + 1));
      }
      code->at_put(end_idx, header_block);

      // correct the flags so that any loop alignment occurs in the right place.
      assert(code->at(end_idx)->is_set(BlockBegin::backward_branch_target_flag), "must be backward branch target");
      code->at(end_idx)->clear(BlockBegin::backward_branch_target_flag);
      code->at(header_idx)->set(BlockBegin::backward_branch_target_flag);
    }
  }
}

void ControlFlowOptimizer::reorder_short_loops(BlockList* code) {
  for (int i = code->length() - 1; i >= 0; i--) {
    BlockBegin* block = code->at(i);

    if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) {
      reorder_short_loop(code, block, i);
    }
  }

  DEBUG_ONLY(verify(code));
}

// only blocks with exactly one successor can be deleted. Such blocks
// must always end with an unconditional branch to this successor
bool ControlFlowOptimizer::can_delete_block(BlockBegin* block) {
  if (block->number_of_sux() != 1 || block->number_of_exception_handlers() != 0 || block->is_entry_block()) {
    return false;
  }

  LIR_OpList* instructions = block->lir()->instructions_list();

  assert(instructions->length() >= 2, "block must have label and branch");
  assert(instructions->at(0)->code() == lir_label, "first instruction must always be a label");
  assert(instructions->last()->as_OpBranch() != nullptr, "last instruction must always be a branch");
  assert(instructions->last()->as_OpBranch()->cond() == lir_cond_always, "branch must be unconditional");
  assert(instructions->last()->as_OpBranch()->block() == block->sux_at(0), "branch target must be the successor");

  // block must have exactly one successor

  if (instructions->length() == 2 && instructions->last()->info() == nullptr) {
    return true;
  }
  return false;
}

// substitute branch targets in all branch-instructions of this blocks
void ControlFlowOptimizer::substitute_branch_target(BlockBegin* block, BlockBegin* target_from, BlockBegin* target_to) {
  TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting empty block: substituting from B%d to B%d inside B%d", target_from->block_id(), target_to->block_id(), block->block_id()));

  LIR_OpList* instructions = block->lir()->instructions_list();

  assert(instructions->at(0)->code() == lir_label, "first instruction must always be a label");
  for (int i = instructions->length() - 1; i >= 1; i--) {
    LIR_Op* op = instructions->at(i);

    if (op->code() == lir_branch || op->code() == lir_cond_float_branch) {
      assert(op->as_OpBranch() != nullptr, "branch must be of type LIR_OpBranch");
      LIR_OpBranch* branch = (LIR_OpBranch*)op;

      if (branch->block() == target_from) {
        branch->change_block(target_to);
      }
      if (branch->ublock() == target_from) {
        branch->change_ublock(target_to);
      }
    }
  }
}

void ControlFlowOptimizer::delete_empty_blocks(BlockList* code) {
  int old_pos = 0;
  int new_pos = 0;
  int num_blocks = code->length();

  while (old_pos < num_blocks) {
    BlockBegin* block = code->at(old_pos);

    if (can_delete_block(block)) {
      BlockBegin* new_target = block->sux_at(0);

      // propagate backward branch target flag for correct code alignment
      if (block->is_set(BlockBegin::backward_branch_target_flag)) {
        new_target->set(BlockBegin::backward_branch_target_flag);
      }

      // collect a list with all predecessors that contains each predecessor only once
      // the predecessors of cur are changed during the substitution, so a copy of the
      // predecessor list is necessary
      int j;
      _original_preds.clear();
      for (j = block->number_of_preds() - 1; j >= 0; j--) {
        BlockBegin* pred = block->pred_at(j);
        if (_original_preds.find(pred) == -1) {
          _original_preds.append(pred);
        }
      }

      for (j = _original_preds.length() - 1; j >= 0; j--) {
        BlockBegin* pred = _original_preds.at(j);
        substitute_branch_target(pred, block, new_target);
        pred->substitute_sux(block, new_target);
      }
    } else {
      // adjust position of this block in the block list if blocks before
      // have been deleted
      if (new_pos != old_pos) {
        code->at_put(new_pos, code->at(old_pos));
      }
      new_pos++;
    }
    old_pos++;
  }
  code->trunc_to(new_pos);

  DEBUG_ONLY(verify(code));
}

void ControlFlowOptimizer::delete_unnecessary_jumps(BlockList* code) {
  // skip the last block because there a branch is always necessary
  for (int i = code->length() - 2; i >= 0; i--) {
    BlockBegin* block = code->at(i);
    LIR_OpList* instructions = block->lir()->instructions_list();

    LIR_Op* last_op = instructions->last();
    if (last_op->code() == lir_branch) {
      assert(last_op->as_OpBranch() != nullptr, "branch must be of type LIR_OpBranch");
      LIR_OpBranch* last_branch = (LIR_OpBranch*)last_op;

      assert(last_branch->block() != nullptr, "last branch must always have a block as target");
      assert(last_branch->label() == last_branch->block()->label(), "must be equal");

      if (last_branch->info() == nullptr) {
        if (last_branch->block() == code->at(i + 1)) {

          TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id()));

          // delete last branch instruction
          instructions->trunc_to(instructions->length() - 1);

        } else {
          LIR_Op* prev_op = instructions->at(instructions->length() - 2);
          if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) {
            assert(prev_op->as_OpBranch() != nullptr, "branch must be of type LIR_OpBranch");
            LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op;

            if (prev_branch->stub() == nullptr) {

              LIR_Op2* prev_cmp = nullptr;
              // There might be a cmove inserted for profiling which depends on the same
              // compare. If we change the condition of the respective compare, we have
              // to take care of this cmove as well.
              LIR_Op4* prev_cmove = nullptr;

              for(int j = instructions->length() - 3; j >= 0 && prev_cmp == nullptr; j--) {
                prev_op = instructions->at(j);
                // check for the cmove
                if (prev_op->code() == lir_cmove) {
                  assert(prev_op->as_Op4() != nullptr, "cmove must be of type LIR_Op4");
                  prev_cmove = (LIR_Op4*)prev_op;
                  assert(prev_branch->cond() == prev_cmove->condition(), "should be the same");
                }
                if (prev_op->code() == lir_cmp) {
                  assert(prev_op->as_Op2() != nullptr, "branch must be of type LIR_Op2");
                  prev_cmp = (LIR_Op2*)prev_op;
                  assert(prev_branch->cond() == prev_cmp->condition(), "should be the same");
                }
              }
              // Guarantee because it is dereferenced below.
              guarantee(prev_cmp != nullptr, "should have found comp instruction for branch");
              if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == nullptr) {

                TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id()));

                // eliminate a conditional branch to the immediate successor
                prev_branch->change_block(last_branch->block());
                prev_branch->negate_cond();
                prev_cmp->set_condition(prev_branch->cond());
                instructions->trunc_to(instructions->length() - 1);
                // if we do change the condition, we have to change the cmove as well
                if (prev_cmove != nullptr) {
                  prev_cmove->set_condition(prev_branch->cond());
                  LIR_Opr t = prev_cmove->in_opr1();
                  prev_cmove->set_in_opr1(prev_cmove->in_opr2());
                  prev_cmove->set_in_opr2(t);
                }
              }
            }
          }
        }
      }
    }
  }

  DEBUG_ONLY(verify(code));
}

void ControlFlowOptimizer::delete_jumps_to_return(BlockList* code) {
#ifdef ASSERT
  ResourceBitMap return_converted(BlockBegin::number_of_blocks());
#endif

  for (int i = code->length() - 1; i >= 0; i--) {
    BlockBegin* block = code->at(i);
    LIR_OpList* cur_instructions = block->lir()->instructions_list();
    LIR_Op*     cur_last_op = cur_instructions->last();

    assert(cur_instructions->at(0)->code() == lir_label, "first instruction must always be a label");
    if (cur_instructions->length() == 2 && cur_last_op->code() == lir_return) {
      // the block contains only a label and a return
      // if a predecessor ends with an unconditional jump to this block, then the jump
      // can be replaced with a return instruction
      //
      // Note: the original block with only a return statement cannot be deleted completely
      //       because the predecessors might have other (conditional) jumps to this block
      //       -> this may lead to unnecessary return instructions in the final code

      assert(cur_last_op->info() == nullptr, "return instructions do not have debug information");
      assert(block->number_of_sux() == 0 ||
             (return_converted.at(block->block_id()) && block->number_of_sux() == 1),
             "blocks that end with return must not have successors");

      assert(cur_last_op->as_Op1() != nullptr, "return must be LIR_Op1");
      LIR_Opr return_opr = ((LIR_Op1*)cur_last_op)->in_opr();

      for (int j = block->number_of_preds() - 1; j >= 0; j--) {
        BlockBegin* pred = block->pred_at(j);
        LIR_OpList* pred_instructions = pred->lir()->instructions_list();
        LIR_Op*     pred_last_op = pred_instructions->last();

        if (pred_last_op->code() == lir_branch) {
          assert(pred_last_op->as_OpBranch() != nullptr, "branch must be LIR_OpBranch");
          LIR_OpBranch* pred_last_branch = (LIR_OpBranch*)pred_last_op;

          if (pred_last_branch->block() == block && pred_last_branch->cond() == lir_cond_always && pred_last_branch->info() == nullptr) {
            // replace the jump to a return with a direct return
            // Note: currently the edge between the blocks is not deleted
            pred_instructions->at_put(pred_instructions->length() - 1, new LIR_OpReturn(return_opr));
#ifdef ASSERT
            return_converted.set_bit(pred->block_id());
#endif
          }
        }
      }
    }
  }
}


#ifdef ASSERT
void ControlFlowOptimizer::verify(BlockList* code) {
  for (int i = 0; i < code->length(); i++) {
    BlockBegin* block = code->at(i);
    LIR_OpList* instructions = block->lir()->instructions_list();

    int j;
    for (j = 0; j < instructions->length(); j++) {
      LIR_OpBranch* op_branch = instructions->at(j)->as_OpBranch();

      if (op_branch != nullptr) {
        assert(op_branch->block() == nullptr || code->find(op_branch->block()) != -1, "branch target not valid");
        assert(op_branch->ublock() == nullptr || code->find(op_branch->ublock()) != -1, "branch target not valid");
      }
    }

    for (j = 0; j < block->number_of_sux() - 1; j++) {
      BlockBegin* sux = block->sux_at(j);
      assert(code->find(sux) != -1, "successor not valid");
    }

    for (j = 0; j < block->number_of_preds() - 1; j++) {
      BlockBegin* pred = block->pred_at(j);
      assert(code->find(pred) != -1, "successor not valid");
    }
  }
}
#endif


#ifndef PRODUCT

// Implementation of LinearStatistic

const char* LinearScanStatistic::counter_name(int counter_idx) {
  switch (counter_idx) {
    case counter_method:          return "compiled methods";
    case counter_fpu_method:      return "methods using fpu";
    case counter_loop_method:     return "methods with loops";
    case counter_exception_method:return "methods with xhandler";

    case counter_loop:            return "loops";
    case counter_block:           return "blocks";
    case counter_loop_block:      return "blocks inside loop";
    case counter_exception_block: return "exception handler entries";
    case counter_interval:        return "intervals";
    case counter_fixed_interval:  return "fixed intervals";
    case counter_range:           return "ranges";
    case counter_fixed_range:     return "fixed ranges";
    case counter_use_pos:         return "use positions";
    case counter_fixed_use_pos:   return "fixed use positions";
    case counter_spill_slots:     return "spill slots";

    // counter for classes of lir instructions
    case counter_instruction:     return "total instructions";
    case counter_label:           return "labels";
    case counter_entry:           return "method entries";
    case counter_return:          return "method returns";
    case counter_call:            return "method calls";
    case counter_move:            return "moves";
    case counter_cmp:             return "compare";
    case counter_cond_branch:     return "conditional branches";
    case counter_uncond_branch:   return "unconditional branches";
    case counter_stub_branch:     return "branches to stub";
    case counter_alu:             return "artithmetic + logic";
    case counter_alloc:           return "allocations";
    case counter_sync:            return "synchronisation";
    case counter_throw:           return "throw";
    case counter_unwind:          return "unwind";
    case counter_typecheck:       return "type+null-checks";
    case counter_fpu_stack:       return "fpu-stack";
    case counter_misc_inst:       return "other instructions";
    case counter_other_inst:      return "misc. instructions";

    // counter for different types of moves
    case counter_move_total:      return "total moves";
    case counter_move_reg_reg:    return "register->register";
    case counter_move_reg_stack:  return "register->stack";
    case counter_move_stack_reg:  return "stack->register";
    case counter_move_stack_stack:return "stack->stack";
    case counter_move_reg_mem:    return "register->memory";
    case counter_move_mem_reg:    return "memory->register";
    case counter_move_const_any:  return "constant->any";

    case blank_line_1:            return "";
    case blank_line_2:            return "";

    default: ShouldNotReachHere(); return "";
  }
}

LinearScanStatistic::Counter LinearScanStatistic::base_counter(int counter_idx) {
  if (counter_idx == counter_fpu_method || counter_idx == counter_loop_method || counter_idx == counter_exception_method) {
    return counter_method;
  } else if (counter_idx == counter_loop_block || counter_idx == counter_exception_block) {
    return counter_block;
  } else if (counter_idx >= counter_instruction && counter_idx <= counter_other_inst) {
    return counter_instruction;
  } else if (counter_idx >= counter_move_total && counter_idx <= counter_move_const_any) {
    return counter_move_total;
  }
  return invalid_counter;
}

LinearScanStatistic::LinearScanStatistic() {
  for (int i = 0; i < number_of_counters; i++) {
    _counters_sum[i] = 0;
    _counters_max[i] = -1;
  }

}

// add the method-local numbers to the total sum
void LinearScanStatistic::sum_up(LinearScanStatistic &method_statistic) {
  for (int i = 0; i < number_of_counters; i++) {
    _counters_sum[i] += method_statistic._counters_sum[i];
    _counters_max[i] = MAX2(_counters_max[i], method_statistic._counters_sum[i]);
  }
}

void LinearScanStatistic::print(const char* title) {
  if (CountLinearScan || TraceLinearScanLevel > 0) {
    tty->cr();
    tty->print_cr("***** LinearScan statistic - %s *****", title);

    for (int i = 0; i < number_of_counters; i++) {
      if (_counters_sum[i] > 0 || _counters_max[i] >= 0) {
        tty->print("%25s: %8d", counter_name(i), _counters_sum[i]);

        LinearScanStatistic::Counter cntr = base_counter(i);
        if (cntr != invalid_counter) {
          tty->print("  (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[cntr]);
        } else {
          tty->print("           ");
        }

        if (_counters_max[i] >= 0) {
          tty->print("%8d", _counters_max[i]);
        }
      }
      tty->cr();
    }
  }
}

void LinearScanStatistic::collect(LinearScan* allocator) {
  inc_counter(counter_method);
  if (allocator->has_fpu_registers()) {
    inc_counter(counter_fpu_method);
  }
  if (allocator->num_loops() > 0) {
    inc_counter(counter_loop_method);
  }
  inc_counter(counter_loop, allocator->num_loops());
  inc_counter(counter_spill_slots, allocator->max_spills());

  int i;
  for (i = 0; i < allocator->interval_count(); i++) {
    Interval* cur = allocator->interval_at(i);

    if (cur != nullptr) {
      inc_counter(counter_interval);
      inc_counter(counter_use_pos, cur->num_use_positions());
      if (LinearScan::is_precolored_interval(cur)) {
        inc_counter(counter_fixed_interval);
        inc_counter(counter_fixed_use_pos, cur->num_use_positions());
      }

      Range* range = cur->first();
      while (range != Range::end()) {
        inc_counter(counter_range);
        if (LinearScan::is_precolored_interval(cur)) {
          inc_counter(counter_fixed_range);
        }
        range = range->next();
      }
    }
  }

  bool has_xhandlers = false;
  // Note: only count blocks that are in code-emit order
  for (i = 0; i < allocator->ir()->code()->length(); i++) {
    BlockBegin* cur = allocator->ir()->code()->at(i);

    inc_counter(counter_block);
    if (cur->loop_depth() > 0) {
      inc_counter(counter_loop_block);
    }
    if (cur->is_set(BlockBegin::exception_entry_flag)) {
      inc_counter(counter_exception_block);
      has_xhandlers = true;
    }

    LIR_OpList* instructions = cur->lir()->instructions_list();
    for (int j = 0; j < instructions->length(); j++) {
      LIR_Op* op = instructions->at(j);

      inc_counter(counter_instruction);

      switch (op->code()) {
        case lir_label:           inc_counter(counter_label); break;
        case lir_std_entry:
        case lir_osr_entry:       inc_counter(counter_entry); break;
        case lir_return:          inc_counter(counter_return); break;

        case lir_rtcall:
        case lir_static_call:
        case lir_optvirtual_call: inc_counter(counter_call); break;

        case lir_move: {
          inc_counter(counter_move);
          inc_counter(counter_move_total);

          LIR_Opr in = op->as_Op1()->in_opr();
          LIR_Opr res = op->as_Op1()->result_opr();
          if (in->is_register()) {
            if (res->is_register()) {
              inc_counter(counter_move_reg_reg);
            } else if (res->is_stack()) {
              inc_counter(counter_move_reg_stack);
            } else if (res->is_address()) {
              inc_counter(counter_move_reg_mem);
            } else {
              ShouldNotReachHere();
            }
          } else if (in->is_stack()) {
            if (res->is_register()) {
              inc_counter(counter_move_stack_reg);
            } else {
              inc_counter(counter_move_stack_stack);
            }
          } else if (in->is_address()) {
            assert(res->is_register(), "must be");
            inc_counter(counter_move_mem_reg);
          } else if (in->is_constant()) {
            inc_counter(counter_move_const_any);
          } else {
            ShouldNotReachHere();
          }
          break;
        }

        case lir_cmp:             inc_counter(counter_cmp); break;

        case lir_branch:
        case lir_cond_float_branch: {
          LIR_OpBranch* branch = op->as_OpBranch();
          if (branch->block() == nullptr) {
            inc_counter(counter_stub_branch);
          } else if (branch->cond() == lir_cond_always) {
            inc_counter(counter_uncond_branch);
          } else {
            inc_counter(counter_cond_branch);
          }
          break;
        }

        case lir_neg:
        case lir_add:
        case lir_sub:
        case lir_mul:
        case lir_div:
        case lir_rem:
        case lir_sqrt:
        case lir_abs:
        case lir_f2hf:
        case lir_hf2f:
        case lir_log10:
        case lir_logic_and:
        case lir_logic_or:
        case lir_logic_xor:
        case lir_shl:
        case lir_shr:
        case lir_ushr:            inc_counter(counter_alu); break;

        case lir_alloc_object:
        case lir_alloc_array:     inc_counter(counter_alloc); break;

        case lir_monaddr:
        case lir_lock:
        case lir_unlock:          inc_counter(counter_sync); break;

        case lir_throw:           inc_counter(counter_throw); break;

        case lir_unwind:          inc_counter(counter_unwind); break;

        case lir_null_check:
        case lir_leal:
        case lir_instanceof:
        case lir_checkcast:
        case lir_store_check:     inc_counter(counter_typecheck); break;

        case lir_fpop_raw:
        case lir_fxch:
        case lir_fld:             inc_counter(counter_fpu_stack); break;

        case lir_nop:
        case lir_push:
        case lir_pop:
        case lir_convert:
        case lir_roundfp:
        case lir_cmove:           inc_counter(counter_misc_inst); break;

        default:                  inc_counter(counter_other_inst); break;
      }
    }
  }

  if (has_xhandlers) {
    inc_counter(counter_exception_method);
  }
}

void LinearScanStatistic::compute(LinearScan* allocator, LinearScanStatistic &global_statistic) {
  if (CountLinearScan || TraceLinearScanLevel > 0) {

    LinearScanStatistic local_statistic = LinearScanStatistic();

    local_statistic.collect(allocator);
    global_statistic.sum_up(local_statistic);

    if (TraceLinearScanLevel > 2) {
      local_statistic.print("current local statistic");
    }
  }
}


// Implementation of LinearTimers

LinearScanTimers::LinearScanTimers() {
  for (int i = 0; i < number_of_timers; i++) {
    timer(i)->reset();
  }
}

const char* LinearScanTimers::timer_name(int idx) {
  switch (idx) {
    case timer_do_nothing:               return "Nothing (Time Check)";
    case timer_number_instructions:      return "Number Instructions";
    case timer_compute_local_live_sets:  return "Local Live Sets";
    case timer_compute_global_live_sets: return "Global Live Sets";
    case timer_build_intervals:          return "Build Intervals";
    case timer_sort_intervals_before:    return "Sort Intervals Before";
    case timer_allocate_registers:       return "Allocate Registers";
    case timer_resolve_data_flow:        return "Resolve Data Flow";
    case timer_sort_intervals_after:     return "Sort Intervals After";
    case timer_eliminate_spill_moves:    return "Spill optimization";
    case timer_assign_reg_num:           return "Assign Reg Num";
    case timer_allocate_fpu_stack:       return "Allocate FPU Stack";
    case timer_optimize_lir:             return "Optimize LIR";
    default: ShouldNotReachHere();       return "";
  }
}

void LinearScanTimers::begin_method() {
  if (TimeEachLinearScan) {
    // reset all timers to measure only current method
    for (int i = 0; i < number_of_timers; i++) {
      timer(i)->reset();
    }
  }
}

void LinearScanTimers::end_method(LinearScan* allocator) {
  if (TimeEachLinearScan) {

    double c = timer(timer_do_nothing)->seconds();
    double total = 0;
    for (int i = 1; i < number_of_timers; i++) {
      total += timer(i)->seconds() - c;
    }

    if (total >= 0.0005) {
      // print all information in one line for automatic processing
      tty->print("@"); allocator->compilation()->method()->print_name();

      tty->print("@ %d ", allocator->compilation()->method()->code_size());
      tty->print("@ %d ", allocator->block_at(allocator->block_count() - 1)->last_lir_instruction_id() / 2);
      tty->print("@ %d ", allocator->block_count());
      tty->print("@ %d ", allocator->num_virtual_regs());
      tty->print("@ %d ", allocator->interval_count());
      tty->print("@ %d ", allocator->_num_calls);
      tty->print("@ %d ", allocator->num_loops());

      tty->print("@ %6.6f ", total);
      for (int i = 1; i < number_of_timers; i++) {
        tty->print("@ %4.1f ", ((timer(i)->seconds() - c) / total) * 100);
      }
      tty->cr();
    }
  }
}

void LinearScanTimers::print(double total_time) {
  if (TimeLinearScan) {
    // correction value: sum of dummy-timer that only measures the time that
    // is necessary to start and stop itself
    double c = timer(timer_do_nothing)->seconds();

    for (int i = 0; i < number_of_timers; i++) {
      double t = timer(i)->seconds();
      tty->print_cr("    %25s: %6.3f s (%4.1f%%)  corrected: %6.3f s (%4.1f%%)", timer_name(i), t, (t / total_time) * 100.0, t - c, (t - c) / (total_time - 2 * number_of_timers * c) * 100);
    }
  }
}

#endif // #ifndef PRODUCT
