/*
 * 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.
 *
 */

// DFA.CPP - Method definitions for outputting the matcher DFA from ADLC
#include "adlc.hpp"

//---------------------------Switches for debugging output---------------------
static bool debug_output   = false;
static bool debug_output1  = false;    // top level chain rules

//---------------------------Production State----------------------------------
static const char *knownInvalid = "knownInvalid";    // The result does NOT have a rule defined
static const char *knownValid   = "knownValid";      // The result must be produced by a rule
static const char *unknownValid = "unknownValid";    // Unknown (probably due to a child or predicate constraint)

static const char *noConstraint  = "noConstraint";   // No constraints seen so far
static const char *hasConstraint = "hasConstraint";  // Within the first constraint


//------------------------------Production------------------------------------
// Track the status of productions for a particular result
class Production {
public:
  const char *_result;
  const char *_constraint;
  const char *_valid;
  Expr       *_cost_lb;            // Cost lower bound for this production
  Expr       *_cost_ub;            // Cost upper bound for this production

public:
  Production(const char *result, const char *constraint, const char *valid);
  ~Production() {};

  void        initialize();        // reset to be an empty container

  const char   *valid()  const { return _valid; }
  Expr       *cost_lb()  const { return (Expr *)_cost_lb;  }
  Expr       *cost_ub()  const { return (Expr *)_cost_ub;  }

  void print();
};


//------------------------------ProductionState--------------------------------
// Track the status of all production rule results
// Reset for each root opcode (e.g., Op_RegI, Op_AddI, ...)
class ProductionState {
private:
  Dict _production;    // map result of production, char*, to information or null
  const char *_constraint;

public:
  // cmpstr does string comparisons.  hashstr computes a key.
  ProductionState(AdlArena *arena) : _production(cmpstr, hashstr, arena) { initialize(); };
  ~ProductionState() { };

  void        initialize();                // reset local and dictionary state

  const char *constraint();
  void    set_constraint(const char *constraint); // currently working inside of constraints

  const char *valid(const char *result);   // unknownValid, or status for this production
  void    set_valid(const char *result);   // if not constrained, set status to knownValid

  Expr           *cost_lb(const char *result);
  Expr           *cost_ub(const char *result);
  void    set_cost_bounds(const char *result, const Expr *cost, bool has_state_check, bool has_cost_check);

  // Return the Production associated with the result,
  // or create a new Production and insert it into the dictionary.
  Production *getProduction(const char *result);

  void print();

private:
    // Disable public use of constructor, copy-ctor,  ...
  ProductionState( )                         : _production(cmpstr, hashstr, Form::arena) {  assert( false, "NotImplemented");  };
  ProductionState( const ProductionState & ) : _production(cmpstr, hashstr, Form::arena) {  assert( false, "NotImplemented");  }; // Deep-copy
};


//---------------------------Helper Functions----------------------------------
// cost_check template:
// 1)      if (STATE__NOT_YET_VALID(EBXREGI) || _cost[EBXREGI] > c) {
// 2)        DFA_PRODUCTION(EBXREGI, cmovI_memu_rule, c)
// 3)      }
//
static void cost_check(FILE *fp, const char *spaces,
                       const char *arrayIdx, const Expr *cost, const char *rule, ProductionState &status) {
  bool state_check               = false;  // true if this production needs to check validity
  bool cost_check                = false;  // true if this production needs to check cost
  bool cost_is_above_upper_bound = false;  // true if this production is unnecessary due to high cost
  bool cost_is_below_lower_bound = false;  // true if this production replaces a higher cost production

  // Get information about this production
  const Expr *previous_ub = status.cost_ub(arrayIdx);
  if( !previous_ub->is_unknown() ) {
    if( previous_ub->less_than_or_equal(cost) ) {
      cost_is_above_upper_bound = true;
      if( debug_output ) { fprintf(fp, "// Previous rule with lower cost than: %s === %s_rule costs %s\n", arrayIdx, rule, cost->as_string()); }
    }
  }

  const Expr *previous_lb = status.cost_lb(arrayIdx);
  if( !previous_lb->is_unknown() ) {
    if( cost->less_than_or_equal(previous_lb) ) {
      cost_is_below_lower_bound = true;
      if( debug_output ) { fprintf(fp, "// Previous rule with higher cost\n"); }
    }
  }

  // line 1)
  // Check for validity and compare to other match costs
  const char *validity_check = status.valid(arrayIdx);
  if( validity_check == unknownValid ) {
    fprintf(fp, "%sif (STATE__NOT_YET_VALID(%s) || _cost[%s] > %s) {\n",  spaces, arrayIdx, arrayIdx, cost->as_string());
    state_check = true;
    cost_check  = true;
  }
  else if( validity_check == knownInvalid ) {
    if( debug_output ) { fprintf(fp, "%s// %s KNOWN_INVALID \n",  spaces, arrayIdx); }
  }
  else if( validity_check == knownValid ) {
    if( cost_is_above_upper_bound ) {
      // production cost is known to be too high.
      return;
    } else if( cost_is_below_lower_bound ) {
      // production will unconditionally overwrite a previous production that had higher cost
    } else {
      fprintf(fp, "%sif ( /* %s KNOWN_VALID || */ _cost[%s] > %s) {\n",  spaces, arrayIdx, arrayIdx, cost->as_string());
      cost_check  = true;
    }
  }

  // line 2)
  fprintf(fp, "%s  DFA_PRODUCTION(%s, %s_rule, %s)", spaces, arrayIdx, rule, cost->as_string() );
  if (validity_check == knownValid) {
    if (cost_is_below_lower_bound) {
      fprintf(fp, "\t  // overwrites higher cost rule");
    }
  }
  fprintf(fp, "\n");

  // line 3)
  if( cost_check || state_check ) {
    fprintf(fp, "%s}\n", spaces);
  }

  status.set_cost_bounds(arrayIdx, cost, state_check, cost_check);

  // Update ProductionState
  if( validity_check != knownValid ) {
    // set State vector if not previously known
    status.set_valid(arrayIdx);
  }
}


