/*
 * Copyright (c) 1997, 2025, 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 "gc/shared/barrierSet.hpp"
#include "gc/shared/c2/barrierSetC2.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/compressedOops.hpp"
#include "opto/ad.hpp"
#include "opto/addnode.hpp"
#include "opto/callnode.hpp"
#include "opto/idealGraphPrinter.hpp"
#include "opto/matcher.hpp"
#include "opto/memnode.hpp"
#include "opto/movenode.hpp"
#include "opto/opcodes.hpp"
#include "opto/regmask.hpp"
#include "opto/rootnode.hpp"
#include "opto/runtime.hpp"
#include "opto/type.hpp"
#include "opto/vectornode.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/align.hpp"

OptoReg::Name OptoReg::c_frame_pointer;

const RegMask *Matcher::idealreg2regmask[_last_machine_leaf];
RegMask Matcher::mreg2regmask[_last_Mach_Reg];
RegMask Matcher::caller_save_regmask;
RegMask Matcher::caller_save_regmask_exclude_soe;
RegMask Matcher::mh_caller_save_regmask;
RegMask Matcher::mh_caller_save_regmask_exclude_soe;
RegMask Matcher::STACK_ONLY_mask;
RegMask Matcher::c_frame_ptr_mask;
const uint Matcher::_begin_rematerialize = _BEGIN_REMATERIALIZE;
const uint Matcher::_end_rematerialize   = _END_REMATERIALIZE;

//---------------------------Matcher-------------------------------------------
Matcher::Matcher()
: PhaseTransform( Phase::Ins_Select ),
  _states_arena(Chunk::medium_size, mtCompiler, Arena::Tag::tag_states),
  _new_nodes(C->comp_arena()),
  _visited(&_states_arena),
  _shared(&_states_arena),
  _dontcare(&_states_arena),
  _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp),
  _swallowed(swallowed),
  _begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE),
  _end_inst_chain_rule(_END_INST_CHAIN_RULE),
  _must_clone(must_clone),
  _shared_nodes(C->comp_arena()),
#ifndef PRODUCT
  _old2new_map(C->comp_arena()),
  _new2old_map(C->comp_arena()),
  _reused(C->comp_arena()),
#endif // !PRODUCT
  _allocation_started(false),
  _ruleName(ruleName),
  _register_save_policy(register_save_policy),
  _c_reg_save_policy(c_reg_save_policy),
  _register_save_type(register_save_type) {
  C->set_matcher(this);

  idealreg2spillmask  [Op_RegI] = nullptr;
  idealreg2spillmask  [Op_RegN] = nullptr;
  idealreg2spillmask  [Op_RegL] = nullptr;
  idealreg2spillmask  [Op_RegF] = nullptr;
  idealreg2spillmask  [Op_RegD] = nullptr;
  idealreg2spillmask  [Op_RegP] = nullptr;
  idealreg2spillmask  [Op_VecA] = nullptr;
  idealreg2spillmask  [Op_VecS] = nullptr;
  idealreg2spillmask  [Op_VecD] = nullptr;
  idealreg2spillmask  [Op_VecX] = nullptr;
  idealreg2spillmask  [Op_VecY] = nullptr;
  idealreg2spillmask  [Op_VecZ] = nullptr;
  idealreg2spillmask  [Op_RegFlags] = nullptr;
  idealreg2spillmask  [Op_RegVectMask] = nullptr;

  idealreg2debugmask  [Op_RegI] = nullptr;
  idealreg2debugmask  [Op_RegN] = nullptr;
  idealreg2debugmask  [Op_RegL] = nullptr;
  idealreg2debugmask  [Op_RegF] = nullptr;
  idealreg2debugmask  [Op_RegD] = nullptr;
  idealreg2debugmask  [Op_RegP] = nullptr;
  idealreg2debugmask  [Op_VecA] = nullptr;
  idealreg2debugmask  [Op_VecS] = nullptr;
  idealreg2debugmask  [Op_VecD] = nullptr;
  idealreg2debugmask  [Op_VecX] = nullptr;
  idealreg2debugmask  [Op_VecY] = nullptr;
  idealreg2debugmask  [Op_VecZ] = nullptr;
  idealreg2debugmask  [Op_RegFlags] = nullptr;
  idealreg2debugmask  [Op_RegVectMask] = nullptr;

  idealreg2mhdebugmask[Op_RegI] = nullptr;
  idealreg2mhdebugmask[Op_RegN] = nullptr;
  idealreg2mhdebugmask[Op_RegL] = nullptr;
  idealreg2mhdebugmask[Op_RegF] = nullptr;
  idealreg2mhdebugmask[Op_RegD] = nullptr;
  idealreg2mhdebugmask[Op_RegP] = nullptr;
  idealreg2mhdebugmask[Op_VecA] = nullptr;
  idealreg2mhdebugmask[Op_VecS] = nullptr;
  idealreg2mhdebugmask[Op_VecD] = nullptr;
  idealreg2mhdebugmask[Op_VecX] = nullptr;
  idealreg2mhdebugmask[Op_VecY] = nullptr;
  idealreg2mhdebugmask[Op_VecZ] = nullptr;
  idealreg2mhdebugmask[Op_RegFlags] = nullptr;
  idealreg2mhdebugmask[Op_RegVectMask] = nullptr;

  DEBUG_ONLY(_mem_node = nullptr;)   // Ideal memory node consumed by mach node
}

//------------------------------warp_incoming_stk_arg------------------------
// This warps a VMReg into an OptoReg::Name
OptoReg::Name Matcher::warp_incoming_stk_arg( VMReg reg ) {
  OptoReg::Name warped;
  if( reg->is_stack() ) {  // Stack slot argument?
    warped = OptoReg::add(_old_SP, reg->reg2stack() );
    warped = OptoReg::add(warped, C->out_preserve_stack_slots());
    if( warped >= _in_arg_limit )
      _in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen
    if (!RegMask::can_represent_arg(warped)) {
      // the compiler cannot represent this method's calling sequence
      // Bailout. We do not have space to represent all arguments.
      C->record_method_not_compilable("unsupported incoming calling sequence");
      return OptoReg::Bad;
    }
    return warped;
  }
  return OptoReg::as_OptoReg(reg);
}

//---------------------------compute_old_SP------------------------------------
OptoReg::Name Compile::compute_old_SP() {
  int fixed    = fixed_slots();
  int preserve = in_preserve_stack_slots();
  return OptoReg::stack2reg(align_up(fixed + preserve, (int)Matcher::stack_alignment_in_slots()));
}



#ifdef ASSERT
void Matcher::verify_new_nodes_only(Node* xroot) {
  // Make sure that the new graph only references new nodes
  ResourceMark rm;
  Unique_Node_List worklist;
  VectorSet visited;
  worklist.push(xroot);
  while (worklist.size() > 0) {
    Node* n = worklist.pop();
    if (visited.test_set(n->_idx)) {
      continue;
    }
    assert(C->node_arena()->contains(n), "dead node");
    for (uint j = 0; j < n->req(); j++) {
      Node* in = n->in(j);
      if (in != nullptr) {
        worklist.push(in);
      }
    }
    for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
      worklist.push(n->fast_out(j));
    }
  }
}
#endif


//---------------------------match---------------------------------------------
void Matcher::match( ) {
  if( MaxLabelRootDepth < 100 ) { // Too small?
    assert(false, "invalid MaxLabelRootDepth, increase it to 100 minimum");
    MaxLabelRootDepth = 100;
  }
  // One-time initialization of some register masks.
  init_spill_mask( C->root()->in(1) );
  if (C->failing()) {
    return;
  }
  _return_addr_mask = return_addr();
#ifdef _LP64
  // Pointers take 2 slots in 64-bit land
  _return_addr_mask.Insert(OptoReg::add(return_addr(),1));
#endif

  // Map a Java-signature return type into return register-value
  // machine registers for 0, 1 and 2 returned values.
  const TypeTuple *range = C->tf()->range();
  if( range->cnt() > TypeFunc::Parms ) { // If not a void function
    // Get ideal-register return type
    uint ireg = range->field_at(TypeFunc::Parms)->ideal_reg();
    // Get machine return register
    uint sop = C->start()->Opcode();
    OptoRegPair regs = return_value(ireg);

    // And mask for same
    _return_value_mask = RegMask(regs.first());
    if( OptoReg::is_valid(regs.second()) )
      _return_value_mask.Insert(regs.second());
  }

  // ---------------
  // Frame Layout

  // Need the method signature to determine the incoming argument types,
  // because the types determine which registers the incoming arguments are
  // in, and this affects the matched code.
  const TypeTuple *domain = C->tf()->domain();
  uint             argcnt = domain->cnt() - TypeFunc::Parms;
  BasicType *sig_bt        = NEW_RESOURCE_ARRAY( BasicType, argcnt );
  VMRegPair *vm_parm_regs  = NEW_RESOURCE_ARRAY( VMRegPair, argcnt );
  _parm_regs               = NEW_RESOURCE_ARRAY( OptoRegPair, argcnt );
  _calling_convention_mask = NEW_RESOURCE_ARRAY( RegMask, argcnt );
  uint i;
  for( i = 0; i<argcnt; i++ ) {
    sig_bt[i] = domain->field_at(i+TypeFunc::Parms)->basic_type();
  }

  // Pass array of ideal registers and length to USER code (from the AD file)
  // that will convert this to an array of register numbers.
  const StartNode *start = C->start();
  start->calling_convention( sig_bt, vm_parm_regs, argcnt );
#ifdef ASSERT
  // Sanity check users' calling convention.  Real handy while trying to
  // get the initial port correct.
  { for (uint i = 0; i<argcnt; i++) {
      if( !vm_parm_regs[i].first()->is_valid() && !vm_parm_regs[i].second()->is_valid() ) {
        assert(domain->field_at(i+TypeFunc::Parms)==Type::HALF, "only allowed on halve" );
        _parm_regs[i].set_bad();
        continue;
      }
      VMReg parm_reg = vm_parm_regs[i].first();
      assert(parm_reg->is_valid(), "invalid arg?");
      if (parm_reg->is_reg()) {
        OptoReg::Name opto_parm_reg = OptoReg::as_OptoReg(parm_reg);
        assert(can_be_java_arg(opto_parm_reg) ||
               C->stub_function() == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C) ||
               opto_parm_reg == inline_cache_reg(),
               "parameters in register must be preserved by runtime stubs");
      }
      for (uint j = 0; j < i; j++) {
        assert(parm_reg != vm_parm_regs[j].first(),
               "calling conv. must produce distinct regs");
      }
    }
  }
#endif

  // Do some initial frame layout.

  // Compute the old incoming SP (may be called FP) as
  //   OptoReg::stack0() + locks + in_preserve_stack_slots + pad2.
  _old_SP = C->compute_old_SP();
  assert( is_even(_old_SP), "must be even" );

  // Compute highest incoming stack argument as
  //   _old_SP + out_preserve_stack_slots + incoming argument size.
  _in_arg_limit = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
  assert( is_even(_in_arg_limit), "out_preserve must be even" );
  for( i = 0; i < argcnt; i++ ) {
    // Permit args to have no register
    _calling_convention_mask[i].Clear();
    if( !vm_parm_regs[i].first()->is_valid() && !vm_parm_regs[i].second()->is_valid() ) {
      _parm_regs[i].set_bad();
      continue;
    }
    // calling_convention returns stack arguments as a count of
    // slots beyond OptoReg::stack0()/VMRegImpl::stack0.  We need to convert this to
    // the allocators point of view, taking into account all the
    // preserve area, locks & pad2.

    OptoReg::Name reg1 = warp_incoming_stk_arg(vm_parm_regs[i].first());
    if (C->failing()) {
      return;
    }
    if( OptoReg::is_valid(reg1))
      _calling_convention_mask[i].Insert(reg1);

    OptoReg::Name reg2 = warp_incoming_stk_arg(vm_parm_regs[i].second());
    if (C->failing()) {
      return;
    }
    if( OptoReg::is_valid(reg2))
      _calling_convention_mask[i].Insert(reg2);

    // Saved biased stack-slot register number
    _parm_regs[i].set_pair(reg2, reg1);
  }

  // Finally, make sure the incoming arguments take up an even number of
  // words, in case the arguments or locals need to contain doubleword stack
  // slots.  The rest of the system assumes that stack slot pairs (in
  // particular, in the spill area) which look aligned will in fact be
  // aligned relative to the stack pointer in the target machine.  Double
  // stack slots will always be allocated aligned.
  _new_SP = OptoReg::Name(align_up(_in_arg_limit, (int)RegMask::SlotsPerLong));

  // Compute highest outgoing stack argument as
  //   _new_SP + out_preserve_stack_slots + max(outgoing argument size).
  _out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
  assert( is_even(_out_arg_limit), "out_preserve must be even" );

  if (!RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1))) {
    // the compiler cannot represent this method's calling sequence
    // Bailout. We do not have space to represent all arguments.
    C->record_method_not_compilable("must be able to represent all call arguments in reg mask");
  }

  if (C->failing())  return;  // bailed out on incoming arg failure

  // ---------------
  // Collect roots of matcher trees.  Every node for which
  // _shared[_idx] is cleared is guaranteed to not be shared, and thus
  // can be a valid interior of some tree.
  find_shared( C->root() );
  find_shared( C->top() );

  C->print_method(PHASE_BEFORE_MATCHING, 1);

  // Create new ideal node ConP #null even if it does exist in old space
  // to avoid false sharing if the corresponding mach node is not used.
  // The corresponding mach node is only used in rare cases for derived
  // pointers.
  Node* new_ideal_null = ConNode::make(TypePtr::NULL_PTR);

  // Swap out to old-space; emptying new-space
  Arena* old = C->swap_old_and_new();

  // Save debug and profile information for nodes in old space:
  _old_node_note_array = C->node_note_array();
  if (_old_node_note_array != nullptr) {
    C->set_node_note_array(new(C->comp_arena()) GrowableArray<Node_Notes*>
                           (C->comp_arena(), _old_node_note_array->length(),
                            0, nullptr));
  }

  // Pre-size the new_node table to avoid the need for range checks.
  grow_new_node_array(C->unique());

  // Reset node counter so MachNodes start with _idx at 0
  int live_nodes = C->live_nodes();
  C->set_unique(0);
  C->reset_dead_node_list();

  // Recursively match trees from old space into new space.
  // Correct leaves of new-space Nodes; they point to old-space.
  _visited.clear();
  Node* const n = xform(C->top(), live_nodes);
  if (C->failing()) return;
  C->set_cached_top_node(n);
  if (!C->failing()) {
    Node* xroot =        xform( C->root(), 1 );
    if (C->failing()) return;
    if (xroot == nullptr) {
      Matcher::soft_match_failure();  // recursive matching process failed
      assert(false, "instruction match failed");
      C->record_method_not_compilable("instruction match failed");
    } else {
      // During matching shared constants were attached to C->root()
      // because xroot wasn't available yet, so transfer the uses to
      // the xroot.
      for( DUIterator_Fast jmax, j = C->root()->fast_outs(jmax); j < jmax; j++ ) {
        Node* n = C->root()->fast_out(j);
        if (C->node_arena()->contains(n)) {
          assert(n->in(0) == C->root(), "should be control user");
          n->set_req(0, xroot);
          --j;
          --jmax;
        }
      }

      // Generate new mach node for ConP #null
      assert(new_ideal_null != nullptr, "sanity");
      _mach_null = match_tree(new_ideal_null);
      // Don't set control, it will confuse GCM since there are no uses.
      // The control will be set when this node is used first time
      // in find_base_for_derived().
      assert(_mach_null != nullptr || C->failure_is_artificial(), ""); // bailouts are handled below.

      C->set_root(xroot->is_Root() ? xroot->as_Root() : nullptr);

#ifdef ASSERT
      verify_new_nodes_only(xroot);
#endif
    }
  }
  if (C->top() == nullptr || C->root() == nullptr) {
    // New graph lost. This is due to a compilation failure we encountered earlier.
    stringStream ss;
    if (C->failure_reason() != nullptr) {
      ss.print("graph lost: %s", C->failure_reason());
    } else {
      assert(C->failure_reason() != nullptr, "graph lost: reason unknown");
      ss.print("graph lost: reason unknown");
    }
    C->record_method_not_compilable(ss.as_string() DEBUG_ONLY(COMMA true));
  }
  if (C->failing()) {
    // delete old;
    old->destruct_contents();
    return;
  }
  assert( C->top(), "" );
  assert( C->root(), "" );
  validate_null_checks();

  // Now smoke old-space
  NOT_DEBUG( old->destruct_contents() );

  // ------------------------
  // Set up save-on-entry registers.
  Fixup_Save_On_Entry( );

  { // Cleanup mach IR after selection phase is over.
    Compile::TracePhase tp(_t_postselect_cleanup);
    do_postselect_cleanup();
    if (C->failing())  return;
    assert(verify_after_postselect_cleanup(), "");
  }
}

//------------------------------Fixup_Save_On_Entry----------------------------
// The stated purpose of this routine is to take care of save-on-entry
// registers.  However, the overall goal of the Match phase is to convert into
// machine-specific instructions which have RegMasks to guide allocation.
// So what this procedure really does is put a valid RegMask on each input
// to the machine-specific variations of all Return, TailCall and Halt
// instructions.  It also adds edgs to define the save-on-entry values (and of
// course gives them a mask).

static RegMask *init_input_masks( uint size, RegMask &ret_adr, RegMask &fp ) {
  RegMask *rms = NEW_RESOURCE_ARRAY( RegMask, size );
  // Do all the pre-defined register masks
  rms[TypeFunc::Control  ] = RegMask::Empty;
  rms[TypeFunc::I_O      ] = RegMask::Empty;
  rms[TypeFunc::Memory   ] = RegMask::Empty;
  rms[TypeFunc::ReturnAdr] = ret_adr;
  rms[TypeFunc::FramePtr ] = fp;
  return rms;
}

int Matcher::scalable_predicate_reg_slots() {
  assert(Matcher::has_predicated_vectors() && Matcher::supports_scalable_vector(),
        "scalable predicate vector should be supported");
  int vector_reg_bit_size = Matcher::scalable_vector_reg_size(T_BYTE) << LogBitsPerByte;
  // We assume each predicate register is one-eighth of the size of
  // scalable vector register, one mask bit per vector byte.
  int predicate_reg_bit_size = vector_reg_bit_size >> 3;
  // Compute number of slots which is required when scalable predicate
  // register is spilled. E.g. if scalable vector register is 640 bits,
  // predicate register is 80 bits, which is 2.5 * slots.
  // We will round up the slot number to power of 2, which is required
  // by find_first_set().
  int slots = predicate_reg_bit_size & (BitsPerInt - 1)
              ? (predicate_reg_bit_size >> LogBitsPerInt) + 1
              : predicate_reg_bit_size >> LogBitsPerInt;
  return round_up_power_of_2(slots);
}

#define NOF_STACK_MASKS (3*13)

// Create the initial stack mask used by values spilling to the stack.
// Disallow any debug info in outgoing argument areas by setting the
// initial mask accordingly.
void Matcher::init_first_stack_mask() {

  // Allocate storage for spill masks as masks for the appropriate load type.
  RegMask *rms = (RegMask*)C->comp_arena()->AmallocWords(sizeof(RegMask) * NOF_STACK_MASKS);

  // Initialize empty placeholder masks into the newly allocated arena
  for (int i = 0; i < NOF_STACK_MASKS; i++) {
    new (rms + i) RegMask();
  }

  idealreg2spillmask  [Op_RegN] = &rms[0];
  idealreg2spillmask  [Op_RegI] = &rms[1];
  idealreg2spillmask  [Op_RegL] = &rms[2];
  idealreg2spillmask  [Op_RegF] = &rms[3];
  idealreg2spillmask  [Op_RegD] = &rms[4];
  idealreg2spillmask  [Op_RegP] = &rms[5];

  idealreg2debugmask  [Op_RegN] = &rms[6];
  idealreg2debugmask  [Op_RegI] = &rms[7];
  idealreg2debugmask  [Op_RegL] = &rms[8];
  idealreg2debugmask  [Op_RegF] = &rms[9];
  idealreg2debugmask  [Op_RegD] = &rms[10];
  idealreg2debugmask  [Op_RegP] = &rms[11];

  idealreg2mhdebugmask[Op_RegN] = &rms[12];
  idealreg2mhdebugmask[Op_RegI] = &rms[13];
  idealreg2mhdebugmask[Op_RegL] = &rms[14];
  idealreg2mhdebugmask[Op_RegF] = &rms[15];
  idealreg2mhdebugmask[Op_RegD] = &rms[16];
  idealreg2mhdebugmask[Op_RegP] = &rms[17];

  idealreg2spillmask  [Op_VecA] = &rms[18];
  idealreg2spillmask  [Op_VecS] = &rms[19];
  idealreg2spillmask  [Op_VecD] = &rms[20];
  idealreg2spillmask  [Op_VecX] = &rms[21];
  idealreg2spillmask  [Op_VecY] = &rms[22];
  idealreg2spillmask  [Op_VecZ] = &rms[23];

  idealreg2debugmask  [Op_VecA] = &rms[24];
  idealreg2debugmask  [Op_VecS] = &rms[25];
  idealreg2debugmask  [Op_VecD] = &rms[26];
  idealreg2debugmask  [Op_VecX] = &rms[27];
  idealreg2debugmask  [Op_VecY] = &rms[28];
  idealreg2debugmask  [Op_VecZ] = &rms[29];

  idealreg2mhdebugmask[Op_VecA] = &rms[30];
  idealreg2mhdebugmask[Op_VecS] = &rms[31];
  idealreg2mhdebugmask[Op_VecD] = &rms[32];
  idealreg2mhdebugmask[Op_VecX] = &rms[33];
  idealreg2mhdebugmask[Op_VecY] = &rms[34];
  idealreg2mhdebugmask[Op_VecZ] = &rms[35];

  idealreg2spillmask  [Op_RegVectMask] = &rms[36];
  idealreg2debugmask  [Op_RegVectMask] = &rms[37];
  idealreg2mhdebugmask[Op_RegVectMask] = &rms[38];

  OptoReg::Name i;

  // At first, start with the empty mask
  C->FIRST_STACK_mask().Clear();

  // Add in the incoming argument area
  OptoReg::Name init_in = OptoReg::add(_old_SP, C->out_preserve_stack_slots());
  for (i = init_in; i < _in_arg_limit; i = OptoReg::add(i,1)) {
    C->FIRST_STACK_mask().Insert(i);
  }
  // Add in all bits past the outgoing argument area
  guarantee(RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1)),
            "must be able to represent all call arguments in reg mask");
  OptoReg::Name init = _out_arg_limit;
  for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1)) {
    C->FIRST_STACK_mask().Insert(i);
  }
  // Finally, set the "infinite stack" bit.
  C->FIRST_STACK_mask().set_AllStack();

  // Make spill masks.  Registers for their class, plus FIRST_STACK_mask.
  RegMask aligned_stack_mask = C->FIRST_STACK_mask();
  // Keep spill masks aligned.
  aligned_stack_mask.clear_to_pairs();
  assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
  RegMask scalable_stack_mask = aligned_stack_mask;

  *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
#ifdef _LP64
  *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN];
   idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask());
   idealreg2spillmask[Op_RegP]->OR(aligned_stack_mask);
#else
   idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
#endif
  *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI];
   idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask());
  *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL];
   idealreg2spillmask[Op_RegL]->OR(aligned_stack_mask);
  *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF];
   idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask());
  *idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD];
   idealreg2spillmask[Op_RegD]->OR(aligned_stack_mask);

  if (Matcher::has_predicated_vectors()) {
    *idealreg2spillmask[Op_RegVectMask] = *idealreg2regmask[Op_RegVectMask];
     idealreg2spillmask[Op_RegVectMask]->OR(aligned_stack_mask);
  } else {
    *idealreg2spillmask[Op_RegVectMask] = RegMask::Empty;
  }

  if (Matcher::vector_size_supported(T_BYTE,4)) {
    *idealreg2spillmask[Op_VecS] = *idealreg2regmask[Op_VecS];
     idealreg2spillmask[Op_VecS]->OR(C->FIRST_STACK_mask());
  } else {
    *idealreg2spillmask[Op_VecS] = RegMask::Empty;
  }

  if (Matcher::vector_size_supported(T_FLOAT,2)) {
    // For VecD we need dual alignment and 8 bytes (2 slots) for spills.
    // RA guarantees such alignment since it is needed for Double and Long values.
    *idealreg2spillmask[Op_VecD] = *idealreg2regmask[Op_VecD];
     idealreg2spillmask[Op_VecD]->OR(aligned_stack_mask);
  } else {
    *idealreg2spillmask[Op_VecD] = RegMask::Empty;
  }

  if (Matcher::vector_size_supported(T_FLOAT,4)) {
    // For VecX we need quadro alignment and 16 bytes (4 slots) for spills.
    //
    // RA can use input arguments stack slots for spills but until RA
    // we don't know frame size and offset of input arg stack slots.
    //
    // Exclude last input arg stack slots to avoid spilling vectors there
    // otherwise vector spills could stomp over stack slots in caller frame.
    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
    for (int k = 1; (in >= init_in) && (k < RegMask::SlotsPerVecX); k++) {
      aligned_stack_mask.Remove(in);
      in = OptoReg::add(in, -1);
    }
     aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecX);
     assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
    *idealreg2spillmask[Op_VecX] = *idealreg2regmask[Op_VecX];
     idealreg2spillmask[Op_VecX]->OR(aligned_stack_mask);
  } else {
    *idealreg2spillmask[Op_VecX] = RegMask::Empty;
  }

  if (Matcher::vector_size_supported(T_FLOAT,8)) {
    // For VecY we need octo alignment and 32 bytes (8 slots) for spills.
    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
    for (int k = 1; (in >= init_in) && (k < RegMask::SlotsPerVecY); k++) {
      aligned_stack_mask.Remove(in);
      in = OptoReg::add(in, -1);
    }
     aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecY);
     assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
    *idealreg2spillmask[Op_VecY] = *idealreg2regmask[Op_VecY];
     idealreg2spillmask[Op_VecY]->OR(aligned_stack_mask);
  } else {
    *idealreg2spillmask[Op_VecY] = RegMask::Empty;
  }

  if (Matcher::vector_size_supported(T_FLOAT,16)) {
    // For VecZ we need enough alignment and 64 bytes (16 slots) for spills.
    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
    for (int k = 1; (in >= init_in) && (k < RegMask::SlotsPerVecZ); k++) {
      aligned_stack_mask.Remove(in);
      in = OptoReg::add(in, -1);
    }
     aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecZ);
     assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
    *idealreg2spillmask[Op_VecZ] = *idealreg2regmask[Op_VecZ];
     idealreg2spillmask[Op_VecZ]->OR(aligned_stack_mask);
  } else {
    *idealreg2spillmask[Op_VecZ] = RegMask::Empty;
  }

  if (Matcher::supports_scalable_vector()) {
    int k = 1;
    OptoReg::Name in = OptoReg::add(_in_arg_limit, -1);
    if (Matcher::has_predicated_vectors()) {
      // Exclude last input arg stack slots to avoid spilling vector register there,
      // otherwise RegVectMask spills could stomp over stack slots in caller frame.
      for (; (in >= init_in) && (k < scalable_predicate_reg_slots()); k++) {
        scalable_stack_mask.Remove(in);
        in = OptoReg::add(in, -1);
      }

      // For RegVectMask
      scalable_stack_mask.clear_to_sets(scalable_predicate_reg_slots());
      assert(scalable_stack_mask.is_AllStack(), "should be infinite stack");
      *idealreg2spillmask[Op_RegVectMask] = *idealreg2regmask[Op_RegVectMask];
      idealreg2spillmask[Op_RegVectMask]->OR(scalable_stack_mask);
    }

    // Exclude last input arg stack slots to avoid spilling vector register there,
    // otherwise vector spills could stomp over stack slots in caller frame.
    for (; (in >= init_in) && (k < scalable_vector_reg_size(T_FLOAT)); k++) {
      scalable_stack_mask.Remove(in);
      in = OptoReg::add(in, -1);
    }

    // For VecA
     scalable_stack_mask.clear_to_sets(RegMask::SlotsPerVecA);
     assert(scalable_stack_mask.is_AllStack(), "should be infinite stack");
    *idealreg2spillmask[Op_VecA] = *idealreg2regmask[Op_VecA];
     idealreg2spillmask[Op_VecA]->OR(scalable_stack_mask);
  } else {
    *idealreg2spillmask[Op_VecA] = RegMask::Empty;
  }

  if (UseFPUForSpilling) {
    // This mask logic assumes that the spill operations are
    // symmetric and that the registers involved are the same size.
    // On sparc for instance we may have to use 64 bit moves will
    // kill 2 registers when used with F0-F31.
    idealreg2spillmask[Op_RegI]->OR(*idealreg2regmask[Op_RegF]);
    idealreg2spillmask[Op_RegF]->OR(*idealreg2regmask[Op_RegI]);
#ifdef _LP64
    idealreg2spillmask[Op_RegN]->OR(*idealreg2regmask[Op_RegF]);
    idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
    idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
    idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegD]);
#else
    idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegF]);
#ifdef ARM
    // ARM has support for moving 64bit values between a pair of
    // integer registers and a double register
    idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
    idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
#endif
#endif
  }

  // Make up debug masks.  Any spill slot plus callee-save (SOE) registers.
  // Caller-save (SOC, AS) registers are assumed to be trashable by the various
  // inline-cache fixup routines.
  *idealreg2debugmask  [Op_RegN] = *idealreg2spillmask[Op_RegN];
  *idealreg2debugmask  [Op_RegI] = *idealreg2spillmask[Op_RegI];
  *idealreg2debugmask  [Op_RegL] = *idealreg2spillmask[Op_RegL];
  *idealreg2debugmask  [Op_RegF] = *idealreg2spillmask[Op_RegF];
  *idealreg2debugmask  [Op_RegD] = *idealreg2spillmask[Op_RegD];
  *idealreg2debugmask  [Op_RegP] = *idealreg2spillmask[Op_RegP];
  *idealreg2debugmask  [Op_RegVectMask] = *idealreg2spillmask[Op_RegVectMask];

  *idealreg2debugmask  [Op_VecA] = *idealreg2spillmask[Op_VecA];
  *idealreg2debugmask  [Op_VecS] = *idealreg2spillmask[Op_VecS];
  *idealreg2debugmask  [Op_VecD] = *idealreg2spillmask[Op_VecD];
  *idealreg2debugmask  [Op_VecX] = *idealreg2spillmask[Op_VecX];
  *idealreg2debugmask  [Op_VecY] = *idealreg2spillmask[Op_VecY];
  *idealreg2debugmask  [Op_VecZ] = *idealreg2spillmask[Op_VecZ];

  *idealreg2mhdebugmask[Op_RegN] = *idealreg2spillmask[Op_RegN];
  *idealreg2mhdebugmask[Op_RegI] = *idealreg2spillmask[Op_RegI];
  *idealreg2mhdebugmask[Op_RegL] = *idealreg2spillmask[Op_RegL];
  *idealreg2mhdebugmask[Op_RegF] = *idealreg2spillmask[Op_RegF];
  *idealreg2mhdebugmask[Op_RegD] = *idealreg2spillmask[Op_RegD];
  *idealreg2mhdebugmask[Op_RegP] = *idealreg2spillmask[Op_RegP];
  *idealreg2mhdebugmask[Op_RegVectMask] = *idealreg2spillmask[Op_RegVectMask];

  *idealreg2mhdebugmask[Op_VecA] = *idealreg2spillmask[Op_VecA];
  *idealreg2mhdebugmask[Op_VecS] = *idealreg2spillmask[Op_VecS];
  *idealreg2mhdebugmask[Op_VecD] = *idealreg2spillmask[Op_VecD];
  *idealreg2mhdebugmask[Op_VecX] = *idealreg2spillmask[Op_VecX];
  *idealreg2mhdebugmask[Op_VecY] = *idealreg2spillmask[Op_VecY];
  *idealreg2mhdebugmask[Op_VecZ] = *idealreg2spillmask[Op_VecZ];

  // Prevent stub compilations from attempting to reference
  // callee-saved (SOE) registers from debug info
  bool exclude_soe = !Compile::current()->is_method_compilation();
  RegMask* caller_save_mask = exclude_soe ? &caller_save_regmask_exclude_soe : &caller_save_regmask;
  RegMask* mh_caller_save_mask = exclude_soe ? &mh_caller_save_regmask_exclude_soe : &mh_caller_save_regmask;

  idealreg2debugmask[Op_RegN]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegI]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegL]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegF]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegD]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegP]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_RegVectMask]->SUBTRACT(*caller_save_mask);

  idealreg2debugmask[Op_VecA]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_VecS]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_VecD]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_VecX]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_VecY]->SUBTRACT(*caller_save_mask);
  idealreg2debugmask[Op_VecZ]->SUBTRACT(*caller_save_mask);

  idealreg2mhdebugmask[Op_RegN]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegI]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegL]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegF]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegD]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegP]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_RegVectMask]->SUBTRACT(*mh_caller_save_mask);

  idealreg2mhdebugmask[Op_VecA]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_VecS]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_VecD]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_VecX]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_VecY]->SUBTRACT(*mh_caller_save_mask);
  idealreg2mhdebugmask[Op_VecZ]->SUBTRACT(*mh_caller_save_mask);
}

//---------------------------is_save_on_entry----------------------------------
bool Matcher::is_save_on_entry(int reg) {
  return
    _register_save_policy[reg] == 'E' ||
    _register_save_policy[reg] == 'A'; // Save-on-entry register?
}

//---------------------------Fixup_Save_On_Entry-------------------------------
void Matcher::Fixup_Save_On_Entry( ) {
  init_first_stack_mask();

  Node *root = C->root();       // Short name for root
  // Count number of save-on-entry registers.
  uint soe_cnt = number_of_saved_registers();
  uint i;

  // Find the procedure Start Node
  StartNode *start = C->start();
  assert( start, "Expect a start node" );

  // Input RegMask array shared by all Returns.
  // The type for doubles and longs has a count of 2, but
  // there is only 1 returned value
  uint ret_edge_cnt = TypeFunc::Parms + ((C->tf()->range()->cnt() == TypeFunc::Parms) ? 0 : 1);
  RegMask *ret_rms  = init_input_masks( ret_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
  // Returns have 0 or 1 returned values depending on call signature.
  // Return register is specified by return_value in the AD file.
  if (ret_edge_cnt > TypeFunc::Parms)
    ret_rms[TypeFunc::Parms+0] = _return_value_mask;

  // Input RegMask array shared by all ForwardExceptions
  uint forw_exc_edge_cnt = TypeFunc::Parms;
  RegMask* forw_exc_rms  = init_input_masks( forw_exc_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );

  // Input RegMask array shared by all Rethrows.
  uint reth_edge_cnt = TypeFunc::Parms+1;
  RegMask *reth_rms  = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
  // Rethrow takes exception oop only, but in the argument 0 slot.
  OptoReg::Name reg = find_receiver();
  if (reg >= 0) {
    reth_rms[TypeFunc::Parms] = mreg2regmask[reg];
#ifdef _LP64
    // Need two slots for ptrs in 64-bit land
    reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(reg), 1));
#endif
  }

  // Input RegMask array shared by all TailCalls
  uint tail_call_edge_cnt = TypeFunc::Parms+2;
  RegMask *tail_call_rms = init_input_masks( tail_call_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );

  // Input RegMask array shared by all TailJumps
  uint tail_jump_edge_cnt = TypeFunc::Parms+2;
  RegMask *tail_jump_rms = init_input_masks( tail_jump_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );

  // TailCalls have 2 returned values (target & moop), whose masks come
  // from the usual MachNode/MachOper mechanism.  Find a sample
  // TailCall to extract these masks and put the correct masks into
  // the tail_call_rms array.
  for( i=1; i < root->req(); i++ ) {
    MachReturnNode *m = root->in(i)->as_MachReturn();
    if( m->ideal_Opcode() == Op_TailCall ) {
      tail_call_rms[TypeFunc::Parms+0] = m->MachNode::in_RegMask(TypeFunc::Parms+0);
      tail_call_rms[TypeFunc::Parms+1] = m->MachNode::in_RegMask(TypeFunc::Parms+1);
      break;
    }
  }

  // TailJumps have 2 returned values (target & ex_oop), whose masks come
  // from the usual MachNode/MachOper mechanism.  Find a sample
  // TailJump to extract these masks and put the correct masks into
  // the tail_jump_rms array.
  for( i=1; i < root->req(); i++ ) {
    MachReturnNode *m = root->in(i)->as_MachReturn();
    if( m->ideal_Opcode() == Op_TailJump ) {
      tail_jump_rms[TypeFunc::Parms+0] = m->MachNode::in_RegMask(TypeFunc::Parms+0);
      tail_jump_rms[TypeFunc::Parms+1] = m->MachNode::in_RegMask(TypeFunc::Parms+1);
      break;
    }
  }

  // Input RegMask array shared by all Halts
  uint halt_edge_cnt = TypeFunc::Parms;
  RegMask *halt_rms = init_input_masks( halt_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );

  // Capture the return input masks into each exit flavor
  for( i=1; i < root->req(); i++ ) {
    MachReturnNode *exit = root->in(i)->as_MachReturn();
    switch( exit->ideal_Opcode() ) {
      case Op_Return   : exit->_in_rms = ret_rms;  break;
      case Op_Rethrow  : exit->_in_rms = reth_rms; break;
      case Op_TailCall : exit->_in_rms = tail_call_rms; break;
      case Op_TailJump : exit->_in_rms = tail_jump_rms; break;
      case Op_ForwardException: exit->_in_rms = forw_exc_rms; break;
      case Op_Halt     : exit->_in_rms = halt_rms; break;
      default          : ShouldNotReachHere();
    }
  }

  // Next unused projection number from Start.
  int proj_cnt = C->tf()->domain()->cnt();

  // Do all the save-on-entry registers.  Make projections from Start for
  // them, and give them a use at the exit points.  To the allocator, they
  // look like incoming register arguments.
  for( i = 0; i < _last_Mach_Reg; i++ ) {
    if( is_save_on_entry(i) ) {

      // Add the save-on-entry to the mask array
      ret_rms      [      ret_edge_cnt] = mreg2regmask[i];
      reth_rms     [     reth_edge_cnt] = mreg2regmask[i];
      tail_call_rms[tail_call_edge_cnt] = mreg2regmask[i];
      tail_jump_rms[tail_jump_edge_cnt] = mreg2regmask[i];
      forw_exc_rms [ forw_exc_edge_cnt] = mreg2regmask[i];
      // Halts need the SOE registers, but only in the stack as debug info.
      // A just-prior uncommon-trap or deoptimization will use the SOE regs.
      halt_rms     [     halt_edge_cnt] = *idealreg2spillmask[_register_save_type[i]];

      Node *mproj;

      // Is this a RegF low half of a RegD?  Double up 2 adjacent RegF's
      // into a single RegD.
      if( (i&1) == 0 &&
          _register_save_type[i  ] == Op_RegF &&
          _register_save_type[i+1] == Op_RegF &&
          is_save_on_entry(i+1) ) {
        // Add other bit for double
        ret_rms      [      ret_edge_cnt].Insert(OptoReg::Name(i+1));
        reth_rms     [     reth_edge_cnt].Insert(OptoReg::Name(i+1));
        tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
        tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
        forw_exc_rms [ forw_exc_edge_cnt].Insert(OptoReg::Name(i+1));
        halt_rms     [     halt_edge_cnt].Insert(OptoReg::Name(i+1));
        mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD );
        proj_cnt += 2;          // Skip 2 for doubles
      }
      else if( (i&1) == 1 &&    // Else check for high half of double
               _register_save_type[i-1] == Op_RegF &&
               _register_save_type[i  ] == Op_RegF &&
               is_save_on_entry(i-1) ) {
        ret_rms      [      ret_edge_cnt] = RegMask::Empty;
        reth_rms     [     reth_edge_cnt] = RegMask::Empty;
        tail_call_rms[tail_call_edge_cnt] = RegMask::Empty;
        tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty;
        forw_exc_rms [ forw_exc_edge_cnt] = RegMask::Empty;
        halt_rms     [     halt_edge_cnt] = RegMask::Empty;
        mproj = C->top();
      }
      // Is this a RegI low half of a RegL?  Double up 2 adjacent RegI's
      // into a single RegL.
      else if( (i&1) == 0 &&
          _register_save_type[i  ] == Op_RegI &&
          _register_save_type[i+1] == Op_RegI &&
        is_save_on_entry(i+1) ) {
        // Add other bit for long
        ret_rms      [      ret_edge_cnt].Insert(OptoReg::Name(i+1));
        reth_rms     [     reth_edge_cnt].Insert(OptoReg::Name(i+1));
        tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
        tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
        forw_exc_rms [ forw_exc_edge_cnt].Insert(OptoReg::Name(i+1));
        halt_rms     [     halt_edge_cnt].Insert(OptoReg::Name(i+1));
        mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL );
        proj_cnt += 2;          // Skip 2 for longs
      }
      else if( (i&1) == 1 &&    // Else check for high half of long
               _register_save_type[i-1] == Op_RegI &&
               _register_save_type[i  ] == Op_RegI &&
               is_save_on_entry(i-1) ) {
        ret_rms      [      ret_edge_cnt] = RegMask::Empty;
        reth_rms     [     reth_edge_cnt] = RegMask::Empty;
        tail_call_rms[tail_call_edge_cnt] = RegMask::Empty;
        tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty;
        forw_exc_rms [ forw_exc_edge_cnt] = RegMask::Empty;
        halt_rms     [     halt_edge_cnt] = RegMask::Empty;
        mproj = C->top();
      } else {
        // Make a projection for it off the Start
        mproj = new MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] );
      }

      ret_edge_cnt ++;
      reth_edge_cnt ++;
      tail_call_edge_cnt ++;
      tail_jump_edge_cnt ++;
      forw_exc_edge_cnt++;
      halt_edge_cnt ++;

      // Add a use of the SOE register to all exit paths
      for (uint j=1; j < root->req(); j++) {
        root->in(j)->add_req(mproj);
      }
    } // End of if a save-on-entry register
  } // End of for all machine registers
}

//------------------------------init_spill_mask--------------------------------
void Matcher::init_spill_mask( Node *ret ) {
  if( idealreg2regmask[Op_RegI] ) return; // One time only init

  OptoReg::c_frame_pointer = c_frame_pointer();
  c_frame_ptr_mask = c_frame_pointer();
#ifdef _LP64
  // pointers are twice as big
  c_frame_ptr_mask.Insert(OptoReg::add(c_frame_pointer(),1));
#endif

  // Start at OptoReg::stack0()
  STACK_ONLY_mask.Clear();
  OptoReg::Name init = OptoReg::stack2reg(0);
  // STACK_ONLY_mask is all stack bits
  OptoReg::Name i;
  for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
    STACK_ONLY_mask.Insert(i);
  // Also set the "infinite stack" bit.
  STACK_ONLY_mask.set_AllStack();

  for (i = OptoReg::Name(0); i < OptoReg::Name(_last_Mach_Reg); i = OptoReg::add(i, 1)) {
    // Copy the register names over into the shared world.
    // SharedInfo::regName[i] = regName[i];
    // Handy RegMasks per machine register
    mreg2regmask[i].Insert(i);

    // Set up regmasks used to exclude save-on-call (and always-save) registers from debug masks.
    if (_register_save_policy[i] == 'C' ||
        _register_save_policy[i] == 'A') {
      caller_save_regmask.Insert(i);
      mh_caller_save_regmask.Insert(i);
    }
    // Exclude save-on-entry registers from debug masks for stub compilations.
    if (_register_save_policy[i] == 'C' ||
        _register_save_policy[i] == 'A' ||
        _register_save_policy[i] == 'E') {
      caller_save_regmask_exclude_soe.Insert(i);
      mh_caller_save_regmask_exclude_soe.Insert(i);
    }
  }

  // Also exclude the register we use to save the SP for MethodHandle
  // invokes to from the corresponding MH debug masks
  const RegMask sp_save_mask = method_handle_invoke_SP_save_mask();
  mh_caller_save_regmask.OR(sp_save_mask);
  mh_caller_save_regmask_exclude_soe.OR(sp_save_mask);

  // Grab the Frame Pointer
  Node *fp  = ret->in(TypeFunc::FramePtr);
  // Share frame pointer while making spill ops
  set_shared(fp);

// Get the ADLC notion of the right regmask, for each basic type.
#ifdef _LP64
  idealreg2regmask[Op_RegN] = regmask_for_ideal_register(Op_RegN, ret);
#endif
  idealreg2regmask[Op_RegI] = regmask_for_ideal_register(Op_RegI, ret);
  idealreg2regmask[Op_RegP] = regmask_for_ideal_register(Op_RegP, ret);
  idealreg2regmask[Op_RegF] = regmask_for_ideal_register(Op_RegF, ret);
  idealreg2regmask[Op_RegD] = regmask_for_ideal_register(Op_RegD, ret);
  idealreg2regmask[Op_RegL] = regmask_for_ideal_register(Op_RegL, ret);
  idealreg2regmask[Op_VecA] = regmask_for_ideal_register(Op_VecA, ret);
  idealreg2regmask[Op_VecS] = regmask_for_ideal_register(Op_VecS, ret);
  idealreg2regmask[Op_VecD] = regmask_for_ideal_register(Op_VecD, ret);
  idealreg2regmask[Op_VecX] = regmask_for_ideal_register(Op_VecX, ret);
  idealreg2regmask[Op_VecY] = regmask_for_ideal_register(Op_VecY, ret);
  idealreg2regmask[Op_VecZ] = regmask_for_ideal_register(Op_VecZ, ret);
  idealreg2regmask[Op_RegVectMask] = regmask_for_ideal_register(Op_RegVectMask, ret);
}

#ifdef ASSERT
static void match_alias_type(Compile* C, Node* n, Node* m) {
  if (!VerifyAliases)  return;  // do not go looking for trouble by default
  const TypePtr* nat = n->adr_type();
  const TypePtr* mat = m->adr_type();
  int nidx = C->get_alias_index(nat);
  int midx = C->get_alias_index(mat);
  // Detune the assert for cases like (AndI 0xFF (LoadB p)).
  if (nidx == Compile::AliasIdxTop && midx >= Compile::AliasIdxRaw) {
    for (uint i = 1; i < n->req(); i++) {
      Node* n1 = n->in(i);
      const TypePtr* n1at = n1->adr_type();
      if (n1at != nullptr) {
        nat = n1at;
        nidx = C->get_alias_index(n1at);
      }
    }
  }
  // %%% Kludgery.  Instead, fix ideal adr_type methods for all these cases:
  if (nidx == Compile::AliasIdxTop && midx == Compile::AliasIdxRaw) {
    switch (n->Opcode()) {
    case Op_PrefetchAllocation:
      nidx = Compile::AliasIdxRaw;
      nat = TypeRawPtr::BOTTOM;
      break;
    }
  }
  if (nidx == Compile::AliasIdxRaw && midx == Compile::AliasIdxTop) {
    switch (n->Opcode()) {
    case Op_ClearArray:
      midx = Compile::AliasIdxRaw;
      mat = TypeRawPtr::BOTTOM;
      break;
    }
  }
  if (nidx == Compile::AliasIdxTop && midx == Compile::AliasIdxBot) {
    switch (n->Opcode()) {
    case Op_Return:
    case Op_Rethrow:
    case Op_Halt:
    case Op_TailCall:
    case Op_TailJump:
    case Op_ForwardException:
      nidx = Compile::AliasIdxBot;
      nat = TypePtr::BOTTOM;
      break;
    }
  }
  if (nidx == Compile::AliasIdxBot && midx == Compile::AliasIdxTop) {
    switch (n->Opcode()) {
    case Op_StrComp:
    case Op_StrEquals:
    case Op_StrIndexOf:
    case Op_StrIndexOfChar:
    case Op_AryEq:
    case Op_VectorizedHashCode:
    case Op_CountPositives:
    case Op_MemBarVolatile:
    case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
    case Op_StrInflatedCopy:
    case Op_StrCompressedCopy:
    case Op_OnSpinWait:
    case Op_EncodeISOArray:
      nidx = Compile::AliasIdxTop;
      nat = nullptr;
      break;
    }
  }
  if (nidx != midx) {
    if (PrintOpto || (PrintMiscellaneous && (WizardMode || Verbose))) {
      tty->print_cr("==== Matcher alias shift %d => %d", nidx, midx);
      n->dump();
      m->dump();
    }
    assert(C->subsume_loads() && C->must_alias(nat, midx),
           "must not lose alias info when matching");
  }
}
#endif

//------------------------------xform------------------------------------------
// Given a Node in old-space, Match him (Label/Reduce) to produce a machine
// Node in new-space.  Given a new-space Node, recursively walk his children.
Node *Matcher::transform( Node *n ) { ShouldNotCallThis(); return n; }
Node *Matcher::xform( Node *n, int max_stack ) {
  // Use one stack to keep both: child's node/state and parent's node/index
  MStack mstack(max_stack * 2 * 2); // usually: C->live_nodes() * 2 * 2
  mstack.push(n, Visit, nullptr, -1);  // set null as parent to indicate root
  while (mstack.is_nonempty()) {
    C->check_node_count(NodeLimitFudgeFactor, "too many nodes matching instructions");
    if (C->failing()) return nullptr;
    n = mstack.node();          // Leave node on stack
    Node_State nstate = mstack.state();
    if (nstate == Visit) {
      mstack.set_state(Post_Visit);
      Node *oldn = n;
      // Old-space or new-space check
      if (!C->node_arena()->contains(n)) {
        // Old space!
        Node* m;
        if (has_new_node(n)) {  // Not yet Label/Reduced
          m = new_node(n);
        } else {
          if (!is_dontcare(n)) { // Matcher can match this guy
            // Calls match special.  They match alone with no children.
            // Their children, the incoming arguments, match normally.
            m = n->is_SafePoint() ? match_sfpt(n->as_SafePoint()):match_tree(n);
            if (C->failing())  return nullptr;
            if (m == nullptr) { Matcher::soft_match_failure(); return nullptr; }
            if (n->is_MemBar()) {
              m->as_MachMemBar()->set_adr_type(n->adr_type());
            }
          } else {                  // Nothing the matcher cares about
            if (n->is_Proj() && n->in(0) != nullptr && n->in(0)->is_Multi()) {       // Projections?
              // Convert to machine-dependent projection
              m = n->in(0)->as_Multi()->match( n->as_Proj(), this );
              NOT_PRODUCT(record_new2old(m, n);)
              if (m->in(0) != nullptr) // m might be top
                collect_null_checks(m, n);
            } else {                // Else just a regular 'ol guy
              m = n->clone();       // So just clone into new-space
              NOT_PRODUCT(record_new2old(m, n);)
              // Def-Use edges will be added incrementally as Uses
              // of this node are matched.
              assert(m->outcnt() == 0, "no Uses of this clone yet");
            }
          }

          set_new_node(n, m);       // Map old to new
          if (_old_node_note_array != nullptr) {
            Node_Notes* nn = C->locate_node_notes(_old_node_note_array,
                                                  n->_idx);
            C->set_node_notes_at(m->_idx, nn);
          }
          DEBUG_ONLY(match_alias_type(C, n, m));
        }
        n = m;    // n is now a new-space node
        mstack.set_node(n);
      }

      // New space!
      if (_visited.test_set(n->_idx)) continue; // while(mstack.is_nonempty())

      int i;
      // Put precedence edges on stack first (match them last).
      for (i = oldn->req(); (uint)i < oldn->len(); i++) {
        Node *m = oldn->in(i);
        if (m == nullptr) break;
        // set -1 to call add_prec() instead of set_req() during Step1
        mstack.push(m, Visit, n, -1);
      }

      // Handle precedence edges for interior nodes
      for (i = n->len()-1; (uint)i >= n->req(); i--) {
        Node *m = n->in(i);
        if (m == nullptr || C->node_arena()->contains(m)) continue;
        n->rm_prec(i);
        // set -1 to call add_prec() instead of set_req() during Step1
        mstack.push(m, Visit, n, -1);
      }

      // For constant debug info, I'd rather have unmatched constants.
      int cnt = n->req();
      JVMState* jvms = n->jvms();
      int debug_cnt = jvms ? jvms->debug_start() : cnt;

      // Now do only debug info.  Clone constants rather than matching.
      // Constants are represented directly in the debug info without
      // the need for executable machine instructions.
      // Monitor boxes are also represented directly.
      for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
        Node *m = n->in(i);          // Get input
        int op = m->Opcode();
        assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
        if( op == Op_ConI || op == Op_ConP || op == Op_ConN || op == Op_ConNKlass ||
            op == Op_ConF || op == Op_ConD || op == Op_ConL
            // || op == Op_BoxLock  // %%%% enable this and remove (+++) in chaitin.cpp
            ) {
          m = m->clone();
          NOT_PRODUCT(record_new2old(m, n));
          mstack.push(m, Post_Visit, n, i); // Don't need to visit
          mstack.push(m->in(0), Visit, m, 0);
        } else {
          mstack.push(m, Visit, n, i);
        }
      }

      // And now walk his children, and convert his inputs to new-space.
      for( ; i >= 0; --i ) { // For all normal inputs do
        Node *m = n->in(i);  // Get input
        if(m != nullptr)
          mstack.push(m, Visit, n, i);
      }

    }
    else if (nstate == Post_Visit) {
      // Set xformed input
      Node *p = mstack.parent();
      if (p != nullptr) { // root doesn't have parent
        int i = (int)mstack.index();
        if (i >= 0)
          p->set_req(i, n); // required input
        else if (i == -1)
          p->add_prec(n);   // precedence input
        else
          ShouldNotReachHere();
      }
      mstack.pop(); // remove processed node from stack
    }
    else {
      ShouldNotReachHere();
    }
  } // while (mstack.is_nonempty())
  return n; // Return new-space Node
}

//------------------------------warp_outgoing_stk_arg------------------------
OptoReg::Name Matcher::warp_outgoing_stk_arg( VMReg reg, OptoReg::Name begin_out_arg_area, OptoReg::Name &out_arg_limit_per_call ) {
  // Convert outgoing argument location to a pre-biased stack offset
  if (reg->is_stack()) {
    OptoReg::Name warped = reg->reg2stack();
    // Adjust the stack slot offset to be the register number used
    // by the allocator.
    warped = OptoReg::add(begin_out_arg_area, warped);
    // Keep track of the largest numbered stack slot used for an arg.
    // Largest used slot per call-site indicates the amount of stack
    // that is killed by the call.
    if( warped >= out_arg_limit_per_call )
      out_arg_limit_per_call = OptoReg::add(warped,1);
    if (!RegMask::can_represent_arg(warped)) {
      // Bailout. For example not enough space on stack for all arguments. Happens for methods with too many arguments.
      C->record_method_not_compilable("unsupported calling sequence");
      return OptoReg::Bad;
    }
    return warped;
  }
  return OptoReg::as_OptoReg(reg);
}


//------------------------------match_sfpt-------------------------------------
// Helper function to match call instructions.  Calls match special.
// They match alone with no children.  Their children, the incoming
// arguments, match normally.
MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
  MachSafePointNode *msfpt = nullptr;
  MachCallNode      *mcall = nullptr;
  uint               cnt;
  // Split out case for SafePoint vs Call
  CallNode *call;
  const TypeTuple *domain;
  ciMethod*        method = nullptr;
  bool             is_method_handle_invoke = false;  // for special kill effects
  if( sfpt->is_Call() ) {
    call = sfpt->as_Call();
    domain = call->tf()->domain();
    cnt = domain->cnt();

    // Match just the call, nothing else
    MachNode *m = match_tree(call);
    if (C->failing())  return nullptr;
    if( m == nullptr ) { Matcher::soft_match_failure(); return nullptr; }

    // Copy data from the Ideal SafePoint to the machine version
    mcall = m->as_MachCall();

    mcall->set_tf(                  call->tf());
    mcall->set_entry_point(         call->entry_point());
    mcall->set_cnt(                 call->cnt());
    mcall->set_guaranteed_safepoint(call->guaranteed_safepoint());

    if( mcall->is_MachCallJava() ) {
      MachCallJavaNode *mcall_java  = mcall->as_MachCallJava();
      const CallJavaNode *call_java =  call->as_CallJava();
      assert(call_java->validate_symbolic_info(), "inconsistent info");
      method = call_java->method();
      mcall_java->_method = method;
      mcall_java->_optimized_virtual = call_java->is_optimized_virtual();
      is_method_handle_invoke = call_java->is_method_handle_invoke();
      mcall_java->_method_handle_invoke = is_method_handle_invoke;
      mcall_java->_override_symbolic_info = call_java->override_symbolic_info();
      mcall_java->_arg_escape = call_java->arg_escape();
      if (is_method_handle_invoke) {
        C->set_has_method_handle_invokes(true);
      }
      if( mcall_java->is_MachCallStaticJava() )
        mcall_java->as_MachCallStaticJava()->_name =
         call_java->as_CallStaticJava()->_name;
      if( mcall_java->is_MachCallDynamicJava() )
        mcall_java->as_MachCallDynamicJava()->_vtable_index =
         call_java->as_CallDynamicJava()->_vtable_index;
    }
    else if( mcall->is_MachCallRuntime() ) {
      MachCallRuntimeNode* mach_call_rt = mcall->as_MachCallRuntime();
      mach_call_rt->_name = call->as_CallRuntime()->_name;
      mach_call_rt->_leaf_no_fp = call->is_CallLeafNoFP();
    }
    msfpt = mcall;
  }
  // This is a non-call safepoint
  else {
    call = nullptr;
    domain = nullptr;
    MachNode *mn = match_tree(sfpt);
    if (C->failing())  return nullptr;
    msfpt = mn->as_MachSafePoint();
    cnt = TypeFunc::Parms;
  }
  msfpt->_has_ea_local_in_scope = sfpt->has_ea_local_in_scope();

  // Advertise the correct memory effects (for anti-dependence computation).
  msfpt->set_adr_type(sfpt->adr_type());

  // Allocate a private array of RegMasks.  These RegMasks are not shared.
  msfpt->_in_rms = NEW_RESOURCE_ARRAY( RegMask, cnt );
  // Empty them all.
  for (uint i = 0; i < cnt; i++) ::new (&(msfpt->_in_rms[i])) RegMask();

  // Do all the pre-defined non-Empty register masks
  msfpt->_in_rms[TypeFunc::ReturnAdr] = _return_addr_mask;
  msfpt->_in_rms[TypeFunc::FramePtr ] = c_frame_ptr_mask;

  // Place first outgoing argument can possibly be put.
  OptoReg::Name begin_out_arg_area = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
  assert( is_even(begin_out_arg_area), "" );
  // Compute max outgoing register number per call site.
  OptoReg::Name out_arg_limit_per_call = begin_out_arg_area;
  // Calls to C may hammer extra stack slots above and beyond any arguments.
  // These are usually backing store for register arguments for varargs.
  if( call != nullptr && call->is_CallRuntime() )
    out_arg_limit_per_call = OptoReg::add(out_arg_limit_per_call,C->varargs_C_out_slots_killed());


  // Do the normal argument list (parameters) register masks
  int argcnt = cnt - TypeFunc::Parms;
  if( argcnt > 0 ) {          // Skip it all if we have no args
    BasicType *sig_bt  = NEW_RESOURCE_ARRAY( BasicType, argcnt );
    VMRegPair *parm_regs = NEW_RESOURCE_ARRAY( VMRegPair, argcnt );
    int i;
    for( i = 0; i < argcnt; i++ ) {
      sig_bt[i] = domain->field_at(i+TypeFunc::Parms)->basic_type();
    }
    // V-call to pick proper calling convention
    call->calling_convention( sig_bt, parm_regs, argcnt );

#ifdef ASSERT
    // Sanity check users' calling convention.  Really handy during
    // the initial porting effort.  Fairly expensive otherwise.
    { for (int i = 0; i<argcnt; i++) {
      if( !parm_regs[i].first()->is_valid() &&
          !parm_regs[i].second()->is_valid() ) continue;
      VMReg reg1 = parm_regs[i].first();
      VMReg reg2 = parm_regs[i].second();
      for (int j = 0; j < i; j++) {
        if( !parm_regs[j].first()->is_valid() &&
            !parm_regs[j].second()->is_valid() ) continue;
        VMReg reg3 = parm_regs[j].first();
        VMReg reg4 = parm_regs[j].second();
        if( !reg1->is_valid() ) {
          assert( !reg2->is_valid(), "valid halvsies" );
        } else if( !reg3->is_valid() ) {
          assert( !reg4->is_valid(), "valid halvsies" );
        } else {
          assert( reg1 != reg2, "calling conv. must produce distinct regs");
          assert( reg1 != reg3, "calling conv. must produce distinct regs");
          assert( reg1 != reg4, "calling conv. must produce distinct regs");
          assert( reg2 != reg3, "calling conv. must produce distinct regs");
          assert( reg2 != reg4 || !reg2->is_valid(), "calling conv. must produce distinct regs");
          assert( reg3 != reg4, "calling conv. must produce distinct regs");
        }
      }
    }
    }
#endif

    // Visit each argument.  Compute its outgoing register mask.
    // Return results now can have 2 bits returned.
    // Compute max over all outgoing arguments both per call-site
    // and over the entire method.
    for( i = 0; i < argcnt; i++ ) {
      // Address of incoming argument mask to fill in
      RegMask *rm = &mcall->_in_rms[i+TypeFunc::Parms];
      VMReg first = parm_regs[i].first();
      VMReg second = parm_regs[i].second();
      if(!first->is_valid() &&
         !second->is_valid()) {
        continue;               // Avoid Halves
      }
      // Handle case where arguments are in vector registers.
      if(call->in(TypeFunc::Parms + i)->bottom_type()->isa_vect()) {
        OptoReg::Name reg_fst = OptoReg::as_OptoReg(first);
        OptoReg::Name reg_snd = OptoReg::as_OptoReg(second);
        assert (reg_fst <= reg_snd, "fst=%d snd=%d", reg_fst, reg_snd);
        for (OptoReg::Name r = reg_fst; r <= reg_snd; r++) {
          rm->Insert(r);
        }
      }
      // Grab first register, adjust stack slots and insert in mask.
      OptoReg::Name reg1 = warp_outgoing_stk_arg(first, begin_out_arg_area, out_arg_limit_per_call );
      if (C->failing()) {
        return nullptr;
      }
      if (OptoReg::is_valid(reg1))
        rm->Insert( reg1 );
      // Grab second register (if any), adjust stack slots and insert in mask.
      OptoReg::Name reg2 = warp_outgoing_stk_arg(second, begin_out_arg_area, out_arg_limit_per_call );
      if (C->failing()) {
        return nullptr;
      }
      if (OptoReg::is_valid(reg2))
        rm->Insert( reg2 );
    } // End of for all arguments
  }

  // Compute the max stack slot killed by any call.  These will not be
  // available for debug info, and will be used to adjust FIRST_STACK_mask
  // after all call sites have been visited.
  if( _out_arg_limit < out_arg_limit_per_call)
    _out_arg_limit = out_arg_limit_per_call;

  if (mcall) {
    // Kill the outgoing argument area, including any non-argument holes and
    // any legacy C-killed slots.  Use Fat-Projections to do the killing.
    // Since the max-per-method covers the max-per-call-site and debug info
    // is excluded on the max-per-method basis, debug info cannot land in
    // this killed area.
    uint r_cnt = mcall->tf()->range()->cnt();
    MachProjNode *proj = new MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
    if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) {
      // Bailout. We do not have space to represent all arguments.
      C->record_method_not_compilable("unsupported outgoing calling sequence");
    } else {
      for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
        proj->_rout.Insert(OptoReg::Name(i));
    }
    if (proj->_rout.is_NotEmpty()) {
      push_projection(proj);
    }
  }
  // Transfer the safepoint information from the call to the mcall
  // Move the JVMState list
  msfpt->set_jvms(sfpt->jvms());
  for (JVMState* jvms = msfpt->jvms(); jvms; jvms = jvms->caller()) {
    jvms->set_map(sfpt);
  }

  // Debug inputs begin just after the last incoming parameter
  assert((mcall == nullptr) || (mcall->jvms() == nullptr) ||
         (mcall->jvms()->debug_start() + mcall->_jvmadj == mcall->tf()->domain()->cnt()), "");

  // Add additional edges.
  if (msfpt->mach_constant_base_node_input() != (uint)-1 && !msfpt->is_MachCallLeaf()) {
    // For these calls we can not add MachConstantBase in expand(), as the
    // ins are not complete then.
    msfpt->ins_req(msfpt->mach_constant_base_node_input(), C->mach_constant_base_node());
    if (msfpt->jvms() &&
        msfpt->mach_constant_base_node_input() <= msfpt->jvms()->debug_start() + msfpt->_jvmadj) {
      // We added an edge before jvms, so we must adapt the position of the ins.
      msfpt->jvms()->adapt_position(+1);
    }
  }

  // Registers killed by the call are set in the local scheduling pass
  // of Global Code Motion.
  return msfpt;
}

//---------------------------match_tree----------------------------------------
// Match a Ideal Node DAG - turn it into a tree; Label & Reduce.  Used as part
// of the whole-sale conversion from Ideal to Mach Nodes.  Also used for
// making GotoNodes while building the CFG and in init_spill_mask() to identify
// a Load's result RegMask for memoization in idealreg2regmask[]
MachNode *Matcher::match_tree( const Node *n ) {
  assert( n->Opcode() != Op_Phi, "cannot match" );
  assert( !n->is_block_start(), "cannot match" );
  // Set the mark for all locally allocated State objects.
  // When this call returns, the _states_arena arena will be reset
  // freeing all State objects.
  ResourceMark rm( &_states_arena );

  LabelRootDepth = 0;

  // StoreNodes require their Memory input to match any LoadNodes
  Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ;
#ifdef ASSERT
  Node* save_mem_node = _mem_node;
  _mem_node = n->is_Store() ? (Node*)n : nullptr;
#endif
  // State object for root node of match tree
  // Allocate it on _states_arena - stack allocation can cause stack overflow.
  State *s = new (&_states_arena) State;
  s->_kids[0] = nullptr;
  s->_kids[1] = nullptr;
  s->_leaf = (Node*)n;
  // Label the input tree, allocating labels from top-level arena
  Node* root_mem = mem;
  Label_Root(n, s, n->in(0), root_mem);
  if (C->failing())  return nullptr;

  // The minimum cost match for the whole tree is found at the root State
  uint mincost = max_juint;
  uint cost = max_juint;
  uint i;
  for (i = 0; i < NUM_OPERANDS; i++) {
    if (s->valid(i) &&               // valid entry and
        s->cost(i) < cost &&         // low cost and
        s->rule(i) >= NUM_OPERANDS) {// not an operand
      mincost = i;
      cost = s->cost(i);
    }
  }
  if (mincost == max_juint) {
#ifndef PRODUCT
    tty->print("No matching rule for:");
    s->dump();
#endif
    Matcher::soft_match_failure();
    return nullptr;
  }
  // Reduce input tree based upon the state labels to machine Nodes
  MachNode *m = ReduceInst(s, s->rule(mincost), mem);
  // New-to-old mapping is done in ReduceInst, to cover complex instructions.
  NOT_PRODUCT(_old2new_map.map(n->_idx, m);)

  // Add any Matcher-ignored edges
  uint cnt = n->req();
  uint start = 1;
  if( mem != (Node*)1 ) start = MemNode::Memory+1;
  if( n->is_AddP() ) {
    assert( mem == (Node*)1, "" );
    start = AddPNode::Base+1;
  }
  for( i = start; i < cnt; i++ ) {
    if( !n->match_edge(i) ) {
      if( i < m->req() )
        m->ins_req( i, n->in(i) );
      else
        m->add_req( n->in(i) );
    }
  }

  DEBUG_ONLY( _mem_node = save_mem_node; )
  return m;
}


//------------------------------match_into_reg---------------------------------
// Choose to either match this Node in a register or part of the current
// match tree.  Return true for requiring a register and false for matching
// as part of the current match tree.
static bool match_into_reg( const Node *n, Node *m, Node *control, int i, bool shared ) {

  const Type *t = m->bottom_type();

  if (t->singleton()) {
    // Never force constants into registers.  Allow them to match as
    // constants or registers.  Copies of the same value will share
    // the same register.  See find_shared_node.
    return false;
  } else {                      // Not a constant
    if (!shared && Matcher::is_encode_and_store_pattern(n, m)) {
      // Make it possible to match "encode and store" patterns with non-shared
      // encode operations that are pinned to a control node (e.g. by CastPP
      // node removal in final graph reshaping). The matched instruction cannot
      // float above the encode's control node because it is pinned to the
      // store's control node.
      return false;
    }
    // Stop recursion if they have different Controls.
    Node* m_control = m->in(0);
    // Control of load's memory can post-dominates load's control.
    // So use it since load can't float above its memory.
    Node* mem_control = (m->is_Load()) ? m->in(MemNode::Memory)->in(0) : nullptr;
    if (control && m_control && control != m_control && control != mem_control) {

      // Actually, we can live with the most conservative control we
      // find, if it post-dominates the others.  This allows us to
      // pick up load/op/store trees where the load can float a little
      // above the store.
      Node *x = control;
      const uint max_scan = 6;  // Arbitrary scan cutoff
      uint j;
      for (j=0; j<max_scan; j++) {
        if (x->is_Region())     // Bail out at merge points
          return true;
        x = x->in(0);
        if (x == m_control)     // Does 'control' post-dominate
          break;                // m->in(0)?  If so, we can use it
        if (x == mem_control)   // Does 'control' post-dominate
          break;                // mem_control?  If so, we can use it
      }
      if (j == max_scan)        // No post-domination before scan end?
        return true;            // Then break the match tree up
    }
    if ((m->is_DecodeN() && Matcher::narrow_oop_use_complex_address()) ||
        (m->is_DecodeNKlass() && Matcher::narrow_klass_use_complex_address())) {
      // These are commonly used in address expressions and can
      // efficiently fold into them on X64 in some cases.
      return false;
    }
  }

  // Not forceable cloning.  If shared, put it into a register.
  return shared;
}


//------------------------------Instruction Selection--------------------------
// Label method walks a "tree" of nodes, using the ADLC generated DFA to match
// ideal nodes to machine instructions.  Trees are delimited by shared Nodes,
// things the Matcher does not match (e.g., Memory), and things with different
// Controls (hence forced into different blocks).  We pass in the Control
// selected for this entire State tree.

// The Matcher works on Trees, but an Intel add-to-memory requires a DAG: the
// Store and the Load must have identical Memories (as well as identical
// pointers).  Since the Matcher does not have anything for Memory (and
// does not handle DAGs), I have to match the Memory input myself.  If the
// Tree root is a Store or if there are multiple Loads in the tree, I require
// all Loads to have the identical memory.
Node* Matcher::Label_Root(const Node* n, State* svec, Node* control, Node*& mem) {
  // Since Label_Root is a recursive function, its possible that we might run
  // out of stack space.  See bugs 6272980 & 6227033 for more info.
  LabelRootDepth++;
  if (LabelRootDepth > MaxLabelRootDepth) {
    // Bailout. Can for example be hit with a deep chain of operations.
    C->record_method_not_compilable("Out of stack space, increase MaxLabelRootDepth");
    return nullptr;
  }
  uint care = 0;                // Edges matcher cares about
  uint cnt = n->req();
  uint i = 0;

  // Examine children for memory state
  // Can only subsume a child into your match-tree if that child's memory state
  // is not modified along the path to another input.
  // It is unsafe even if the other inputs are separate roots.
  Node *input_mem = nullptr;
  for( i = 1; i < cnt; i++ ) {
    if( !n->match_edge(i) ) continue;
    Node *m = n->in(i);         // Get ith input
    assert( m, "expect non-null children" );
    if( m->is_Load() ) {
      if( input_mem == nullptr ) {
        input_mem = m->in(MemNode::Memory);
        if (mem == (Node*)1) {
          // Save this memory to bail out if there's another memory access
          // to a different memory location in the same tree.
          mem = input_mem;
        }
      } else if( input_mem != m->in(MemNode::Memory) ) {
        input_mem = NodeSentinel;
      }
    }
  }

  for( i = 1; i < cnt; i++ ){// For my children
    if( !n->match_edge(i) ) continue;
    Node *m = n->in(i);         // Get ith input
    // Allocate states out of a private arena
    State *s = new (&_states_arena) State;
    svec->_kids[care++] = s;
    assert( care <= 2, "binary only for now" );

    // Recursively label the State tree.
    s->_kids[0] = nullptr;
    s->_kids[1] = nullptr;
    s->_leaf = m;

    // Check for leaves of the State Tree; things that cannot be a part of
    // the current tree.  If it finds any, that value is matched as a
    // register operand.  If not, then the normal matching is used.
    if( match_into_reg(n, m, control, i, is_shared(m)) ||
        // Stop recursion if this is a LoadNode and there is another memory access
        // to a different memory location in the same tree (for example, a StoreNode
        // at the root of this tree or another LoadNode in one of the children).
        ((mem!=(Node*)1) && m->is_Load() && m->in(MemNode::Memory) != mem) ||
        // Can NOT include the match of a subtree when its memory state
        // is used by any of the other subtrees
        (input_mem == NodeSentinel) ) {
      // Print when we exclude matching due to different memory states at input-loads
      if (PrintOpto && (Verbose && WizardMode) && (input_mem == NodeSentinel)
          && !((mem!=(Node*)1) && m->is_Load() && m->in(MemNode::Memory) != mem)) {
        tty->print_cr("invalid input_mem");
      }
      // Switch to a register-only opcode; this value must be in a register
      // and cannot be subsumed as part of a larger instruction.
      s->DFA( m->ideal_reg(), m );

    } else {
      // If match tree has no control and we do, adopt it for entire tree
      if( control == nullptr && m->in(0) != nullptr && m->req() > 1 )
        control = m->in(0);         // Pick up control
      // Else match as a normal part of the match tree.
      control = Label_Root(m, s, control, mem);
      if (C->failing()) return nullptr;
    }
  }

  // Call DFA to match this node, and return
  svec->DFA( n->Opcode(), n );

  uint x;
  for( x = 0; x < _LAST_MACH_OPER; x++ )
    if( svec->valid(x) )
      break;

  if (x >= _LAST_MACH_OPER) {
#ifdef ASSERT
    n->dump();
    svec->dump();
#endif
    assert( false, "bad AD file" );
    C->record_failure("bad AD file");
  }
  return control;
}


// Con nodes reduced using the same rule can share their MachNode
// which reduces the number of copies of a constant in the final
// program.  The register allocator is free to split uses later to
// split live ranges.
MachNode* Matcher::find_shared_node(Node* leaf, uint rule) {
  if (!leaf->is_Con() && !leaf->is_DecodeNarrowPtr()) return nullptr;

  // See if this Con has already been reduced using this rule.
  if (_shared_nodes.max() <= leaf->_idx) return nullptr;
  MachNode* last = (MachNode*)_shared_nodes.at(leaf->_idx);
  if (last != nullptr && rule == last->rule()) {
    // Don't expect control change for DecodeN
    if (leaf->is_DecodeNarrowPtr())
      return last;
    // Get the new space root.
    Node* xroot = new_node(C->root());
    if (xroot == nullptr) {
      // This shouldn't happen give the order of matching.
      return nullptr;
    }

    // Shared constants need to have their control be root so they
    // can be scheduled properly.
    Node* control = last->in(0);
    if (control != xroot) {
      if (control == nullptr || control == C->root()) {
        last->set_req(0, xroot);
      } else {
        assert(false, "unexpected control");
        return nullptr;
      }
    }
    return last;
  }
  return nullptr;
}


//------------------------------ReduceInst-------------------------------------
// Reduce a State tree (with given Control) into a tree of MachNodes.
// This routine (and it's cohort ReduceOper) convert Ideal Nodes into
// complicated machine Nodes.  Each MachNode covers some tree of Ideal Nodes.
// Each MachNode has a number of complicated MachOper operands; each
// MachOper also covers a further tree of Ideal Nodes.

// The root of the Ideal match tree is always an instruction, so we enter
// the recursion here.  After building the MachNode, we need to recurse
// the tree checking for these cases:
// (1) Child is an instruction -
//     Build the instruction (recursively), add it as an edge.
//     Build a simple operand (register) to hold the result of the instruction.
// (2) Child is an interior part of an instruction -
//     Skip over it (do nothing)
// (3) Child is the start of a operand -
//     Build the operand, place it inside the instruction
//     Call ReduceOper.
MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
  assert( rule >= NUM_OPERANDS, "called with operand rule" );

  MachNode* shared_node = find_shared_node(s->_leaf, rule);
  if (shared_node != nullptr) {
    return shared_node;
  }

  // Build the object to represent this state & prepare for recursive calls
  MachNode *mach = s->MachNodeGenerator(rule);
  guarantee(mach != nullptr, "Missing MachNode");
  mach->_opnds[0] = s->MachOperGenerator(_reduceOp[rule]);
  assert( mach->_opnds[0] != nullptr, "Missing result operand" );
  Node *leaf = s->_leaf;
  NOT_PRODUCT(record_new2old(mach, leaf);)
  // Check for instruction or instruction chain rule
  if( rule >= _END_INST_CHAIN_RULE || rule < _BEGIN_INST_CHAIN_RULE ) {
    assert(C->node_arena()->contains(s->_leaf) || !has_new_node(s->_leaf),
           "duplicating node that's already been matched");
    // Instruction
    mach->add_req( leaf->in(0) ); // Set initial control
    // Reduce interior of complex instruction
    ReduceInst_Interior( s, rule, mem, mach, 1 );
  } else {
    // Instruction chain rules are data-dependent on their inputs
    mach->add_req(nullptr);     // Set initial control to none
    ReduceInst_Chain_Rule( s, rule, mem, mach );
  }

  // If a Memory was used, insert a Memory edge
  if( mem != (Node*)1 ) {
    mach->ins_req(MemNode::Memory,mem);
#ifdef ASSERT
    // Verify adr type after matching memory operation
    const MachOper* oper = mach->memory_operand();
    if (oper != nullptr && oper != (MachOper*)-1) {
      // It has a unique memory operand.  Find corresponding ideal mem node.
      Node* m = nullptr;
      if (leaf->is_Mem()) {
        m = leaf;
      } else {
        m = _mem_node;
        assert(m != nullptr && m->is_Mem(), "expecting memory node");
      }
      const Type* mach_at = mach->adr_type();
      // DecodeN node consumed by an address may have different type
      // than its input. Don't compare types for such case.
      if (m->adr_type() != mach_at &&
          (m->in(MemNode::Address)->is_DecodeNarrowPtr() ||
           (m->in(MemNode::Address)->is_AddP() &&
            m->in(MemNode::Address)->in(AddPNode::Address)->is_DecodeNarrowPtr()) ||
           (m->in(MemNode::Address)->is_AddP() &&
            m->in(MemNode::Address)->in(AddPNode::Address)->is_AddP() &&
            m->in(MemNode::Address)->in(AddPNode::Address)->in(AddPNode::Address)->is_DecodeNarrowPtr()))) {
        mach_at = m->adr_type();
      }
      if (m->adr_type() != mach_at) {
        m->dump();
        tty->print_cr("mach:");
        mach->dump(1);
      }
      assert(m->adr_type() == mach_at, "matcher should not change adr type");
    }
#endif
  }

  // If the _leaf is an AddP, insert the base edge
  if (leaf->is_AddP()) {
    mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base));
  }

  uint number_of_projections_prior = number_of_projections();

  // Perform any 1-to-many expansions required
  MachNode *ex = mach->Expand(s, _projection_list, mem);
  if (ex != mach) {
    assert(ex->ideal_reg() == mach->ideal_reg(), "ideal types should match");
    if( ex->in(1)->is_Con() )
      ex->in(1)->set_req(0, C->root());
    // Remove old node from the graph
    for( uint i=0; i<mach->req(); i++ ) {
      mach->set_req(i,nullptr);
    }
    NOT_PRODUCT(record_new2old(ex, s->_leaf);)
  }

  // PhaseChaitin::fixup_spills will sometimes generate spill code
  // via the matcher.  By the time, nodes have been wired into the CFG,
  // and any further nodes generated by expand rules will be left hanging
  // in space, and will not get emitted as output code.  Catch this.
  // Also, catch any new register allocation constraints ("projections")
  // generated belatedly during spill code generation.
  if (_allocation_started) {
    guarantee(ex == mach, "no expand rules during spill generation");
    guarantee(number_of_projections_prior == number_of_projections(), "no allocation during spill generation");
  }

  if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
    // Record the con for sharing
    _shared_nodes.map(leaf->_idx, ex);
  }

  // Have mach nodes inherit GC barrier data
  mach->set_barrier_data(MemNode::barrier_data(leaf));

  return ex;
}

void Matcher::handle_precedence_edges(Node* n, MachNode *mach) {
  for (uint i = n->req(); i < n->len(); i++) {
    if (n->in(i) != nullptr) {
      mach->add_prec(n->in(i));
    }
  }
}

void Matcher::ReduceInst_Chain_Rule(State* s, int rule, Node* &mem, MachNode* mach) {
  // 'op' is what I am expecting to receive
  int op = _leftOp[rule];
  // Operand type to catch childs result
  // This is what my child will give me.
  unsigned int opnd_class_instance = s->rule(op);
  // Choose between operand class or not.
  // This is what I will receive.
  int catch_op = (FIRST_OPERAND_CLASS <= op && op < NUM_OPERANDS) ? opnd_class_instance : op;
  // New rule for child.  Chase operand classes to get the actual rule.
  unsigned int newrule = s->rule(catch_op);

  if (newrule < NUM_OPERANDS) {
    // Chain from operand or operand class, may be output of shared node
    assert(opnd_class_instance < NUM_OPERANDS, "Bad AD file: Instruction chain rule must chain from operand");
    // Insert operand into array of operands for this instruction
    mach->_opnds[1] = s->MachOperGenerator(opnd_class_instance);

    ReduceOper(s, newrule, mem, mach);
  } else {
    // Chain from the result of an instruction
    assert(newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
    mach->_opnds[1] = s->MachOperGenerator(_reduceOp[catch_op]);
    Node *mem1 = (Node*)1;
    DEBUG_ONLY(Node *save_mem_node = _mem_node;)
    mach->add_req( ReduceInst(s, newrule, mem1) );
    DEBUG_ONLY(_mem_node = save_mem_node;)
  }
  return;
}


uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) {
  handle_precedence_edges(s->_leaf, mach);

  if( s->_leaf->is_Load() ) {
    Node *mem2 = s->_leaf->in(MemNode::Memory);
    assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
    DEBUG_ONLY( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
    mem = mem2;
  }
  if( s->_leaf->in(0) != nullptr && s->_leaf->req() > 1) {
    if( mach->in(0) == nullptr )
      mach->set_req(0, s->_leaf->in(0));
  }

  // Now recursively walk the state tree & add operand list.
  for( uint i=0; i<2; i++ ) {   // binary tree
    State *newstate = s->_kids[i];
    if( newstate == nullptr ) break;      // Might only have 1 child
    // 'op' is what I am expecting to receive
    int op;
    if( i == 0 ) {
      op = _leftOp[rule];
    } else {
      op = _rightOp[rule];
    }
    // Operand type to catch childs result
    // This is what my child will give me.
    int opnd_class_instance = newstate->rule(op);
    // Choose between operand class or not.
    // This is what I will receive.
    int catch_op = (op >= FIRST_OPERAND_CLASS && op < NUM_OPERANDS) ? opnd_class_instance : op;
    // New rule for child.  Chase operand classes to get the actual rule.
    int newrule = newstate->rule(catch_op);

    if (newrule < NUM_OPERANDS) { // Operand/operandClass or internalOp/instruction?
      // Operand/operandClass
      // Insert operand into array of operands for this instruction
      mach->_opnds[num_opnds++] = newstate->MachOperGenerator(opnd_class_instance);
      ReduceOper(newstate, newrule, mem, mach);

    } else {                    // Child is internal operand or new instruction
      if (newrule < _LAST_MACH_OPER) { // internal operand or instruction?
        // internal operand --> call ReduceInst_Interior
        // Interior of complex instruction.  Do nothing but recurse.
        num_opnds = ReduceInst_Interior(newstate, newrule, mem, mach, num_opnds);
      } else {
        // instruction --> call build operand(  ) to catch result
        //             --> ReduceInst( newrule )
        mach->_opnds[num_opnds++] = s->MachOperGenerator(_reduceOp[catch_op]);
        Node *mem1 = (Node*)1;
        DEBUG_ONLY(Node *save_mem_node = _mem_node;)
        mach->add_req( ReduceInst( newstate, newrule, mem1 ) );
        DEBUG_ONLY(_mem_node = save_mem_node;)
      }
    }
    assert( mach->_opnds[num_opnds-1], "" );
  }
  return num_opnds;
}

// This routine walks the interior of possible complex operands.
// At each point we check our children in the match tree:
// (1) No children -
//     We are a leaf; add _leaf field as an input to the MachNode
// (2) Child is an internal operand -
//     Skip over it ( do nothing )
// (3) Child is an instruction -
//     Call ReduceInst recursively and
//     and instruction as an input to the MachNode
void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
  assert( rule < _LAST_MACH_OPER, "called with operand rule" );
  State *kid = s->_kids[0];
  assert( kid == nullptr || s->_leaf->in(0) == nullptr, "internal operands have no control" );

  // Leaf?  And not subsumed?
  if( kid == nullptr && !_swallowed[rule] ) {
    mach->add_req( s->_leaf );  // Add leaf pointer
    return;                     // Bail out
  }

  if( s->_leaf->is_Load() ) {
    assert( mem == (Node*)1, "multiple Memories being matched at once?" );
    mem = s->_leaf->in(MemNode::Memory);
    DEBUG_ONLY(_mem_node = s->_leaf;)
  }

  handle_precedence_edges(s->_leaf, mach);

  if( s->_leaf->in(0) && s->_leaf->req() > 1) {
    if( !mach->in(0) )
      mach->set_req(0,s->_leaf->in(0));
    else {
      assert( s->_leaf->in(0) == mach->in(0), "same instruction, differing controls?" );
    }
  }

  for (uint i = 0; kid != nullptr && i < 2; kid = s->_kids[1], i++) {   // binary tree
    int newrule;
    if( i == 0) {
      newrule = kid->rule(_leftOp[rule]);
    } else {
      newrule = kid->rule(_rightOp[rule]);
    }

    if (newrule < _LAST_MACH_OPER) { // Operand or instruction?
      // Internal operand; recurse but do nothing else
      ReduceOper(kid, newrule, mem, mach);

    } else {                    // Child is a new instruction
      // Reduce the instruction, and add a direct pointer from this
      // machine instruction to the newly reduced one.
      Node *mem1 = (Node*)1;
      DEBUG_ONLY(Node *save_mem_node = _mem_node;)
      mach->add_req( ReduceInst( kid, newrule, mem1 ) );
      DEBUG_ONLY(_mem_node = save_mem_node;)
    }
  }
}


// -------------------------------------------------------------------------
// Java-Java calling convention
// (what you use when Java calls Java)

//------------------------------find_receiver----------------------------------
// For a given signature, return the OptoReg for parameter 0.
OptoReg::Name Matcher::find_receiver() {
  VMRegPair regs;
  BasicType sig_bt = T_OBJECT;
  SharedRuntime::java_calling_convention(&sig_bt, &regs, 1);
  // Return argument 0 register.  In the LP64 build pointers
  // take 2 registers, but the VM wants only the 'main' name.
  return OptoReg::as_OptoReg(regs.first());
}

bool Matcher::is_vshift_con_pattern(Node* n, Node* m) {
  if (n != nullptr && m != nullptr) {
    return VectorNode::is_vector_shift(n) &&
           VectorNode::is_vector_shift_count(m) && m->in(1)->is_Con();
  }
  return false;
}

bool Matcher::clone_node(Node* n, Node* m, Matcher::MStack& mstack) {
  // Must clone all producers of flags, or we will not match correctly.
  // Suppose a compare setting int-flags is shared (e.g., a switch-tree)
  // then it will match into an ideal Op_RegFlags.  Alas, the fp-flags
  // are also there, so we may match a float-branch to int-flags and
  // expect the allocator to haul the flags from the int-side to the
  // fp-side.  No can do.
  if (_must_clone[m->Opcode()]) {
    mstack.push(m, Visit);
    return true;
  }
  return pd_clone_node(n, m, mstack);
}

bool Matcher::clone_base_plus_offset_address(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) {
  Node *off = m->in(AddPNode::Offset);
  if (off->is_Con()) {
    address_visited.test_set(m->_idx); // Flag as address_visited
    mstack.push(m->in(AddPNode::Address), Pre_Visit);
    // Clone X+offset as it also folds into most addressing expressions
    mstack.push(off, Visit);
    mstack.push(m->in(AddPNode::Base), Pre_Visit);
    return true;
  }
  return false;
}

// A method-klass-holder may be passed in the inline_cache_reg
// and then expanded into the inline_cache_reg and a method_ptr register
//   defined in ad_<arch>.cpp

//------------------------------find_shared------------------------------------
// Set bits if Node is shared or otherwise a root
void Matcher::find_shared(Node* n) {
  // Allocate stack of size C->live_nodes() * 2 to avoid frequent realloc
  MStack mstack(C->live_nodes() * 2);
  // Mark nodes as address_visited if they are inputs to an address expression
  VectorSet address_visited;
  mstack.push(n, Visit);     // Don't need to pre-visit root node
  while (mstack.is_nonempty()) {
    n = mstack.node();       // Leave node on stack
    Node_State nstate = mstack.state();
    uint nop = n->Opcode();
    if (nstate == Pre_Visit) {
      if (address_visited.test(n->_idx)) { // Visited in address already?
        // Flag as visited and shared now.
        set_visited(n);
      }
      if (is_visited(n)) {   // Visited already?
        // Node is shared and has no reason to clone.  Flag it as shared.
        // This causes it to match into a register for the sharing.
        set_shared(n);       // Flag as shared and
        if (n->is_DecodeNarrowPtr()) {
          // Oop field/array element loads must be shared but since
          // they are shared through a DecodeN they may appear to have
          // a single use so force sharing here.
          set_shared(n->in(1));
        }
        mstack.pop();        // remove node from stack
        continue;
      }
      nstate = Visit; // Not already visited; so visit now
    }
    if (nstate == Visit) {
      mstack.set_state(Post_Visit);
      set_visited(n);   // Flag as visited now
      bool mem_op = false;
      int mem_addr_idx = MemNode::Address;
      if (find_shared_visit(mstack, n, nop, mem_op, mem_addr_idx)) {
        continue;
      }
      for (int i = n->req() - 1; i >= 0; --i) { // For my children
        Node* m = n->in(i); // Get ith input
        if (m == nullptr) {
          continue;  // Ignore nulls
        }
        if (clone_node(n, m, mstack)) {
          continue;
        }

        // Clone addressing expressions as they are "free" in memory access instructions
        if (mem_op && i == mem_addr_idx && m->is_AddP() &&
            // When there are other uses besides address expressions
            // put it on stack and mark as shared.
            !is_visited(m)) {
          // Some inputs for address expression are not put on stack
          // to avoid marking them as shared and forcing them into register
          // if they are used only in address expressions.
          // But they should be marked as shared if there are other uses
          // besides address expressions.

          if (pd_clone_address_expressions(m->as_AddP(), mstack, address_visited)) {
            continue;
          }
        }   // if( mem_op &&
        mstack.push(m, Pre_Visit);
      }     // for(int i = ...)
    }
    else if (nstate == Alt_Post_Visit) {
      mstack.pop(); // Remove node from stack
      // We cannot remove the Cmp input from the Bool here, as the Bool may be
      // shared and all users of the Bool need to move the Cmp in parallel.
      // This leaves both the Bool and the If pointing at the Cmp.  To
      // prevent the Matcher from trying to Match the Cmp along both paths
      // BoolNode::match_edge always returns a zero.

      // We reorder the Op_If in a pre-order manner, so we can visit without
      // accidentally sharing the Cmp (the Bool and the If make 2 users).
      n->add_req( n->in(1)->in(1) ); // Add the Cmp next to the Bool
    }
    else if (nstate == Post_Visit) {
      mstack.pop(); // Remove node from stack

      // Now hack a few special opcodes
      uint opcode = n->Opcode();
      bool gc_handled = BarrierSet::barrier_set()->barrier_set_c2()->matcher_find_shared_post_visit(this, n, opcode);
      if (!gc_handled) {
        find_shared_post_visit(n, opcode);
      }
    }
    else {
      ShouldNotReachHere();
    }
  } // end of while (mstack.is_nonempty())
}

bool Matcher::find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx) {
  switch(opcode) {  // Handle some opcodes special
    case Op_Phi:             // Treat Phis as shared roots
    case Op_Parm:
    case Op_Proj:            // All handled specially during matching
    case Op_SafePointScalarObject:
      set_shared(n);
      set_dontcare(n);
      break;
    case Op_If:
    case Op_CountedLoopEnd:
      mstack.set_state(Alt_Post_Visit); // Alternative way
      // Convert (If (Bool (CmpX A B))) into (If (Bool) (CmpX A B)).  Helps
      // with matching cmp/branch in 1 instruction.  The Matcher needs the
      // Bool and CmpX side-by-side, because it can only get at constants
      // that are at the leaves of Match trees, and the Bool's condition acts
      // as a constant here.
      mstack.push(n->in(1), Visit);         // Clone the Bool
      mstack.push(n->in(0), Pre_Visit);     // Visit control input
      return true; // while (mstack.is_nonempty())
    case Op_ConvI2D:         // These forms efficiently match with a prior
    case Op_ConvI2F:         //   Load but not a following Store
      if( n->in(1)->is_Load() &&        // Prior load
          n->outcnt() == 1 &&           // Not already shared
          n->unique_out()->is_Store() ) // Following store
        set_shared(n);       // Force it to be a root
      break;
    case Op_ReverseBytesI:
    case Op_ReverseBytesL:
      if( n->in(1)->is_Load() &&        // Prior load
          n->outcnt() == 1 )            // Not already shared
        set_shared(n);                  // Force it to be a root
      break;
    case Op_BoxLock:         // Can't match until we get stack-regs in ADLC
    case Op_IfFalse:
    case Op_IfTrue:
    case Op_MachProj:
    case Op_MergeMem:
    case Op_Catch:
    case Op_CatchProj:
    case Op_CProj:
    case Op_JumpProj:
    case Op_JProj:
    case Op_NeverBranch:
      set_dontcare(n);
      break;
    case Op_Jump:
      mstack.push(n->in(1), Pre_Visit);     // Switch Value (could be shared)
      mstack.push(n->in(0), Pre_Visit);     // Visit Control input
      return true;                             // while (mstack.is_nonempty())
    case Op_StrComp:
    case Op_StrEquals:
    case Op_StrIndexOf:
    case Op_StrIndexOfChar:
    case Op_AryEq:
    case Op_VectorizedHashCode:
    case Op_CountPositives:
    case Op_StrInflatedCopy:
    case Op_StrCompressedCopy:
    case Op_EncodeISOArray:
    case Op_FmaD:
    case Op_FmaF:
    case Op_FmaHF:
    case Op_FmaVD:
    case Op_FmaVF:
    case Op_FmaVHF:
    case Op_MacroLogicV:
    case Op_VectorCmpMasked:
    case Op_CompressV:
    case Op_CompressM:
    case Op_ExpandV:
    case Op_VectorLoadMask:
      set_shared(n); // Force result into register (it will be anyways)
      break;
    case Op_ConP: {  // Convert pointers above the centerline to NUL
      TypeNode *tn = n->as_Type(); // Constants derive from type nodes
      const TypePtr* tp = tn->type()->is_ptr();
      if (tp->_ptr == TypePtr::AnyNull) {
        tn->set_type(TypePtr::NULL_PTR);
      }
      break;
    }
    case Op_ConN: {  // Convert narrow pointers above the centerline to NUL
      TypeNode *tn = n->as_Type(); // Constants derive from type nodes
      const TypePtr* tp = tn->type()->make_ptr();
      if (tp && tp->_ptr == TypePtr::AnyNull) {
        tn->set_type(TypeNarrowOop::NULL_PTR);
      }
      break;
    }
    case Op_Binary:         // These are introduced in the Post_Visit state.
      ShouldNotReachHere();
      break;
    case Op_ClearArray:
    case Op_SafePoint:
      mem_op = true;
      break;
    default:
      if( n->is_Store() ) {
        // Do match stores, despite no ideal reg
        mem_op = true;
        break;
      }
      if( n->is_Mem() ) { // Loads and LoadStores
        mem_op = true;
        // Loads must be root of match tree due to prior load conflict
        if( C->subsume_loads() == false )
          set_shared(n);
      }
      // Fall into default case
      if( !n->ideal_reg() )
        set_dontcare(n);  // Unmatchable Nodes
  } // end_switch
  return false;
}

void Matcher::find_shared_post_visit(Node* n, uint opcode) {
  if (n->is_predicated_vector()) {
    // Restructure into binary trees for Matching.
    if (n->req() == 4) {
      n->set_req(1, new BinaryNode(n->in(1), n->in(2)));
      n->set_req(2, n->in(3));
      n->del_req(3);
    } else if (n->req() == 5) {
      n->set_req(1, new BinaryNode(n->in(1), n->in(2)));
      n->set_req(2, new BinaryNode(n->in(3), n->in(4)));
      n->del_req(4);
      n->del_req(3);
    } else if (n->req() == 6) {
      Node* b3 = new BinaryNode(n->in(4), n->in(5));
      Node* b2 = new BinaryNode(n->in(3), b3);
      Node* b1 = new BinaryNode(n->in(2), b2);
      n->set_req(2, b1);
      n->del_req(5);
      n->del_req(4);
      n->del_req(3);
    }
    return;
  }

  switch(opcode) {       // Handle some opcodes special
    case Op_CompareAndExchangeB:
    case Op_CompareAndExchangeS:
    case Op_CompareAndExchangeI:
    case Op_CompareAndExchangeL:
    case Op_CompareAndExchangeP:
    case Op_CompareAndExchangeN:
    case Op_WeakCompareAndSwapB:
    case Op_WeakCompareAndSwapS:
    case Op_WeakCompareAndSwapI:
    case Op_WeakCompareAndSwapL:
    case Op_WeakCompareAndSwapP:
    case Op_WeakCompareAndSwapN:
    case Op_CompareAndSwapB:
    case Op_CompareAndSwapS:
    case Op_CompareAndSwapI:
    case Op_CompareAndSwapL:
    case Op_CompareAndSwapP:
    case Op_CompareAndSwapN: {   // Convert trinary to binary-tree
      Node* newval = n->in(MemNode::ValueIn);
      Node* oldval = n->in(LoadStoreConditionalNode::ExpectedIn);
      Node* pair = new BinaryNode(oldval, newval);
      n->set_req(MemNode::ValueIn, pair);
      n->del_req(LoadStoreConditionalNode::ExpectedIn);
      break;
    }
    case Op_CMoveD:              // Convert trinary to binary-tree
    case Op_CMoveF:
    case Op_CMoveI:
    case Op_CMoveL:
    case Op_CMoveN:
    case Op_CMoveP: {
      // Restructure into a binary tree for Matching.  It's possible that
      // we could move this code up next to the graph reshaping for IfNodes
      // or vice-versa, but I do not want to debug this for Ladybird.
      // 10/2/2000 CNC.
      Node* pair1 = new BinaryNode(n->in(1), n->in(1)->in(1));
      n->set_req(1, pair1);
      Node* pair2 = new BinaryNode(n->in(2), n->in(3));
      n->set_req(2, pair2);
      n->del_req(3);
      break;
    }
    case Op_MacroLogicV: {
      Node* pair1 = new BinaryNode(n->in(1), n->in(2));
      Node* pair2 = new BinaryNode(n->in(3), n->in(4));
      n->set_req(1, pair1);
      n->set_req(2, pair2);
      n->del_req(4);
      n->del_req(3);
      break;
    }
    case Op_StoreVectorMasked: {
      Node* pair = new BinaryNode(n->in(3), n->in(4));
      n->set_req(3, pair);
      n->del_req(4);
      break;
    }
    case Op_SelectFromTwoVector:
    case Op_LoopLimit: {
      Node* pair1 = new BinaryNode(n->in(1), n->in(2));
      n->set_req(1, pair1);
      n->set_req(2, n->in(3));
      n->del_req(3);
      break;
    }
    case Op_StrEquals:
    case Op_StrIndexOfChar: {
      Node* pair1 = new BinaryNode(n->in(2), n->in(3));
      n->set_req(2, pair1);
      n->set_req(3, n->in(4));
      n->del_req(4);
      break;
    }
    case Op_StrComp:
    case Op_StrIndexOf:
    case Op_VectorizedHashCode: {
      Node* pair1 = new BinaryNode(n->in(2), n->in(3));
      n->set_req(2, pair1);
      Node* pair2 = new BinaryNode(n->in(4),n->in(5));
      n->set_req(3, pair2);
      n->del_req(5);
      n->del_req(4);
      break;
    }
    case Op_EncodeISOArray:
    case Op_StrCompressedCopy:
    case Op_StrInflatedCopy: {
      // Restructure into a binary tree for Matching.
      Node* pair = new BinaryNode(n->in(3), n->in(4));
      n->set_req(3, pair);
      n->del_req(4);
      break;
    }
    case Op_FmaD:
    case Op_FmaF:
    case Op_FmaHF:
    case Op_FmaVD:
    case Op_FmaVF:
    case Op_FmaVHF: {
      // Restructure into a binary tree for Matching.
      Node* pair = new BinaryNode(n->in(1), n->in(2));
      n->set_req(2, pair);
      n->set_req(1, n->in(3));
      n->del_req(3);
      break;
    }
    case Op_MulAddS2I: {
      Node* pair1 = new BinaryNode(n->in(1), n->in(2));
      Node* pair2 = new BinaryNode(n->in(3), n->in(4));
      n->set_req(1, pair1);
      n->set_req(2, pair2);
      n->del_req(4);
      n->del_req(3);
      break;
    }
    case Op_VectorCmpMasked:
    case Op_CopySignD:
    case Op_SignumVF:
    case Op_SignumVD:
    case Op_SignumF:
    case Op_SignumD: {
      Node* pair = new BinaryNode(n->in(2), n->in(3));
      n->set_req(2, pair);
      n->del_req(3);
      break;
    }
    case Op_VectorBlend:
    case Op_VectorInsert: {
      Node* pair = new BinaryNode(n->in(1), n->in(2));
      n->set_req(1, pair);
      n->set_req(2, n->in(3));
      n->del_req(3);
      break;
    }
    case Op_LoadVectorGather:
      if (is_subword_type(n->bottom_type()->is_vect()->element_basic_type())) {
        Node* pair = new BinaryNode(n->in(MemNode::ValueIn), n->in(MemNode::ValueIn+1));
        n->set_req(MemNode::ValueIn, pair);
        n->del_req(MemNode::ValueIn+1);
      }
      break;
    case Op_LoadVectorGatherMasked:
      if (is_subword_type(n->bottom_type()->is_vect()->element_basic_type())) {
        Node* pair2 = new BinaryNode(n->in(MemNode::ValueIn + 1), n->in(MemNode::ValueIn + 2));
        Node* pair1 = new BinaryNode(n->in(MemNode::ValueIn), pair2);
        n->set_req(MemNode::ValueIn, pair1);
        n->del_req(MemNode::ValueIn+2);
        n->del_req(MemNode::ValueIn+1);
        break;
      } // fall-through
    case Op_StoreVectorScatter: {
      Node* pair = new BinaryNode(n->in(MemNode::ValueIn), n->in(MemNode::ValueIn+1));
      n->set_req(MemNode::ValueIn, pair);
      n->del_req(MemNode::ValueIn+1);
      break;
    }
    case Op_StoreVectorScatterMasked: {
      Node* pair = new BinaryNode(n->in(MemNode::ValueIn+1), n->in(MemNode::ValueIn+2));
      n->set_req(MemNode::ValueIn+1, pair);
      n->del_req(MemNode::ValueIn+2);
      pair = new BinaryNode(n->in(MemNode::ValueIn), n->in(MemNode::ValueIn+1));
      n->set_req(MemNode::ValueIn, pair);
      n->del_req(MemNode::ValueIn+1);
      break;
    }
    case Op_VectorMaskCmp: {
      n->set_req(1, new BinaryNode(n->in(1), n->in(2)));
      n->set_req(2, n->in(3));
      n->del_req(3);
      break;
    }
    case Op_PartialSubtypeCheck: {
      if (UseSecondarySupersTable && n->in(2)->is_Con()) {
        // PartialSubtypeCheck uses both constant and register operands for superclass input.
        n->set_req(2, new BinaryNode(n->in(2), n->in(2)));
        break;
      }
      break;
    }
    default:
      break;
  }
}

#ifndef PRODUCT
void Matcher::record_new2old(Node* newn, Node* old) {
  _new2old_map.map(newn->_idx, old);
  if (!_reused.test_set(old->_igv_idx)) {
    // Reuse the Ideal-level IGV identifier so that the node can be tracked
    // across matching. If there are multiple machine nodes expanded from the
    // same Ideal node, only one will reuse its IGV identifier.
    newn->_igv_idx = old->_igv_idx;
  }
}

// machine-independent root to machine-dependent root
void Matcher::dump_old2new_map() {
  _old2new_map.dump();
}
#endif // !PRODUCT

//---------------------------collect_null_checks-------------------------------
// Find null checks in the ideal graph; write a machine-specific node for
// it.  Used by later implicit-null-check handling.  Actually collects
// either an IfTrue or IfFalse for the common NOT-null path, AND the ideal
// value being tested.
void Matcher::collect_null_checks( Node *proj, Node *orig_proj ) {
  Node *iff = proj->in(0);
  if( iff->Opcode() == Op_If ) {
    // During matching If's have Bool & Cmp side-by-side
    BoolNode *b = iff->in(1)->as_Bool();
    Node *cmp = iff->in(2);
    int opc = cmp->Opcode();
    if (opc != Op_CmpP && opc != Op_CmpN) return;

    const Type* ct = cmp->in(2)->bottom_type();
    if (ct == TypePtr::NULL_PTR ||
        (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) {

      bool push_it = false;
      if( proj->Opcode() == Op_IfTrue ) {
#ifndef PRODUCT
        extern uint all_null_checks_found;
        all_null_checks_found++;
#endif
        if( b->_test._test == BoolTest::ne ) {
          push_it = true;
        }
      } else {
        assert( proj->Opcode() == Op_IfFalse, "" );
        if( b->_test._test == BoolTest::eq ) {
          push_it = true;
        }
      }
      if( push_it ) {
        _null_check_tests.push(proj);
        Node* val = cmp->in(1);
#ifdef _LP64
        if (val->bottom_type()->isa_narrowoop() &&
            !Matcher::narrow_oop_use_complex_address()) {
          //
          // Look for DecodeN node which should be pinned to orig_proj.
          // On platforms (Sparc) which can not handle 2 adds
          // in addressing mode we have to keep a DecodeN node and
          // use it to do implicit null check in address.
          //
          // DecodeN node was pinned to non-null path (orig_proj) during
          // CastPP transformation in final_graph_reshaping_impl().
          //
          uint cnt = orig_proj->outcnt();
          for (uint i = 0; i < orig_proj->outcnt(); i++) {
            Node* d = orig_proj->raw_out(i);
            if (d->is_DecodeN() && d->in(1) == val) {
              val = d;
              val->set_req(0, nullptr); // Unpin now.
              // Mark this as special case to distinguish from
              // a regular case: CmpP(DecodeN, null).
              val = (Node*)(((intptr_t)val) | 1);
              break;
            }
          }
        }
#endif
        _null_check_tests.push(val);
      }
    }
  }
}

//---------------------------validate_null_checks------------------------------
// Its possible that the value being null checked is not the root of a match
// tree.  If so, I cannot use the value in an implicit null check.
void Matcher::validate_null_checks( ) {
  uint cnt = _null_check_tests.size();
  for( uint i=0; i < cnt; i+=2 ) {
    Node *test = _null_check_tests[i];
    Node *val = _null_check_tests[i+1];
    bool is_decoden = ((intptr_t)val) & 1;
    val = (Node*)(((intptr_t)val) & ~1);
    if (has_new_node(val)) {
      Node* new_val = new_node(val);
      if (is_decoden) {
        assert(val->is_DecodeNarrowPtr() && val->in(0) == nullptr, "sanity");
        // Note: new_val may have a control edge if
        // the original ideal node DecodeN was matched before
        // it was unpinned in Matcher::collect_null_checks().
        // Unpin the mach node and mark it.
        new_val->set_req(0, nullptr);
        new_val = (Node*)(((intptr_t)new_val) | 1);
      }
      // Is a match-tree root, so replace with the matched value
      _null_check_tests.map(i+1, new_val);
    } else {
      // Yank from candidate list
      _null_check_tests.map(i+1,_null_check_tests[--cnt]);
      _null_check_tests.map(i,_null_check_tests[--cnt]);
      _null_check_tests.pop();
      _null_check_tests.pop();
      i-=2;
    }
  }
}

bool Matcher::gen_narrow_oop_implicit_null_checks() {
  // Advice matcher to perform null checks on the narrow oop side.
  // Implicit checks are not possible on the uncompressed oop side anyway
  // (at least not for read accesses).
  // Performs significantly better (especially on Power 6).
  if (!os::zero_page_read_protected()) {
    return true;
  }
  return CompressedOops::use_implicit_null_checks() &&
         (narrow_oop_use_complex_address() ||
          CompressedOops::base() != nullptr);
}

// Compute RegMask for an ideal register.
const RegMask* Matcher::regmask_for_ideal_register(uint ideal_reg, Node* ret) {
  assert(!C->failing_internal() || C->failure_is_artificial(), "already failing.");
  if (C->failing()) {
    return nullptr;
  }
  const Type* t = Type::mreg2type[ideal_reg];
  if (t == nullptr) {
    assert(ideal_reg >= Op_VecA && ideal_reg <= Op_VecZ, "not a vector: %d", ideal_reg);
    return nullptr; // not supported
  }
  Node* fp  = ret->in(TypeFunc::FramePtr);
  Node* mem = ret->in(TypeFunc::Memory);
  const TypePtr* atp = TypePtr::BOTTOM;
  MemNode::MemOrd mo = MemNode::unordered;

  Node* spill;
  switch (ideal_reg) {
    case Op_RegN: spill = new LoadNNode(nullptr, mem, fp, atp, t->is_narrowoop(), mo); break;
    case Op_RegI: spill = new LoadINode(nullptr, mem, fp, atp, t->is_int(),       mo); break;
    case Op_RegP: spill = new LoadPNode(nullptr, mem, fp, atp, t->is_ptr(),       mo); break;
    case Op_RegF: spill = new LoadFNode(nullptr, mem, fp, atp, t,                 mo); break;
    case Op_RegD: spill = new LoadDNode(nullptr, mem, fp, atp, t,                 mo); break;
    case Op_RegL: spill = new LoadLNode(nullptr, mem, fp, atp, t->is_long(),      mo); break;

    case Op_VecA: // fall-through
    case Op_VecS: // fall-through
    case Op_VecD: // fall-through
    case Op_VecX: // fall-through
    case Op_VecY: // fall-through
    case Op_VecZ: spill = new LoadVectorNode(nullptr, mem, fp, atp, t->is_vect()); break;
    case Op_RegVectMask: return Matcher::predicate_reg_mask();

    default: ShouldNotReachHere();
  }
  MachNode* mspill = match_tree(spill);
  assert(mspill != nullptr || C->failure_is_artificial(), "matching failed: %d", ideal_reg);
  if (C->failing()) {
    return nullptr;
  }
  // Handle generic vector operand case
  if (Matcher::supports_generic_vector_operands && t->isa_vect()) {
    specialize_mach_node(mspill);
  }
  return &mspill->out_RegMask();
}

// Process Mach IR right after selection phase is over.
void Matcher::do_postselect_cleanup() {
  if (supports_generic_vector_operands) {
    specialize_generic_vector_operands();
    if (C->failing())  return;
  }
}

//----------------------------------------------------------------------
// Generic machine operands elision.
//----------------------------------------------------------------------

// Compute concrete vector operand for a generic TEMP vector mach node based on its user info.
void Matcher::specialize_temp_node(MachTempNode* tmp, MachNode* use, uint idx) {
  assert(use->in(idx) == tmp, "not a user");
  assert(!Matcher::is_generic_vector(use->_opnds[0]), "use not processed yet");

  if ((uint)idx == use->two_adr()) { // DEF_TEMP case
    tmp->_opnds[0] = use->_opnds[0]->clone();
  } else {
    uint ideal_vreg = vector_ideal_reg(C->max_vector_size());
    tmp->_opnds[0] = Matcher::pd_specialize_generic_vector_operand(tmp->_opnds[0], ideal_vreg, true /*is_temp*/);
  }
}

