/*
 * Copyright (c) 1998, 2024, 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.
 *
 */

// FORMS.CPP - Definitions for ADL Parser Forms Classes
#include "adlc.hpp"

//==============================Register Allocation============================
int RegisterForm::_reg_ctr = 0;

//------------------------------RegisterForm-----------------------------------
// Constructor
RegisterForm::RegisterForm()
  : _current_ac(nullptr),
    _regDef(cmpstr,hashstr, Form::arena),
    _regClass(cmpstr,hashstr, Form::arena),
    _allocClass(cmpstr,hashstr, Form::arena) {
}
RegisterForm::~RegisterForm() {
}

// record a new register definition
void RegisterForm::addRegDef(char *name, char *callingConv, char *c_conv,
                             char *idealtype, char *encoding, char* concrete) {
  RegDef *regDef = new RegDef(name, callingConv, c_conv, idealtype, encoding, concrete);
  _rdefs.addName(name);
  _regDef.Insert(name,regDef);
}

// record a new register class
template <typename T>
T* RegisterForm::addRegClass(const char* className) {
  T* regClass = new T(className);
  _rclasses.addName(className);
  _regClass.Insert(className, regClass);
  return regClass;
}

// Explicit instantiation for all supported register classes.
template RegClass* RegisterForm::addRegClass<RegClass>(const char* className);
template CodeSnippetRegClass* RegisterForm::addRegClass<CodeSnippetRegClass>(const char* className);
template ConditionalRegClass* RegisterForm::addRegClass<ConditionalRegClass>(const char* className);

// record a new register class
AllocClass *RegisterForm::addAllocClass(char *className) {
  AllocClass *allocClass = new AllocClass(className);
  _aclasses.addName(className);
  _allocClass.Insert(className,allocClass);
  return allocClass;
}

// Called after parsing the Register block.  Record the register class
// for spill-slots/regs.
void RegisterForm::addSpillRegClass() {
  // Stack slots start at the next available even register number.
  _reg_ctr = (_reg_ctr+7) & ~7;
  const char *rc_name = "stack_slots";
  RegClass* reg_class = new RegClass(rc_name);
  reg_class->set_stack_version(true);
  _rclasses.addName(rc_name);
  _regClass.Insert(rc_name,reg_class);
}

// Called after parsing the Register block.  Record the register class
// for operands which are overwritten after matching.
void RegisterForm::addDynamicRegClass() {
  const char *rc_name = "dynamic";
  RegClass* reg_class = new RegClass(rc_name);
  reg_class->set_stack_version(false);
  _rclasses.addName(rc_name);
  _regClass.Insert(rc_name,reg_class);
}

// Provide iteration over all register definitions
// in the order used by the register allocator
void        RegisterForm::reset_RegDefs() {
  _current_ac = nullptr;
  _aclasses.reset();
}

RegDef     *RegisterForm::iter_RegDefs() {
  // Check if we need to get the next AllocClass
  if ( _current_ac == nullptr ) {
    const char *ac_name = _aclasses.iter();
    if( ac_name == nullptr )   return nullptr;   // No more allocation classes
    _current_ac = (AllocClass*)_allocClass[ac_name];
    _current_ac->_regDefs.reset();
    assert( _current_ac != nullptr, "Name must match an allocation class");
  }

  const char *rd_name = _current_ac->_regDefs.iter();
  if( rd_name == nullptr ) {
    // At end of this allocation class, check the next
    _current_ac = nullptr;
    return iter_RegDefs();
  }
  RegDef *reg_def = (RegDef*)_current_ac->_regDef[rd_name];
  assert( reg_def != nullptr, "Name must match a register definition");
  return reg_def;
}

// return the register definition with name 'regName'
RegDef *RegisterForm::getRegDef(const char *regName) {
  RegDef *regDef = (RegDef*)_regDef[regName];
  return  regDef;
}

// return the register class with name 'className'
RegClass *RegisterForm::getRegClass(const char *className) {
  RegClass *regClass = (RegClass*)_regClass[className];
  return    regClass;
}