//---------------------------child_test----------------------------------------
// Example:
//   STATE__VALID_CHILD(_kids[0], FOO) &&  STATE__VALID_CHILD(_kids[1], BAR)
// Macro equivalent to: _kids[0]->valid(FOO) && _kids[1]->valid(BAR)
//
static void child_test(FILE *fp, MatchList &mList, bool is_vector_unary_op) {
  if (mList._lchild) { // If left child, check it
    const char* lchild_to_upper = ArchDesc::getMachOperEnum(mList._lchild);
    fprintf(fp, "STATE__VALID_CHILD(_kids[0], %s)", lchild_to_upper);
    delete[] lchild_to_upper;

    if (mList._rchild) { // If both, add the "&&"
      fprintf(fp, " && ");
    } else if (is_vector_unary_op) {
      // If unpredicated vector unary operation, add one extra check, i.e. right
      // child should be null, to distinguish from the predicated version.
      fprintf(fp, " && _kids[1] == nullptr");
    }
  }
  if (mList._rchild) { // If right child, check it
    const char* rchild_to_upper = ArchDesc::getMachOperEnum(mList._rchild);
    fprintf(fp, "STATE__VALID_CHILD(_kids[1], %s)", rchild_to_upper);
    delete[] rchild_to_upper;
  }
}

//---------------------------calc_cost-----------------------------------------
// Example:
//           unsigned int c = _kids[0]->_cost[FOO] + _kids[1]->_cost[BAR] + 5;
//
Expr *ArchDesc::calc_cost(FILE *fp, const char *spaces, MatchList &mList, ProductionState &status) {
  fprintf(fp, "%sunsigned int c = ", spaces);
  Expr *c = new Expr("0");
  if (mList._lchild) { // If left child, add it in
    const char* lchild_to_upper = ArchDesc::getMachOperEnum(mList._lchild);
    snprintf_checked(Expr::buffer(), STRING_BUFFER_LENGTH, "_kids[0]->_cost[%s]", lchild_to_upper);
    c->add(Expr::buffer());
    delete[] lchild_to_upper;
}
  if (mList._rchild) { // If right child, add it in
    const char* rchild_to_upper = ArchDesc::getMachOperEnum(mList._rchild);
    snprintf_checked(Expr::buffer(), STRING_BUFFER_LENGTH, "_kids[1]->_cost[%s]", rchild_to_upper);
    c->add(Expr::buffer());
    delete[] rchild_to_upper;
  }
  // Add in cost of this rule
  const char *mList_cost = mList.get_cost();
  c->add(mList_cost, *this);

  fprintf(fp, "%s;\n", c->as_string());
  c->set_external_name("c");
  return c;
}


//---------------------------gen_match-----------------------------------------
void ArchDesc::gen_match(FILE *fp, MatchList &mList, ProductionState &status,
                         Dict &operands_chained_from, bool is_vector_unary_op) {
  const char *spaces4 = "    ";
  const char *spaces6 = "      ";

  fprintf(fp, "%s", spaces4);
  // Only generate child tests if this is not a leaf node
  bool has_child_constraints = mList._lchild || mList._rchild;
  const char *predicate_test = mList.get_pred();
  if (has_child_constraints || predicate_test) {
    // Open the child-and-predicate-test braces
    fprintf(fp, "if( ");
    status.set_constraint(hasConstraint);
    child_test(fp, mList, is_vector_unary_op);
    // Only generate predicate test if one exists for this match
    if (predicate_test) {
      if (has_child_constraints) {
        fprintf(fp," &&\n");
      }
      fprintf(fp, "%s  %s", spaces6, predicate_test);
    }
    // End of outer tests
    fprintf(fp," ) ");
  } else {
    // No child or predicate test needed
    status.set_constraint(noConstraint);
  }

  // End of outer tests
  fprintf(fp,"{\n");

  // Calculate cost of this match
  const Expr *cost = calc_cost(fp, spaces6, mList, status);
  // Check against other match costs, and update cost & rule vectors
  cost_check(fp, spaces6, ArchDesc::getMachOperEnum(mList._resultStr), cost, mList._opcode, status);

  // If this is a member of an operand class, update the class cost & rule
  expand_opclass( fp, spaces6, cost, mList._resultStr, status);

  // Check if this rule should be used to generate the chains as well.
  const char *rule = /* set rule to "Invalid" for internal operands */
    strcmp(mList._opcode, mList._resultStr) ? mList._opcode : "Invalid";

  // If this rule produces an operand which has associated chain rules,
  // update the operands with the chain rule + this rule cost & this rule.
  chain_rule(fp, spaces6, mList._resultStr, cost, rule, operands_chained_from, status);

  // Close the child-and-predicate-test braces
  fprintf(fp, "    }\n");

}