// Compute concrete vector operand for a generic DEF/USE vector operand (of mach node m at index idx).
MachOper* Matcher::specialize_vector_operand(MachNode* m, uint opnd_idx) {
  assert(Matcher::is_generic_vector(m->_opnds[opnd_idx]), "repeated updates");
  Node* def = nullptr;
  if (opnd_idx == 0) { // DEF
    def = m; // use mach node itself to compute vector operand type
  } else {
    int base_idx = m->operand_index(opnd_idx);
    def = m->in(base_idx);
    if (def->is_Mach()) {
      if (def->is_MachTemp() && Matcher::is_generic_vector(def->as_Mach()->_opnds[0])) {
        specialize_temp_node(def->as_MachTemp(), m, base_idx); // MachTemp node use site
      } else if (is_reg2reg_move(def->as_Mach())) {
        def = def->in(1); // skip over generic reg-to-reg moves
      }
    }
  }
  assert(def->bottom_type()->isa_vect(), "not a vector");
  uint ideal_vreg = def->bottom_type()->ideal_reg();
  return Matcher::pd_specialize_generic_vector_operand(m->_opnds[opnd_idx], ideal_vreg, false /*is_temp*/);
}

void Matcher::specialize_mach_node(MachNode* m) {
  assert(!m->is_MachTemp(), "processed along with its user");
  // For generic use operands pull specific register class operands from
  // its def instruction's output operand (def operand).
  for (uint i = 0; i < m->num_opnds(); i++) {
    if (Matcher::is_generic_vector(m->_opnds[i])) {
      m->_opnds[i] = specialize_vector_operand(m, i);
    }
  }
}