// Check that register classes are compatible with chunks
bool   RegisterForm::verify() {
  bool valid = true;

  // Verify Register Classes
  // check that each register class contains registers from one chunk
  const char *rc_name = nullptr;
  _rclasses.reset();
  while ( (rc_name = _rclasses.iter()) != nullptr ) {
    // Check the chunk value for all registers in this class
    RegClass *reg_class = getRegClass(rc_name);
    assert( reg_class != nullptr, "InternalError() no matching register class");
  } // end of RegClasses

  // Verify that every register has been placed into an allocation class
  RegDef *reg_def = nullptr;
  reset_RegDefs();
  uint  num_register_zero = 0;
  while ( (reg_def = iter_RegDefs()) != nullptr ) {
    if( reg_def->register_num() == 0 )  ++num_register_zero;
  }
  if( num_register_zero > 1 ) {
    fprintf(stderr,
            "ERROR: More than one register has been assigned register-number 0.\n"
            "Probably because a register has not been entered into an allocation class.\n");
  }

  return  valid;
}

// Compute RegMask size
int RegisterForm::RegMask_Size() {
  // Need at least this many words
  int words_for_regs = (_reg_ctr + 31)>>5;
  // The array of Register Mask bits should be large enough to cover
  // all the machine registers and all parameters that need to be passed
  // on the stack (stack registers) up to some interesting limit.  Methods
  // that need more parameters will NOT be compiled.  On Intel, the limit
  // is something like 90+ parameters.
  // - Add a few (3 words == 96 bits) for incoming & outgoing arguments to
  //   calls.
  // - Round up to the next doubleword size.
  // - Add one more word to accommodate a reasonable number of stack locations
  //   in the register mask regardless of how much slack is created by rounding.
  //   This was found necessary after adding 16 new registers for APX.
  return (words_for_regs + 3 + 1 + 1) & ~1;
}

void RegisterForm::dump() {                  // Debug printer
  output(stderr);
}

void RegisterForm::output(FILE *fp) {          // Write info to output files
  const char *name;
  fprintf(fp,"\n");
  fprintf(fp,"-------------------- Dump RegisterForm --------------------\n");
  for(_rdefs.reset(); (name = _rdefs.iter()) != nullptr;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"\n");
  for (_rclasses.reset(); (name = _rclasses.iter()) != nullptr;) {
    ((RegClass*)_regClass[name])->output(fp);
  }
  fprintf(fp,"\n");
  for (_aclasses.reset(); (name = _aclasses.iter()) != nullptr;) {
    ((AllocClass*)_allocClass[name])->output(fp);
  }
  fprintf(fp,"-------------------- end  RegisterForm --------------------\n");
}

void RegisterForm::forms_do(FormClosure *f) {
  const char *name = nullptr;
  if (_current_ac) f->do_form(_current_ac);
  for(_rdefs.reset(); (name = _rdefs.iter()) != nullptr;) {
    f->do_form((RegDef*)_regDef[name]);
  }
  for (_rclasses.reset(); (name = _rclasses.iter()) != nullptr;) {
    f->do_form((RegClass*)_regClass[name]);
  }
  for (_aclasses.reset(); (name = _aclasses.iter()) != nullptr;) {
    f->do_form((AllocClass*)_allocClass[name]);
  }
}

//------------------------------RegDef-----------------------------------------
// Constructor
RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, char * encode, char * concrete)
  : _regname(regname), _callconv(callconv), _c_conv(c_conv),
    _idealtype(idealtype),
    _register_encode(encode),
    _concrete(concrete),
    _register_num(0) {

  // AdlChunk and register mask are determined by the register number
  // _register_num is set when registers are added to an allocation class
}
RegDef::~RegDef() {                      // Destructor
}

void RegDef::set_register_num(uint32 register_num) {
  _register_num      = register_num;
}

// Bit pattern used for generating machine code
const char* RegDef::register_encode() const {
  return _register_encode;
}

// Register number used in machine-independent code
uint32 RegDef::register_num()    const {
  return _register_num;
}

void RegDef::dump() {
  output(stderr);
}

void RegDef::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"RegDef: %s (%s) encode as %s  using number %d\n",
          _regname, (_callconv?_callconv:""), _register_encode, _register_num);
  fprintf(fp,"\n");
}


//------------------------------RegClass---------------------------------------
// Construct a register class into which registers will be inserted
RegClass::RegClass(const char* classid) : _stack_or_reg(false), _classid(classid), _regDef(cmpstr, hashstr, Form::arena) {
}