//---------------------------expand_opclass------------------------------------
// Chain from one result_type to all other members of its operand class
void ArchDesc::expand_opclass(FILE *fp, const char *indent, const Expr *cost,
                              const char *result_type, ProductionState &status) {
  const Form *form = _globalNames[result_type];
  OperandForm *op = form ? form->is_operand() : nullptr;
  if( op && op->_classes.count() > 0 ) {
    if( debug_output ) { fprintf(fp, "// expand operand classes for operand: %s \n", (char *)op->_ident  ); } // %%%%% Explanation
    // Iterate through all operand classes which include this operand
    op->_classes.reset();
    const char *oclass;
    // Expr *cCost = new Expr(cost);
    while( (oclass = op->_classes.iter()) != nullptr )
      // Check against other match costs, and update cost & rule vectors
      cost_check(fp, indent, ArchDesc::getMachOperEnum(oclass), cost, result_type, status);
  }
}

//---------------------------chain_rule----------------------------------------
// Starting at 'operand', check if we know how to automatically generate other results
void ArchDesc::chain_rule(FILE *fp, const char *indent, const char *operand,
     const Expr *icost, const char *irule, Dict &operands_chained_from,  ProductionState &status) {

  // Check if we have already generated chains from this starting point
  if( operands_chained_from[operand] != nullptr ) {
    return;
  } else {
    operands_chained_from.Insert( operand, operand);
  }
  if( debug_output ) { fprintf(fp, "// chain rules starting from: %s  and  %s \n", (char *)operand, (char *)irule); } // %%%%% Explanation

  ChainList *lst = (ChainList *)_chainRules[operand];
  if (lst) {
    // printf("\nChain from <%s> at cost #%s\n",operand, icost ? icost : "_");
    const char *result, *cost, *rule;
    for(lst->reset(); (lst->iter(result,cost,rule)) == true; ) {
      // Do not generate operands that are already available
      if( operands_chained_from[result] != nullptr ) {
        continue;
      } else {
        // Compute the cost for previous match + chain_rule_cost
        // total_cost = icost + cost;
        Expr *total_cost = icost->clone();  // icost + cost
        total_cost->add(cost, *this);

        // Check for transitive chain rules
        Form *form = (Form *)_globalNames[rule];
        if ( ! form->is_instruction()) {
          // printf("   result=%s cost=%s rule=%s\n", result, total_cost, rule);
          // Check against other match costs, and update cost & rule vectors
          const char *reduce_rule = strcmp(irule,"Invalid") ? irule : rule;
          cost_check(fp, indent, ArchDesc::getMachOperEnum(result), total_cost, reduce_rule, status);
          chain_rule(fp, indent, result, total_cost, irule, operands_chained_from, status);
        } else {
          // printf("   result=%s cost=%s rule=%s\n", result, total_cost, rule);
          // Check against other match costs, and update cost & rule vectors
          cost_check(fp, indent, ArchDesc::getMachOperEnum(result), total_cost, rule, status);
          chain_rule(fp, indent, result, total_cost, rule, operands_chained_from, status);
        }

        // If this is a member of an operand class, update class cost & rule
        expand_opclass( fp, indent, total_cost, result, status );
      }
    }
  }
}

//---------------------------prune_matchlist-----------------------------------
// Check for duplicate entries in a matchlist, and prune out the higher cost
// entry.
void ArchDesc::prune_matchlist(Dict &minimize, MatchList &mlist) {

}