// Replace generic vector operands with concrete vector operands and eliminate generic reg-to-reg moves from the graph.
void Matcher::specialize_generic_vector_operands() {
  assert(supports_generic_vector_operands, "sanity");
  ResourceMark rm;

  // Replace generic vector operands (vec/legVec) with concrete ones (vec[SDXYZ]/legVec[SDXYZ])
  // and remove reg-to-reg vector moves (MoveVec2Leg and MoveLeg2Vec).
  Unique_Node_List live_nodes;
  C->identify_useful_nodes(live_nodes);

  while (live_nodes.size() > 0) {
    MachNode* m = live_nodes.pop()->isa_Mach();
    if (m != nullptr) {
      if (Matcher::is_reg2reg_move(m)) {
        // Register allocator properly handles vec <=> leg moves using register masks.
        int opnd_idx = m->operand_index(1);
        Node* def = m->in(opnd_idx);
        m->subsume_by(def, C);
      } else if (m->is_MachTemp()) {
        // process MachTemp nodes at use site (see Matcher::specialize_vector_operand)
      } else {
        specialize_mach_node(m);
      }
    }
  }
}

uint Matcher::vector_length(const Node* n) {
  const TypeVect* vt = n->bottom_type()->is_vect();
  return vt->length();
}

uint Matcher::vector_length(const MachNode* use, const MachOper* opnd) {
  int def_idx = use->operand_index(opnd);
  Node* def = use->in(def_idx);
  return def->bottom_type()->is_vect()->length();
}