RegClass::~RegClass() {
}

// record a register in this class
void RegClass::addReg(RegDef *regDef) {
  _regDefs.addName(regDef->_regname);
  _regDef.Insert((void*)regDef->_regname, regDef);
}

// Number of registers in class
uint RegClass::size() const {
  return _regDef.Size();
}

const RegDef *RegClass::get_RegDef(const char *rd_name) const {
  return  (const RegDef*)_regDef[rd_name];
}

void RegClass::reset() {
  _regDefs.reset();
}

const char *RegClass::rd_name_iter() {
  return _regDefs.iter();
}

RegDef *RegClass::RegDef_iter() {
  const char *rd_name  = rd_name_iter();
  RegDef     *reg_def  = rd_name ? (RegDef*)_regDef[rd_name] : nullptr;
  return      reg_def;
}

const RegDef* RegClass::find_first_elem() {
  const RegDef* first = nullptr;
  const RegDef* def = nullptr;

  reset();
  while ((def = RegDef_iter()) != nullptr) {
    if (first == nullptr || def->register_num() < first->register_num()) {
      first = def;
    }
  }

  assert(first != nullptr, "empty mask?");
  return first;;
}

// Collect all the registers in this register-word.  One bit per register.
int RegClass::regs_in_word( int wordnum, bool stack_also ) {
  int         word = 0;
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
    int rnum = ((RegDef*)_regDef[name])->register_num();
    if( (rnum >> 5) == wordnum )
      word |= (1 << (rnum & 31));
  }
  if( stack_also ) {
    // Now also collect stack bits
    for( int i = 0; i < 32; i++ )
      if( wordnum*32+i >= RegisterForm::_reg_ctr )
        word |= (1 << i);
  }

  return word;
}

void RegClass::dump() {
  output(stderr);
}

void RegClass::output(FILE *fp) {           // Write info to output files
  fprintf(fp,"RegClass: %s\n",_classid);
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"--- done with entries for reg_class %s\n\n",_classid);
}

void RegClass::forms_do(FormClosure *f) {
  const char *name = nullptr;
  for( _regDefs.reset(); (name = _regDefs.iter()) != nullptr; ) {
    f->do_form((RegDef*)_regDef[name]);
  }
}

void RegClass::declare_register_masks(FILE* fp) {
  const char* prefix = "";
  const char* rc_name_to_upper = toUpper(_classid);
  fprintf(fp, "extern const RegMask _%s%s_mask;\n", prefix,  rc_name_to_upper);
  fprintf(fp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
  if (_stack_or_reg) {
    fprintf(fp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, rc_name_to_upper);
    fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, rc_name_to_upper, prefix, rc_name_to_upper);
  }
  delete[] rc_name_to_upper;
}

void RegClass::build_register_masks(FILE* fp) {
  int len = RegisterForm::RegMask_Size();
  const char *prefix = "";
  const char* rc_name_to_upper = toUpper(_classid);
  fprintf(fp, "const RegMask _%s%s_mask(", prefix, rc_name_to_upper);

  int i;
  for(i = 0; i < len - 1; i++) {
    fprintf(fp," 0x%x,", regs_in_word(i, false));
  }
  fprintf(fp," 0x%x );\n", regs_in_word(i, false));

  if (_stack_or_reg) {
    fprintf(fp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, rc_name_to_upper);
    for(i = 0; i < len - 1; i++) {
      fprintf(fp," 0x%x,", regs_in_word(i, true));
    }
    fprintf(fp," 0x%x );\n", regs_in_word(i, true));
  }
  delete[] rc_name_to_upper;
}

//------------------------------CodeSnippetRegClass---------------------------
CodeSnippetRegClass::CodeSnippetRegClass(const char* classid) : RegClass(classid), _code_snippet(nullptr) {
}

CodeSnippetRegClass::~CodeSnippetRegClass() {
  delete _code_snippet;
}

void CodeSnippetRegClass::declare_register_masks(FILE* fp) {
  const char* prefix = "";
  const char* rc_name_to_upper = toUpper(_classid);
  fprintf(fp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, rc_name_to_upper, _code_snippet);
  delete[] rc_name_to_upper;
}