//---------------------------buildDFA------------------------------------------
// DFA is a large switch with case statements for each ideal opcode encountered
// in any match rule in the ad file.  Each case has a series of if's to handle
// the match or fail decisions.  The matches test the cost function of that
// rule, and prune any cases which are higher cost for the same reduction.
// In order to generate the DFA we walk the table of ideal opcode/MatchList
// pairs generated by the ADLC front end to build the contents of the case
// statements (a series of if statements).
void ArchDesc::buildDFA(FILE* fp) {
  int i;
  // Remember operands that are the starting points for chain rules.
  // Prevent cycles by checking if we have already generated chain.
  Dict operands_chained_from(cmpstr, hashstr, Form::arena);

  // Hash inputs to match rules so that final DFA contains only one entry for
  // each match pattern which is the low cost entry.
  Dict minimize(cmpstr, hashstr, Form::arena);

  // Track status of dfa for each resulting production
  // reset for each ideal root.
  ProductionState status(Form::arena);

  // Output the start of the DFA method into the output file

  fprintf(fp, "\n");
  fprintf(fp, "//------------------------- Source -----------------------------------------\n");
  // Do not put random source code into the DFA.
  // If there are constants which need sharing, put them in "source_hpp" forms.
  // _source.output(fp);
  fprintf(fp, "\n");
  fprintf(fp, "//------------------------- Attributes -------------------------------------\n");
  _attributes.output(fp);
  fprintf(fp, "\n");
  fprintf(fp, "//------------------------- Macros -----------------------------------------\n");
  fprintf(fp, "#define DFA_PRODUCTION(result, rule, cost)\\\n");
  fprintf(fp, "  assert(rule < (1 << 15), \"too many rules\"); _cost[ (result) ] = cost; _rule[ (result) ] = (rule << 1) | 0x1;\n");
  fprintf(fp, "\n");

  fprintf(fp, "//------------------------- DFA --------------------------------------------\n");

  fprintf(fp,
"// DFA is a large switch with case statements for each ideal opcode encountered\n"
"// in any match rule in the ad file.  Each case has a series of if's to handle\n"
"// the match or fail decisions.  The matches test the cost function of that\n"
"// rule, and prune any cases which are higher cost for the same reduction.\n"
"// In order to generate the DFA we walk the table of ideal opcode/MatchList\n"
"// pairs generated by the ADLC front end to build the contents of the case\n"
"// statements (a series of if statements).\n"
);
  fprintf(fp, "\n");
  fprintf(fp, "\n");
  if (_dfa_small) {
    // Now build the individual routines just like the switch entries in large version
    // Iterate over the table of MatchLists, start at first valid opcode of 1
    for (i = 1; i < _last_opcode; i++) {
      if (_mlistab[i] == nullptr) continue;
      // Generate the routine header statement for this opcode
      fprintf(fp, "void  State::_sub_Op_%s(const Node *n){\n", NodeClassNames[i]);
      // Generate body. Shared for both inline and out-of-line version
      gen_dfa_state_body(fp, minimize, status, operands_chained_from, i);
      // End of routine
      fprintf(fp, "}\n");
    }
  }
  fprintf(fp, "bool State::DFA");
  fprintf(fp, "(int opcode, const Node *n) {\n");
  fprintf(fp, "  switch(opcode) {\n");

  // Iterate over the table of MatchLists, start at first valid opcode of 1
  for (i = 1; i < _last_opcode; i++) {
    if (_mlistab[i] == nullptr) continue;
    // Generate the case statement for this opcode
    if (_dfa_small) {
      fprintf(fp, "  case Op_%s: { _sub_Op_%s(n);\n", NodeClassNames[i], NodeClassNames[i]);
    } else {
      fprintf(fp, "  case Op_%s: {\n", NodeClassNames[i]);
      // Walk the list, compacting it
      gen_dfa_state_body(fp, minimize, status, operands_chained_from, i);
    }
    // Print the "break"
    fprintf(fp, "    break;\n");
    fprintf(fp, "  }\n");
  }

  // Generate the default case for switch(opcode)
  fprintf(fp, "  \n");
  fprintf(fp, "  default:\n");
  fprintf(fp, "    tty->print(\"Default case invoked for: \\n\");\n");
  fprintf(fp, "    tty->print(\"   opcode  = %cd, \\\"%cs\\\"\\n\", opcode, NodeClassNames[opcode]);\n", '%', '%');
  fprintf(fp, "    return false;\n");
  fprintf(fp, "  }\n");

  // Return status, indicating a successful match.
  fprintf(fp, "  return true;\n");
  // Generate the closing brace for method Matcher::DFA
  fprintf(fp, "}\n");
  Expr::check_buffers();
}


class dfa_shared_preds {
  enum { count = 3 };

  static bool        _found[count];
  static const char* _type [count];
  static const char* _var  [count];
  static const char* _pred [count];

  static void check_index(int index) { assert( 0 <= index && index < count, "Invalid index"); }

  // Confirm that this is a separate sub-expression.
  // Only need to catch common cases like " ... && shared ..."
  // and avoid hazardous ones like "...->shared"
  static bool valid_loc(char *pred, char *shared) {
    // start of predicate is valid
    if( shared == pred ) return true;

    // Check previous character and recurse if needed
    char *prev = shared - 1;
    char c  = *prev;
    switch( c ) {
    case ' ':
    case '\n':
      return dfa_shared_preds::valid_loc(pred, prev);
    case '!':
    case '(':
    case '<':
    case '=':
      return true;
    case '"':  // such as: #line 10 "myfile.ad"\n mypredicate
      return true;
    case '|':
      if (prev != pred && *(prev-1) == '|') return true;
      break;
    case '&':
      if (prev != pred && *(prev-1) == '&') return true;
      break;
    default:
      return false;
    }

    return false;
  }

public:

  static bool        found(int index){ check_index(index); return _found[index]; }
  static void    set_found(int index, bool val) { check_index(index); _found[index] = val; }
  static void  reset_found() {
    for( int i = 0; i < count; ++i ) { _found[i] = false; }
  };

  static const char* type(int index) { check_index(index); return _type[index]; }
  static const char* var (int index) { check_index(index); return _var [index];  }
  static const char* pred(int index) { check_index(index); return _pred[index]; }

  // Check each predicate in the MatchList for common sub-expressions
  static void cse_matchlist(MatchList *matchList) {
    for( MatchList *mList = matchList; mList != nullptr; mList = mList->get_next() ) {
      Predicate* predicate = mList->get_pred_obj();
      char*      pred      = mList->get_pred();
      if( pred != nullptr ) {
        for(int index = 0; index < count; ++index ) {
          const char *shared_pred      = dfa_shared_preds::pred(index);
          const char *shared_pred_var  = dfa_shared_preds::var(index);
          bool result = dfa_shared_preds::cse_predicate(predicate, shared_pred, shared_pred_var);
          if( result ) dfa_shared_preds::set_found(index, true);
        }
      }
    }
  }

  // If the Predicate contains a common sub-expression, replace the Predicate's
  // string with one that uses the variable name.
  static bool cse_predicate(Predicate* predicate, const char *shared_pred, const char *shared_pred_var) {
    bool result = false;
    char *pred = predicate->_pred;
    if( pred != nullptr ) {
      char *new_pred = pred;
      for( char *shared_pred_loc = strstr(new_pred, shared_pred);
      shared_pred_loc != nullptr && dfa_shared_preds::valid_loc(new_pred,shared_pred_loc);
      shared_pred_loc = strstr(new_pred, shared_pred) ) {
        // Do not modify the original predicate string, it is shared
        if( new_pred == pred ) {
          new_pred = strdup(pred);
          shared_pred_loc = strstr(new_pred, shared_pred);
        }
        // Replace shared_pred with variable name
        strncpy(shared_pred_loc, shared_pred_var, strlen(shared_pred_var));
      }
      // Install new predicate
      if( new_pred != pred ) {
        predicate->_pred = new_pred;
        result = true;
      }
    }
    return result;
  }

  // Output the hoisted common sub-expression if we found it in predicates
  static void generate_cse(FILE *fp) {
    for(int j = 0; j < count; ++j ) {
      if( dfa_shared_preds::found(j) ) {
        const char *shared_pred_type = dfa_shared_preds::type(j);
        const char *shared_pred_var  = dfa_shared_preds::var(j);
        const char *shared_pred      = dfa_shared_preds::pred(j);
        fprintf(fp, "    %s %s = %s;\n", shared_pred_type, shared_pred_var, shared_pred);
      }
    }
  }
};
// shared predicates, _var and _pred entry should be the same length
bool         dfa_shared_preds::_found[dfa_shared_preds::count] = { false,          false,           false               };
const char*  dfa_shared_preds::_type [dfa_shared_preds::count] = { "int",          "jlong",         "intptr_t"          };
const char*  dfa_shared_preds::_var  [dfa_shared_preds::count] = { "_n_get_int__", "_n_get_long__", "_n_get_intptr_t__" };
const char*  dfa_shared_preds::_pred [dfa_shared_preds::count] = { "n->get_int()", "n->get_long()", "n->get_intptr_t()" };

// Helper method to check whether a node is vector unary operation.
static bool is_vector_unary_op_name(const char* op_name) {
  static const char* vector_unary_op_list[] = {
    "AbsVB", "AbsVS", "AbsVI", "AbsVL", "AbsVF", "AbsVD",
    "NegVI", "NegVL", "NegVF", "NegVD",
    "SqrtVHF", "SqrtVF", "SqrtVD",
    "PopCountVI", "PopCountVL",
    "CountLeadingZerosV", "CountTrailingZerosV",
    "ReverseV", "ReverseBytesV",
    "MaskAll", "VectorLoadMask", "VectorMaskFirstTrue"
  };
  int cnt = sizeof(vector_unary_op_list) / sizeof(char*);
  for (int i = 0; i < cnt; i++) {
    if (strcmp(op_name, vector_unary_op_list[i]) == 0) {
      return true;
    }
  }
  return false;
}