uint Matcher::vector_length_in_bytes(const Node* n) {
  const TypeVect* vt = n->bottom_type()->is_vect();
  return vt->length_in_bytes();
}

uint Matcher::vector_length_in_bytes(const MachNode* use, const MachOper* opnd) {
  uint def_idx = use->operand_index(opnd);
  Node* def = use->in(def_idx);
  return def->bottom_type()->is_vect()->length_in_bytes();
}

BasicType Matcher::vector_element_basic_type(const Node* n) {
  const TypeVect* vt = n->bottom_type()->is_vect();
  return vt->element_basic_type();
}

BasicType Matcher::vector_element_basic_type(const MachNode* use, const MachOper* opnd) {
  int def_idx = use->operand_index(opnd);
  Node* def = use->in(def_idx);
  return def->bottom_type()->is_vect()->element_basic_type();
}

bool Matcher::is_non_long_integral_vector(const Node* n) {
  BasicType bt = vector_element_basic_type(n);
  assert(bt != T_CHAR, "char is not allowed in vector");
  return is_subword_type(bt) || bt == T_INT;
}

bool Matcher::is_encode_and_store_pattern(const Node* n, const Node* m) {
  if (n == nullptr ||
      m == nullptr ||
      n->Opcode() != Op_StoreN ||
      !m->is_EncodeP() ||
      n->as_Store()->barrier_data() == 0) {
    return false;
  }
  assert(m == n->in(MemNode::ValueIn), "m should be input to n");
  return true;
}