//------------------------------ConditionalRegClass---------------------------
ConditionalRegClass::ConditionalRegClass(const char *classid) : RegClass(classid), _condition_code(nullptr) {
    _rclasses[0] = nullptr;
    _rclasses[1] = nullptr;
}

ConditionalRegClass::~ConditionalRegClass() {
  delete _condition_code;
}

void ConditionalRegClass::declare_register_masks(FILE* fp) {
  const char* prefix = "";
  const char* rc_name_to_upper = toUpper(_classid);
  const char* rclass_0_to_upper = toUpper(_rclasses[0]->_classid);
  const char* rclass_1_to_upper = toUpper(_rclasses[1]->_classid);
  fprintf(fp, "inline const RegMask &%s%s_mask() {"
              " return (%s) ?"
              " %s%s_mask() :"
              " %s%s_mask(); }\n",
              prefix, rc_name_to_upper,
              _condition_code,
              prefix, rclass_0_to_upper,
              prefix, rclass_1_to_upper);
  if (_stack_or_reg) {
    fprintf(fp, "inline const RegMask &%sSTACK_OR_%s_mask() {"
                  " return (%s) ?"
                  " %sSTACK_OR_%s_mask() :"
                  " %sSTACK_OR_%s_mask(); }\n",
                  prefix, rc_name_to_upper,
                  _condition_code,
                  prefix, rclass_0_to_upper,
                  prefix, rclass_1_to_upper);
  }
  delete[] rc_name_to_upper;
  delete[] rclass_0_to_upper;
  delete[] rclass_1_to_upper;
  return;
}

//------------------------------AllocClass-------------------------------------
AllocClass::AllocClass(char *classid) : _classid(classid), _regDef(cmpstr,hashstr, Form::arena) {
}

// record a register in this class
void AllocClass::addReg(RegDef *regDef) {
  assert( regDef != nullptr, "Can not add a null to an allocation class");
  regDef->set_register_num( RegisterForm::_reg_ctr++ );
  // Add regDef to this allocation class
  _regDefs.addName(regDef->_regname);
  _regDef.Insert((void*)regDef->_regname, regDef);
}

void AllocClass::dump() {
  output(stderr);
}

void AllocClass::output(FILE *fp) {       // Write info to output files
  fprintf(fp,"AllocClass: %s \n",_classid);
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
    ((RegDef*)_regDef[name])->output(fp);
  }
  fprintf(fp,"--- done with entries for alloc_class %s\n\n",_classid);
}

void AllocClass::forms_do(FormClosure* f) {
  const char *name;
  for(_regDefs.reset(); (name = _regDefs.iter()) != nullptr;) {
    f->do_form((RegDef*)_regDef[name]);
  }
  return;
}

//==============================Frame Handling=================================
//------------------------------FrameForm--------------------------------------
FrameForm::FrameForm() {
  _sync_stack_slots = nullptr;
  _inline_cache_reg = nullptr;
  _interpreter_frame_pointer_reg = nullptr;
  _cisc_spilling_operand_name = nullptr;
  _frame_pointer = nullptr;
  _c_frame_pointer = nullptr;
  _alignment = nullptr;
  _return_addr_loc = false;
  _c_return_addr_loc = false;
  _return_addr = nullptr;
  _c_return_addr = nullptr;
  _varargs_C_out_slots_killed = nullptr;
  _return_value = nullptr;
  _c_return_value = nullptr;
}

FrameForm::~FrameForm() {
}

void FrameForm::dump() {
  output(stderr);
}

void FrameForm::output(FILE *fp) {           // Write info to output files
  fprintf(fp,"\nFrame:\n");
}

//==============================Scheduling=====================================
//------------------------------PipelineForm-----------------------------------
PipelineForm::PipelineForm()
  :  _reslist               ()
  ,  _resdict               (cmpstr, hashstr, Form::arena)
  ,  _classdict             (cmpstr, hashstr, Form::arena)
  ,  _rescount              (0)
  ,  _maxcycleused          (0)
  ,  _stages                ()
  ,  _stagecnt              (0)
  ,  _classlist             ()
  ,  _classcnt              (0)
  ,  _noplist               ()
  ,  _nopcnt                (0)
  ,  _variableSizeInstrs    (false)
  ,  _branchHasDelaySlot    (false)
  ,  _maxInstrsPerBundle    (0)
  ,  _maxBundlesPerCycle    (1)
  ,  _instrUnitSize         (0)
  ,  _bundleUnitSize        (0)
  ,  _instrFetchUnitSize    (0)
  ,  _instrFetchUnits       (0) {
}
PipelineForm::~PipelineForm() {
}