void ArchDesc::gen_dfa_state_body(FILE* fp, Dict &minimize, ProductionState &status, Dict &operands_chained_from, int i) {
  // Start the body of each Op_XXX sub-dfa with a clean state.
  status.initialize();

  // Walk the list, compacting it
  MatchList* mList = _mlistab[i];
  do {
    // Hash each entry using inputs as key and pointer as data.
    // If there is already an entry, keep the one with lower cost, and
    // remove the other one from the list.
    prune_matchlist(minimize, *mList);
    // Iterate
    mList = mList->get_next();
  } while(mList != nullptr);

  // Hoist previously specified common sub-expressions out of predicates
  dfa_shared_preds::reset_found();
  dfa_shared_preds::cse_matchlist(_mlistab[i]);
  dfa_shared_preds::generate_cse(fp);

  mList = _mlistab[i];
  bool is_vector_unary_op = is_vector_unary_op_name(NodeClassNames[i]);

  // Walk the list again, generating code
  do {
    // Each match can generate its own chains
    operands_chained_from.Clear();
    gen_match(fp, *mList, status, operands_chained_from, is_vector_unary_op);
    mList = mList->get_next();
  } while(mList != nullptr);
  // Fill in any chain rules which add instructions
  // These can generate their own chains as well.
  operands_chained_from.Clear();  //
  if( debug_output1 ) { fprintf(fp, "// top level chain rules for: %s \n", (char *)NodeClassNames[i]); } // %%%%% Explanation
  const Expr *zeroCost = new Expr("0");
  chain_rule(fp, "   ", (char *)NodeClassNames[i], zeroCost, "Invalid",
             operands_chained_from, status);
}



//------------------------------Expr------------------------------------------
Expr *Expr::_unknown_expr = nullptr;
char  Expr::string_buffer[STRING_BUFFER_LENGTH];
char  Expr::external_buffer[STRING_BUFFER_LENGTH];
bool  Expr::_init_buffers = Expr::init_buffers();

Expr::Expr() {
  _external_name = nullptr;
  _expr          = "Invalid_Expr";
  _min_value     = Expr::Max;
  _max_value     = Expr::Zero;
}
Expr::Expr(const char *cost) {
  _external_name = nullptr;

  int intval = 0;
  if( cost == nullptr ) {
    _expr = "0";
    _min_value = Expr::Zero;
    _max_value = Expr::Zero;
  }
  else if( ADLParser::is_int_token(cost, intval) ) {
    _expr = cost;
    _min_value = intval;
    _max_value = intval;
  }
  else {
    assert( strcmp(cost,"0") != 0, "Recognize string zero as an int");
    _expr = cost;
    _min_value = Expr::Zero;
    _max_value = Expr::Max;
  }
}

Expr::Expr(const char *name, const char *expression, int min_value, int max_value) {
  _external_name = name;
  _expr          = expression ? expression : name;
  _min_value     = min_value;
  _max_value     = max_value;
  assert(_min_value >= 0 && _min_value <= Expr::Max, "value out of range");
  assert(_max_value >= 0 && _max_value <= Expr::Max, "value out of range");
}

Expr *Expr::clone() const {
  Expr *cost = new Expr();
  cost->_external_name = _external_name;
  cost->_expr          = _expr;
  cost->_min_value     = _min_value;
  cost->_max_value     = _max_value;

  return cost;
}

void Expr::add(const Expr *c) {
  // Do not update fields until all computation is complete
  const char *external  = compute_external(this, c);
  const char *expr      = compute_expr(this, c);
  int         min_value = compute_min (this, c);
  int         max_value = compute_max (this, c);

  _external_name = external;
  _expr      = expr;
  _min_value = min_value;
  _max_value = max_value;
}

void Expr::add(const char *c) {
  Expr *cost = new Expr(c);
  add(cost);
}

void Expr::add(const char *c, ArchDesc &AD) {
  const Expr *e = AD.globalDefs()[c];
  if( e != nullptr ) {
    // use the value of 'c' defined in <arch>.ad
    add(e);
  } else {
    Expr *cost = new Expr(c);
    add(cost);
  }
}

const char *Expr::compute_external(const Expr *c1, const Expr *c2) {
  const char * result = nullptr;

  // Preserve use of external name which has a zero value
  if( c1->_external_name != nullptr ) {
    if( c2->is_zero() ) {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s", c1->as_string());
    } else {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s+%s", c1->as_string(), c2->as_string());
    }
    string_buffer[STRING_BUFFER_LENGTH - 1] = '\0';
    result = strdup(string_buffer);
  }
  else if( c2->_external_name != nullptr ) {
    if( c1->is_zero() ) {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s", c2->_external_name);
    } else {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s + %s", c1->as_string(), c2->as_string());
    }
    string_buffer[STRING_BUFFER_LENGTH - 1] = '\0';
    result = strdup(string_buffer);
  }
  return result;
}

const char *Expr::compute_expr(const Expr *c1, const Expr *c2) {
  if( !c1->is_zero() ) {
    if( c2->is_zero() ) {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s", c1->_expr);
    } else {
      snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s+%s", c1->_expr, c2->_expr);
    }
  }
  else if( !c2->is_zero() ) {
    snprintf(string_buffer, STRING_BUFFER_LENGTH, "%s", c2->_expr);
  }
  else {
    snprintf_checked(string_buffer, STRING_BUFFER_LENGTH, "0");
  }
  string_buffer[STRING_BUFFER_LENGTH - 1] = '\0';
  char *cost = strdup(string_buffer);

  return cost;
}