#ifdef ASSERT
bool Matcher::verify_after_postselect_cleanup() {
  assert(!C->failing_internal() || C->failure_is_artificial(), "sanity");
  if (supports_generic_vector_operands) {
    Unique_Node_List useful;
    C->identify_useful_nodes(useful);
    for (uint i = 0; i < useful.size(); i++) {
      MachNode* m = useful.at(i)->isa_Mach();
      if (m != nullptr) {
        assert(!Matcher::is_reg2reg_move(m), "no MoveVec nodes allowed");
        for (uint j = 0; j < m->num_opnds(); j++) {
          assert(!Matcher::is_generic_vector(m->_opnds[j]), "no generic vector operands allowed");
        }
      }
    }
  }
  return true;
}
#endif // ASSERT

// Used by the DFA in dfa_xxx.cpp.  Check for a following barrier or
// atomic instruction acting as a store_load barrier without any
// intervening volatile load, and thus we don't need a barrier here.
// We retain the Node to act as a compiler ordering barrier.
bool Matcher::post_store_load_barrier(const Node* vmb) {
  Compile* C = Compile::current();
  assert(vmb->is_MemBar(), "");
  assert(vmb->Opcode() != Op_MemBarAcquire && vmb->Opcode() != Op_LoadFence, "");
  const MemBarNode* membar = vmb->as_MemBar();

  // Get the Ideal Proj node, ctrl, that can be used to iterate forward
  Node* ctrl = nullptr;
  for (DUIterator_Fast imax, i = membar->fast_outs(imax); i < imax; i++) {
    Node* p = membar->fast_out(i);
    assert(p->is_Proj(), "only projections here");
    if ((p->as_Proj()->_con == TypeFunc::Control) &&
        !C->node_arena()->contains(p)) { // Unmatched old-space only
      ctrl = p;
      break;
    }
  }
  assert((ctrl != nullptr), "missing control projection");

  for (DUIterator_Fast jmax, j = ctrl->fast_outs(jmax); j < jmax; j++) {
    Node *x = ctrl->fast_out(j);
    int xop = x->Opcode();

    // We don't need current barrier if we see another or a lock
    // before seeing volatile load.
    //
    // Op_Fastunlock previously appeared in the Op_* list below.
    // With the advent of 1-0 lock operations we're no longer guaranteed
    // that a monitor exit operation contains a serializing instruction.

    if (xop == Op_MemBarVolatile ||
        xop == Op_CompareAndExchangeB ||
        xop == Op_CompareAndExchangeS ||
        xop == Op_CompareAndExchangeI ||
        xop == Op_CompareAndExchangeL ||
        xop == Op_CompareAndExchangeP ||
        xop == Op_CompareAndExchangeN ||
        xop == Op_WeakCompareAndSwapB ||
        xop == Op_WeakCompareAndSwapS ||
        xop == Op_WeakCompareAndSwapL ||
        xop == Op_WeakCompareAndSwapP ||
        xop == Op_WeakCompareAndSwapN ||
        xop == Op_WeakCompareAndSwapI ||
        xop == Op_CompareAndSwapB ||
        xop == Op_CompareAndSwapS ||
        xop == Op_CompareAndSwapL ||
        xop == Op_CompareAndSwapP ||
        xop == Op_CompareAndSwapN ||
        xop == Op_CompareAndSwapI ||
        BarrierSet::barrier_set()->barrier_set_c2()->matcher_is_store_load_barrier(x, xop)) {
      return true;
    }

    // Op_FastLock previously appeared in the Op_* list above.
    if (xop == Op_FastLock) {
      return true;
    }

    if (x->is_MemBar()) {
      // We must retain this membar if there is an upcoming volatile
      // load, which will be followed by acquire membar.
      if (xop == Op_MemBarAcquire || xop == Op_LoadFence) {
        return false;
      } else {
        // For other kinds of barriers, check by pretending we
        // are them, and seeing if we can be removed.
        return post_store_load_barrier(x->as_MemBar());
      }
    }

    // probably not necessary to check for these
    if (x->is_Call() || x->is_SafePoint() || x->is_block_proj()) {
      return false;
    }
  }
  return false;
}