void PipelineForm::dump() {
  output(stderr);
}

void PipelineForm::output(FILE *fp) {           // Write info to output files
  const char *res;
  const char *stage;
  const char *cls;
  const char *nop;
  int count = 0;

  fprintf(fp,"\nPipeline:");
  if (_variableSizeInstrs)
    if (_instrUnitSize > 0)
      fprintf(fp," variable-sized instructions in %d byte units", _instrUnitSize);
    else
      fprintf(fp," variable-sized instructions");
  else
    if (_instrUnitSize > 0)
      fprintf(fp," fixed-sized instructions of %d bytes", _instrUnitSize);
    else if (_bundleUnitSize > 0)
      fprintf(fp," fixed-sized bundles of %d bytes", _bundleUnitSize);
    else
      fprintf(fp," fixed-sized instructions");
  if (_branchHasDelaySlot)
    fprintf(fp,", branch has delay slot");
  if (_maxInstrsPerBundle > 0)
    fprintf(fp,", max of %d instruction%s in parallel",
      _maxInstrsPerBundle, _maxInstrsPerBundle > 1 ? "s" : "");
  if (_maxBundlesPerCycle > 0)
    fprintf(fp,", max of %d bundle%s in parallel",
      _maxBundlesPerCycle, _maxBundlesPerCycle > 1 ? "s" : "");
  if (_instrFetchUnitSize > 0 && _instrFetchUnits)
    fprintf(fp, ", fetch %d x % d bytes per cycle", _instrFetchUnits, _instrFetchUnitSize);

  fprintf(fp,"\nResource:");
  for ( _reslist.reset(); (res = _reslist.iter()) != nullptr; )
    fprintf(fp," %s(0x%08x)", res, _resdict[res]->is_resource()->mask());
  fprintf(fp,"\n");

  fprintf(fp,"\nDescription:\n");
  for ( _stages.reset(); (stage = _stages.iter()) != nullptr; )
    fprintf(fp," %s(%d)", stage, count++);
  fprintf(fp,"\n");

  fprintf(fp,"\nClasses:\n");
  for ( _classlist.reset(); (cls = _classlist.iter()) != nullptr; )
    _classdict[cls]->is_pipeclass()->output(fp);

  fprintf(fp,"\nNop Instructions:");
  for ( _noplist.reset(); (nop = _noplist.iter()) != nullptr; )
    fprintf(fp, " \"%s\"", nop);
  fprintf(fp,"\n");
}


//------------------------------ResourceForm-----------------------------------
ResourceForm::ResourceForm(unsigned resmask)
: _resmask(resmask) {
}
ResourceForm::~ResourceForm() {
}

ResourceForm  *ResourceForm::is_resource() const {
  return (ResourceForm *)(this);
}

void ResourceForm::dump() {
  output(stderr);
}

void ResourceForm::output(FILE *fp) {          // Write info to output files
  fprintf(fp, "resource: 0x%08x;\n", mask());
}


//------------------------------PipeClassOperandForm----------------------------------

void PipeClassOperandForm::dump() {
  output(stderr);
}

void PipeClassOperandForm::output(FILE *fp) {         // Write info to output files
  fprintf(stderr,"PipeClassOperandForm: %s", _stage);
  fflush(stderr);
  if (_more_instrs > 0)
    fprintf(stderr,"+%d", _more_instrs);
  fprintf(stderr," (%s)\n", _iswrite ? "write" : "read");
  fflush(stderr);
  fprintf(fp,"PipeClassOperandForm: %s", _stage);
  if (_more_instrs > 0)
    fprintf(fp,"+%d", _more_instrs);
  fprintf(fp," (%s)\n", _iswrite ? "write" : "read");
}


//------------------------------PipeClassResourceForm----------------------------------

void PipeClassResourceForm::dump() {
  output(stderr);
}

void PipeClassResourceForm::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"PipeClassResourceForm: %s at stage %s for %d cycles\n",
     _resource, _stage, _cycles);
}