int Expr::compute_min(const Expr *c1, const Expr *c2) {
  int v1 = c1->_min_value;
  int v2 = c2->_min_value;
  assert(0 <= v2 && v2 <= Expr::Max, "sanity");
  assert(v1 <= Expr::Max - v2, "Invalid cost computation");

  return v1 + v2;
}


int Expr::compute_max(const Expr *c1, const Expr *c2) {
  int v1 = c1->_max_value;
  int v2 = c2->_max_value;

  // Check for overflow without producing UB. If v2 is positive
  // and not larger than Max, the subtraction cannot underflow.
  assert(0 <= v2 && v2 <= Expr::Max, "sanity");
  if (v1 > Expr::Max - v2) {
    return Expr::Max;
  }

  return v1 + v2;
}

void Expr::print() const {
  if( _external_name != nullptr ) {
    printf("  %s == (%s) === [%d, %d]\n", _external_name, _expr, _min_value, _max_value);
  } else {
    printf("  %s === [%d, %d]\n", _expr, _min_value, _max_value);
  }
}

void Expr::print_define(FILE *fp) const {
  assert( _external_name != nullptr, "definition does not have a name");
  assert( _min_value == _max_value, "Expect user definitions to have constant value");
  fprintf(fp, "#define  %s  (%s)  \n", _external_name, _expr);
  fprintf(fp, "// value == %d \n", _min_value);
}

void Expr::print_assert(FILE *fp) const {
  assert( _external_name != nullptr, "definition does not have a name");
  assert( _min_value == _max_value, "Expect user definitions to have constant value");
  fprintf(fp, "  assert( %s == %d, \"Expect (%s) to equal %d\");\n", _external_name, _min_value, _expr, _min_value);
}

Expr *Expr::get_unknown() {
  if( Expr::_unknown_expr == nullptr ) {
    Expr::_unknown_expr = new Expr();
  }

  return Expr::_unknown_expr;
}

bool Expr::init_buffers() {
  // Fill buffers with 0
  for( int i = 0; i < STRING_BUFFER_LENGTH; ++i ) {
    external_buffer[i] = '\0';
    string_buffer[i]   = '\0';
  }

  return true;
}

bool Expr::check_buffers() {
  // returns 'true' if buffer use may have overflowed
  bool ok = true;
  for( int i = STRING_BUFFER_LENGTH - 100; i < STRING_BUFFER_LENGTH; ++i) {
    if( external_buffer[i] != '\0' || string_buffer[i]   != '\0' ) {
      ok = false;
      assert( false, "Expr:: Buffer overflow");
    }
  }

  return ok;
}


//------------------------------ExprDict---------------------------------------
// Constructor
ExprDict::ExprDict( CmpKey cmp, Hash hash, AdlArena *arena )
  : _expr(cmp, hash, arena), _defines()  {
}
ExprDict::~ExprDict() {
}

// Return # of name-Expr pairs in dict
int ExprDict::Size(void) const {
  return _expr.Size();
}

// define inserts the given key-value pair into the dictionary,
// and records the name in order for later output, ...
const Expr  *ExprDict::define(const char *name, Expr *expr) {
  const Expr *old_expr = (*this)[name];
  assert(old_expr == nullptr, "Implementation does not support redefinition");

  _expr.Insert(name, expr);
  _defines.addName(name);

  return old_expr;
}

// Insert inserts the given key-value pair into the dictionary.  The prior
// value of the key is returned; null if the key was not previously defined.
const Expr  *ExprDict::Insert(const char *name, Expr *expr) {
  return (Expr*)_expr.Insert((void*)name, (void*)expr);
}

// Finds the value of a given key; or null if not found.
// The dictionary is NOT changed.
const Expr  *ExprDict::operator [](const char *name) const {
  return (Expr*)_expr[name];
}

void ExprDict::print_defines(FILE *fp) {
  fprintf(fp, "\n");
  const char *name = nullptr;
  for( _defines.reset(); (name = _defines.iter()) != nullptr; ) {
    const Expr *expr = (const Expr*)_expr[name];
    assert( expr != nullptr, "name in ExprDict without matching Expr in dictionary");
    expr->print_define(fp);
  }
}
void ExprDict::print_asserts(FILE *fp) {
  fprintf(fp, "\n");
  fprintf(fp, "  // Following assertions generated from definition section\n");
  const char *name = nullptr;
  for( _defines.reset(); (name = _defines.iter()) != nullptr; ) {
    const Expr *expr = (const Expr*)_expr[name];
    assert( expr != nullptr, "name in ExprDict without matching Expr in dictionary");
    expr->print_assert(fp);
  }
}