// Check whether node n is a branch to an uncommon trap that we could
// optimize as test with very high branch costs in case of going to
// the uncommon trap. The code must be able to be recompiled to use
// a cheaper test.
bool Matcher::branches_to_uncommon_trap(const Node *n) {
  // Don't do it for natives, adapters, or runtime stubs
  Compile *C = Compile::current();
  if (!C->is_method_compilation()) return false;

  assert(n->is_If(), "You should only call this on if nodes.");
  IfNode *ifn = n->as_If();

  Node *ifFalse = nullptr;
  for (DUIterator_Fast imax, i = ifn->fast_outs(imax); i < imax; i++) {
    if (ifn->fast_out(i)->is_IfFalse()) {
      ifFalse = ifn->fast_out(i);
      break;
    }
  }
  assert(ifFalse, "An If should have an ifFalse. Graph is broken.");

  Node *reg = ifFalse;
  int cnt = 4; // We must protect against cycles.  Limit to 4 iterations.
               // Alternatively use visited set?  Seems too expensive.
  while (reg != nullptr && cnt > 0) {
    CallNode *call = nullptr;
    RegionNode *nxt_reg = nullptr;
    for (DUIterator_Fast imax, i = reg->fast_outs(imax); i < imax; i++) {
      Node *o = reg->fast_out(i);
      if (o->is_Call()) {
        call = o->as_Call();
      }
      if (o->is_Region()) {
        nxt_reg = o->as_Region();
      }
    }

    if (call &&
        call->entry_point() == OptoRuntime::uncommon_trap_blob()->entry_point()) {
      const Type* trtype = call->in(TypeFunc::Parms)->bottom_type();
      if (trtype->isa_int() && trtype->is_int()->is_con()) {
        jint tr_con = trtype->is_int()->get_con();
        Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
        Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
        assert((int)reason < (int)BitsPerInt, "recode bit map");

        if (is_set_nth_bit(C->allowed_deopt_reasons(), (int)reason)
            && action != Deoptimization::Action_none) {
          // This uncommon trap is sure to recompile, eventually.
          // When that happens, C->too_many_traps will prevent
          // this transformation from happening again.
          return true;
        }
      }
    }

    reg = nxt_reg;
    cnt--;
  }

  return false;
}