//------------------------------PipeClassForm----------------------------------
PipeClassForm::PipeClassForm(const char *id, int num)
  : _ident(id)
  , _num(num)
  , _localNames(cmpstr, hashstr, Form::arena)
  , _localUsage(cmpstr, hashstr, Form::arena)
  , _has_fixed_latency(0)
  , _fixed_latency(0)
  , _instruction_count(0)
  , _has_multiple_bundles(false)
  , _has_branch_delay_slot(false)
  , _force_serialization(false)
  , _may_have_no_code(false) {
}

PipeClassForm::~PipeClassForm() {
}

PipeClassForm  *PipeClassForm::is_pipeclass() const {
  return (PipeClassForm *)(this);
}

void PipeClassForm::dump() {
  output(stderr);
}

void PipeClassForm::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"PipeClassForm: #%03d", _num);
  if (_ident)
     fprintf(fp," \"%s\":", _ident);
  if (_has_fixed_latency)
     fprintf(fp," latency %d", _fixed_latency);
  if (_force_serialization)
     fprintf(fp, ", force serialization");
  if (_may_have_no_code)
     fprintf(fp, ", may have no code");
  fprintf(fp, ", %d instruction%s\n", InstructionCount(), InstructionCount() != 1 ? "s" : "");
}


//==============================Peephole Optimization==========================
int Peephole::_peephole_counter = 0;
//------------------------------Peephole---------------------------------------
Peephole::Peephole() : _predicate(nullptr), _match(nullptr), _procedure(nullptr),
                       _constraint(nullptr), _replace(nullptr), _next(nullptr) {
  _peephole_number = _peephole_counter++;
}
Peephole::~Peephole() {
}

// Append a peephole rule with the same root instruction
void Peephole::append_peephole(Peephole *next_peephole) {
  if( _next == nullptr ) {
    _next = next_peephole;
  } else {
    _next->append_peephole( next_peephole );
  }
}

// Add a predicate to this peephole rule
void Peephole::add_predicate(PeepPredicate* predicate) {
  assert( _predicate == nullptr, "fatal()" );
  _predicate = predicate;
}

// Store the components of this peephole rule
void Peephole::add_match(PeepMatch *match) {
  assert( _match == nullptr, "fatal()" );
  _match = match;
}

// Add a procedure to this peephole rule
void Peephole::add_procedure(PeepProcedure* procedure) {
  assert( _procedure == nullptr, "fatal()" );
  _procedure = procedure;
}

void Peephole::append_constraint(PeepConstraint *next_constraint) {
  if( _constraint == nullptr ) {
    _constraint = next_constraint;
  } else {
    _constraint->append( next_constraint );
  }
}

void Peephole::add_replace(PeepReplace *replace) {
  assert( _replace == nullptr, "fatal()" );
  _replace = replace;
}

// class Peephole accessor methods are in the declaration.


void Peephole::dump() {
  output(stderr);
}

void Peephole::output(FILE *fp) {         // Write info to output files
  fprintf(fp,"Peephole:\n");
  if( _match != nullptr )       _match->output(fp);
  if( _constraint != nullptr )  _constraint->output(fp);
  if( _replace != nullptr )     _replace->output(fp);
  // Output the next entry
  if( _next ) _next->output(fp);
}

void Peephole::forms_do(FormClosure *f) {
  if (_predicate) f->do_form(_predicate);
  if (_match) f->do_form(_match);
  if (_procedure) f->do_form(_procedure);
  if (_constraint) f->do_form(_constraint);
  if (_replace) f->do_form(_replace);
  return;
}

//----------------------------PeepPredicate------------------------------------
PeepPredicate::PeepPredicate(const char* rule) : _rule(rule) {
}
PeepPredicate::~PeepPredicate() {
}

const char* PeepPredicate::rule() const {
  return _rule;
}

void PeepPredicate::dump() {
  output(stderr);
}

void PeepPredicate::output(FILE* fp) {
  fprintf(fp, "PeepPredicate\n");
}

//------------------------------PeepMatch--------------------------------------
PeepMatch::PeepMatch(char *rule) : _max_position(0), _rule(rule) {
}
PeepMatch::~PeepMatch() {
}