// Print out the dictionary contents as key-value pairs
static void dumpekey(const void* key)  { fprintf(stdout, "%s", (char*) key); }
static void dumpexpr(const void* expr) { fflush(stdout); ((Expr*)expr)->print(); }

void ExprDict::dump() {
  _expr.print(dumpekey, dumpexpr);
}


//------------------------------ExprDict::private------------------------------
// Disable public use of constructor, copy-ctor, operator =, operator ==
ExprDict::ExprDict( ) : _expr(cmpkey,hashkey), _defines()  {
  assert( false, "NotImplemented");
}
ExprDict::ExprDict( const ExprDict & ) : _expr(cmpkey,hashkey), _defines() {
  assert( false, "NotImplemented");
}
ExprDict &ExprDict::operator =( const ExprDict &rhs) {
  assert( false, "NotImplemented");
  _expr = rhs._expr;
  return *this;
}
// == compares two dictionaries; they must have the same keys (their keys
// must match using CmpKey) and they must have the same values (pointer
// comparison).  If so 1 is returned, if not 0 is returned.
bool ExprDict::operator ==(const ExprDict &d) const {
  assert( false, "NotImplemented");
  return false;
}


//------------------------------Production-------------------------------------
Production::Production(const char *result, const char *constraint, const char *valid) {
  initialize();
  _result     = result;
  _constraint = constraint;
  _valid      = valid;
}

void Production::initialize() {
  _result     = nullptr;
  _constraint = nullptr;
  _valid      = knownInvalid;
  _cost_lb    = Expr::get_unknown();
  _cost_ub    = Expr::get_unknown();
}

void Production::print() {
  printf("%s", (_result     == nullptr ? "nullptr" : _result ) );
  printf("%s", (_constraint == nullptr ? "nullptr" : _constraint ) );
  printf("%s", (_valid      == nullptr ? "nullptr" : _valid ) );
  _cost_lb->print();
  _cost_ub->print();
}


//------------------------------ProductionState--------------------------------
void ProductionState::initialize() {
  _constraint = noConstraint;

  // reset each Production currently in the dictionary
  DictI iter( &_production );
  const void *x, *y = nullptr;
  for( ; iter.test(); ++iter) {
    x = iter._key;
    y = iter._value;
    Production *p = (Production*)y;
    if( p != nullptr ) {
      p->initialize();
    }
  }
}

Production *ProductionState::getProduction(const char *result) {
  Production *p = (Production *)_production[result];
  if( p == nullptr ) {
    p = new Production(result, _constraint, knownInvalid);
    _production.Insert(result, p);
  }

  return p;
}

void ProductionState::set_constraint(const char *constraint) {
  _constraint = constraint;
}

const char *ProductionState::valid(const char *result) {
  return getProduction(result)->valid();
}

void ProductionState::set_valid(const char *result) {
  Production *p = getProduction(result);

  // Update valid as allowed by current constraints
  if( _constraint == noConstraint ) {
    p->_valid = knownValid;
  } else {
    if( p->_valid != knownValid ) {
      p->_valid = unknownValid;
    }
  }
}

Expr *ProductionState::cost_lb(const char *result) {
  return getProduction(result)->cost_lb();
}

Expr *ProductionState::cost_ub(const char *result) {
  return getProduction(result)->cost_ub();
}

void ProductionState::set_cost_bounds(const char *result, const Expr *cost, bool has_state_check, bool has_cost_check) {
  Production *p = getProduction(result);

  if( p->_valid == knownInvalid ) {
    // Our cost bounds are not unknown, just not defined.
    p->_cost_lb = cost->clone();
    p->_cost_ub = cost->clone();
  } else if (has_state_check || _constraint != noConstraint) {
    // The production is protected by a condition, so
    // the cost bounds may expand.
    // _cost_lb = min(cost, _cost_lb)
    if( cost->less_than_or_equal(p->_cost_lb) ) {
      p->_cost_lb = cost->clone();
    }
    // _cost_ub = max(cost, _cost_ub)
    if( p->_cost_ub->less_than_or_equal(cost) ) {
      p->_cost_ub = cost->clone();
    }
  } else if (has_cost_check) {
    // The production has no condition check, but does
    // have a cost check that could reduce the upper
    // and/or lower bound.
    // _cost_lb = min(cost, _cost_lb)
    if( cost->less_than_or_equal(p->_cost_lb) ) {
      p->_cost_lb = cost->clone();
    }
    // _cost_ub = min(cost, _cost_ub)
    if( cost->less_than_or_equal(p->_cost_ub) ) {
      p->_cost_ub = cost->clone();
    }
  } else {
    // The costs are unconditionally set.
    p->_cost_lb = cost->clone();
    p->_cost_ub = cost->clone();
  }

}

// Print out the dictionary contents as key-value pairs
static void print_key (const void* key)              { fprintf(stdout, "%s", (char*) key); }
static void print_production(const void* production) { fflush(stdout); ((Production*)production)->print(); }

void ProductionState::print() {
  _production.print(print_key, print_production);
}