//=============================================================================
//---------------------------State---------------------------------------------
State::State(void) : _rule() {
#ifdef ASSERT
  _id = 0;
  _kids[0] = _kids[1] = (State*)(intptr_t) CONST64(0xcafebabecafebabe);
  _leaf = (Node*)(intptr_t) CONST64(0xbaadf00dbaadf00d);
#endif
}

#ifdef ASSERT
State::~State() {
  _id = 99;
  _kids[0] = _kids[1] = (State*)(intptr_t) CONST64(0xcafebabecafebabe);
  _leaf = (Node*)(intptr_t) CONST64(0xbaadf00dbaadf00d);
  memset(_cost, -3, sizeof(_cost));
  memset(_rule, -3, sizeof(_rule));
}
#endif

#ifndef PRODUCT
//---------------------------dump----------------------------------------------
void State::dump() {
  tty->print("\n");
  dump(0);
}

void State::dump(int depth) {
  for (int j = 0; j < depth; j++) {
    tty->print("   ");
  }
  tty->print("--N: ");
  _leaf->dump();
  uint i;
  for (i = 0; i < _LAST_MACH_OPER; i++) {
    // Check for valid entry
    if (valid(i)) {
      for (int j = 0; j < depth; j++) {
        tty->print("   ");
      }
      assert(cost(i) != max_juint, "cost must be a valid value");
      assert(rule(i) < _last_Mach_Node, "rule[i] must be valid rule");
      tty->print_cr("%s  %d  %s",
                    ruleName[i], cost(i), ruleName[rule(i)] );
    }
  }
  tty->cr();

  for (i = 0; i < 2; i++) {
    if (_kids[i]) {
      _kids[i]->dump(depth + 1);
    }
  }
}
#endif