// Insert info into the match-rule
void  PeepMatch::add_instruction(int parent, int position, const char *name,
                                 int input) {
  if( position > _max_position ) _max_position = position;

  _parent.addName((char*) (intptr_t) parent);
  _position.addName((char*) (intptr_t) position);
  _instrs.addName(name);
  _input.addName((char*) (intptr_t) input);
}

// Access info about instructions in the peep-match rule
int   PeepMatch::max_position() {
  return _max_position;
}

const char *PeepMatch::instruction_name(int position) {
  return _instrs.name(position);
}

// Iterate through all info on matched instructions
void  PeepMatch::reset() {
  _parent.reset();
  _position.reset();
  _instrs.reset();
  _input.reset();
}

void  PeepMatch::next_instruction(int &parent, int &position, const char* &name, int &input) {
  parent   = (int) (intptr_t) _parent.iter();
  position = (int) (intptr_t) _position.iter();
  name     = _instrs.iter();
  input    = (int) (intptr_t) _input.iter();
}

// 'true' if current position in iteration is a placeholder, not matched.
bool  PeepMatch::is_placeholder() {
  return _instrs.current_is_signal();
}


void PeepMatch::dump() {
  output(stderr);
}

void PeepMatch::output(FILE *fp) {        // Write info to output files
  fprintf(fp,"PeepMatch:\n");
}

//----------------------------PeepProcedure------------------------------------
PeepProcedure::PeepProcedure(const char* name) : _name(name) {
}
PeepProcedure::~PeepProcedure() {
}

const char* PeepProcedure::name() const {
  return _name;
}

void PeepProcedure::dump() {
  output(stderr);
}

void PeepProcedure::output(FILE* fp) {
  fprintf(fp, "PeepProcedure\n");
}

//------------------------------PeepConstraint---------------------------------
PeepConstraint::PeepConstraint(int left_inst,  char* left_op, char* relation,
                               int right_inst, char* right_op)
  : _left_inst(left_inst), _left_op(left_op), _relation(relation),
    _right_inst(right_inst), _right_op(right_op), _next(nullptr) {}
PeepConstraint::~PeepConstraint() {
}

// Check if constraints use instruction at position
bool PeepConstraint::constrains_instruction(int position) {
  // Check local instruction constraints
  if( _left_inst  == position ) return true;
  if( _right_inst == position ) return true;

  // Check remaining constraints in list
  if( _next == nullptr )  return false;
  else                 return _next->constrains_instruction(position);
}

// Add another constraint
void PeepConstraint::append(PeepConstraint *next_constraint) {
  if( _next == nullptr ) {
    _next = next_constraint;
  } else {
    _next->append( next_constraint );
  }
}

// Access the next constraint in the list
PeepConstraint *PeepConstraint::next() {
  return _next;
}


void PeepConstraint::dump() {
  output(stderr);
}

void PeepConstraint::output(FILE *fp) {   // Write info to output files
  fprintf(fp,"PeepConstraint:\n");
}

//------------------------------PeepReplace------------------------------------
PeepReplace::PeepReplace(char *rule) : _rule(rule) {
}
PeepReplace::~PeepReplace() {
}

// Add contents of peepreplace
void  PeepReplace::add_instruction(char *root) {
  _instruction.addName(root);
  _operand_inst_num.add_signal();
  _operand_op_name.add_signal();
}
void  PeepReplace::add_operand( int inst_num, char *inst_operand ) {
  _instruction.add_signal();
  _operand_inst_num.addName((char*) (intptr_t) inst_num);
  _operand_op_name.addName(inst_operand);
}

// Access contents of peepreplace
void  PeepReplace::reset() {
  _instruction.reset();
  _operand_inst_num.reset();
  _operand_op_name.reset();
}
void  PeepReplace::next_instruction(const char* &inst){
  inst                     = _instruction.iter();
  int         inst_num     = (int) (intptr_t) _operand_inst_num.iter();
  const char* inst_operand = _operand_op_name.iter();
}
void  PeepReplace::next_operand(int &inst_num, const char* &inst_operand) {
  const char* inst = _instruction.iter();
  inst_num         = (int) (intptr_t) _operand_inst_num.iter();
  inst_operand     = _operand_op_name.iter();
}



void PeepReplace::dump() {
  output(stderr);
}

void PeepReplace::output(FILE *fp) {      // Write info to output files
  fprintf(fp,"PeepReplace:\n");
}
