hotspot/src/share/vm/adlc/formssel.cpp
changeset 2154 72a9b7284ccf
parent 2105 347008ce7984
parent 2150 0d91d17158cc
child 2348 4e71ed4c2709
equal deleted inserted replaced
2106:ec595a5e793e 2154:72a9b7284ccf
   842   const char *name;
   842   const char *name;
   843   const char *kill_name = NULL;
   843   const char *kill_name = NULL;
   844   for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
   844   for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
   845     OperandForm *opForm = (OperandForm*)_localNames[name];
   845     OperandForm *opForm = (OperandForm*)_localNames[name];
   846 
   846 
   847     const Form *form = _effects[name];
   847     Effect* e = NULL;
   848     Effect     *e    = form ? form->is_effect() : NULL;
   848     {
       
   849       const Form* form = _effects[name];
       
   850       e = form ? form->is_effect() : NULL;
       
   851     }
       
   852 
   849     if (e != NULL) {
   853     if (e != NULL) {
   850       has_temp |= e->is(Component::TEMP);
   854       has_temp |= e->is(Component::TEMP);
   851 
   855 
   852       // KILLs must be declared after any TEMPs because TEMPs are real
   856       // KILLs must be declared after any TEMPs because TEMPs are real
   853       // uses so their operand numbering must directly follow the real
   857       // uses so their operand numbering must directly follow the real
   856       if (kill_name != NULL &&
   860       if (kill_name != NULL &&
   857           e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
   861           e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
   858         OperandForm* kill = (OperandForm*)_localNames[kill_name];
   862         OperandForm* kill = (OperandForm*)_localNames[kill_name];
   859         globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",
   863         globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",
   860                              _ident, kill->_ident, kill_name);
   864                              _ident, kill->_ident, kill_name);
   861       } else if (e->isa(Component::KILL)) {
   865       } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) {
   862         kill_name = name;
       
   863       }
       
   864 
       
   865       // TEMPs are real uses and need to be among the first parameters
       
   866       // listed, otherwise the numbering of operands and inputs gets
       
   867       // screwy, so enforce this restriction during parse.
       
   868       if (kill_name != NULL &&
       
   869           e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
       
   870         OperandForm* kill = (OperandForm*)_localNames[kill_name];
       
   871         globalAD->syntax_err(_linenum, "%s: %s %s must follow %s %s in the argument list\n",
       
   872                              _ident, kill->_ident, kill_name, opForm->_ident, name);
       
   873       } else if (e->isa(Component::KILL)) {
       
   874         kill_name = name;
   866         kill_name = name;
   875       }
   867       }
   876     }
   868     }
   877 
   869 
   878     const Component *component  = _components.search(name);
   870     const Component *component  = _components.search(name);
  1120   char       *result             = NULL;
  1112   char       *result             = NULL;
  1121   char       *result2            = NULL;
  1113   char       *result2            = NULL;
  1122   const char *op_name            = NULL;
  1114   const char *op_name            = NULL;
  1123   const char *reg_type           = NULL;
  1115   const char *reg_type           = NULL;
  1124   FormDict   &globals            = AD.globalNames();
  1116   FormDict   &globals            = AD.globalNames();
  1125   cisc_spill_operand = _matrule->cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
  1117   cisc_spill_operand = _matrule->matchrule_cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
  1126   if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != NULL) && equivalent_predicates(this, instr) ) {
  1118   if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != NULL) && equivalent_predicates(this, instr) ) {
  1127     cisc_spill_operand = operand_position(op_name, Component::USE);
  1119     cisc_spill_operand = operand_position(op_name, Component::USE);
  1128     int def_oper  = operand_position(op_name, Component::DEF);
  1120     int def_oper  = operand_position(op_name, Component::DEF);
  1129     if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) {
  1121     if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) {
  1130       // Do not support cisc-spilling for destination operands and
  1122       // Do not support cisc-spilling for destination operands and
  1215 }
  1207 }
  1216 
  1208 
  1217 // Seach through operands to determine parameters unique positions.
  1209 // Seach through operands to determine parameters unique positions.
  1218 void InstructForm::set_unique_opnds() {
  1210 void InstructForm::set_unique_opnds() {
  1219   uint* uniq_idx = NULL;
  1211   uint* uniq_idx = NULL;
  1220   uint  nopnds = num_opnds();
  1212   int  nopnds = num_opnds();
  1221   uint  num_uniq = nopnds;
  1213   uint  num_uniq = nopnds;
  1222   uint i;
  1214   int i;
       
  1215   _uniq_idx_length = 0;
  1223   if ( nopnds > 0 ) {
  1216   if ( nopnds > 0 ) {
  1224     // Allocate index array with reserve.
  1217     // Allocate index array.  Worst case we're mapping from each
  1225     uniq_idx = (uint*) malloc(sizeof(uint)*(nopnds + 2));
  1218     // component back to an index and any DEF always goes at 0 so the
  1226     for( i = 0; i < nopnds+2; i++ ) {
  1219     // length of the array has to be the number of components + 1.
       
  1220     _uniq_idx_length = _components.count() + 1;
       
  1221     uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
       
  1222     for( i = 0; i < _uniq_idx_length; i++ ) {
  1227       uniq_idx[i] = i;
  1223       uniq_idx[i] = i;
  1228     }
  1224     }
  1229   }
  1225   }
  1230   // Do it only if there is a match rule and no expand rule.  With an
  1226   // Do it only if there is a match rule and no expand rule.  With an
  1231   // expand rule it is done by creating new mach node in Expand()
  1227   // expand rule it is done by creating new mach node in Expand()
  1236     bool has_dupl_use = false;
  1232     bool has_dupl_use = false;
  1237 
  1233 
  1238     _parameters.reset();
  1234     _parameters.reset();
  1239     while( (name = _parameters.iter()) != NULL ) {
  1235     while( (name = _parameters.iter()) != NULL ) {
  1240       count = 0;
  1236       count = 0;
  1241       uint position = 0;
  1237       int position = 0;
  1242       uint uniq_position = 0;
  1238       int uniq_position = 0;
  1243       _components.reset();
  1239       _components.reset();
  1244       Component *comp = NULL;
  1240       Component *comp = NULL;
  1245       if( sets_result() ) {
  1241       if( sets_result() ) {
  1246         comp = _components.iter();
  1242         comp = _components.iter();
  1247         position++;
  1243         position++;
  1253         if ( position==0 && (! comp->isa(Component::DEF)) ) {
  1249         if ( position==0 && (! comp->isa(Component::DEF)) ) {
  1254           ++position;
  1250           ++position;
  1255         }
  1251         }
  1256         if( strcmp(name, comp->_name)==0 ) {
  1252         if( strcmp(name, comp->_name)==0 ) {
  1257           if( ++count > 1 ) {
  1253           if( ++count > 1 ) {
       
  1254             assert(position < _uniq_idx_length, "out of bounds");
  1258             uniq_idx[position] = uniq_position;
  1255             uniq_idx[position] = uniq_position;
  1259             has_dupl_use = true;
  1256             has_dupl_use = true;
  1260           } else {
  1257           } else {
  1261             uniq_position = position;
  1258             uniq_position = position;
  1262           }
  1259           }
  1282   }
  1279   }
  1283   _uniq_idx = uniq_idx;
  1280   _uniq_idx = uniq_idx;
  1284   _num_uniq = num_uniq;
  1281   _num_uniq = num_uniq;
  1285 }
  1282 }
  1286 
  1283 
  1287 // Generate index values needed for determing the operand position
  1284 // Generate index values needed for determining the operand position
  1288 void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) {
  1285 void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) {
  1289   uint  idx = 0;                  // position of operand in match rule
  1286   uint  idx = 0;                  // position of operand in match rule
  1290   int   cur_num_opnds = num_opnds();
  1287   int   cur_num_opnds = num_opnds();
  1291 
  1288 
  1292   // Compute the index into vector of operand pointers:
  1289   // Compute the index into vector of operand pointers:
  2198 
  2195 
  2199 
  2196 
  2200 // Return zero-based position in component list, only counting constants;
  2197 // Return zero-based position in component list, only counting constants;
  2201 // Return -1 if not in list.
  2198 // Return -1 if not in list.
  2202 int OperandForm::constant_position(FormDict &globals, const Component *last) {
  2199 int OperandForm::constant_position(FormDict &globals, const Component *last) {
  2203   // Iterate through components and count constants preceeding 'constant'
  2200   // Iterate through components and count constants preceding 'constant'
  2204   uint  position = 0;
  2201   int position = 0;
  2205   Component *comp;
  2202   Component *comp;
  2206   _components.reset();
  2203   _components.reset();
  2207   while( (comp = _components.iter()) != NULL  && (comp != last) ) {
  2204   while( (comp = _components.iter()) != NULL  && (comp != last) ) {
  2208     // Special case for operands that take a single user-defined operand
  2205     // Special case for operands that take a single user-defined operand
  2209     // Skip the initial definition in the component list.
  2206     // Skip the initial definition in the component list.
  2236 
  2233 
  2237 
  2234 
  2238 // Return zero-based position in component list, only counting constants;
  2235 // Return zero-based position in component list, only counting constants;
  2239 // Return -1 if not in list.
  2236 // Return -1 if not in list.
  2240 int OperandForm::register_position(FormDict &globals, const char *reg_name) {
  2237 int OperandForm::register_position(FormDict &globals, const char *reg_name) {
  2241   // Iterate through components and count registers preceeding 'last'
  2238   // Iterate through components and count registers preceding 'last'
  2242   uint  position = 0;
  2239   uint  position = 0;
  2243   Component *comp;
  2240   Component *comp;
  2244   _components.reset();
  2241   _components.reset();
  2245   while( (comp = _components.iter()) != NULL
  2242   while( (comp = _components.iter()) != NULL
  2246          && (strcmp(comp->_name,reg_name) != 0) ) {
  2243          && (strcmp(comp->_name,reg_name) != 0) ) {
  2302   assert( op, "Memory Interface 'disp' can only emit an operand form");
  2299   assert( op, "Memory Interface 'disp' can only emit an operand form");
  2303   // Check if this is a ConP, which may require relocation
  2300   // Check if this is a ConP, which may require relocation
  2304   if ( op->is_base_constant(globals) == Form::idealP ) {
  2301   if ( op->is_base_constant(globals) == Form::idealP ) {
  2305     // Find the constant's index:  _c0, _c1, _c2, ... , _cN
  2302     // Find the constant's index:  _c0, _c1, _c2, ... , _cN
  2306     uint idx  = op->constant_position( globals, rep_var);
  2303     uint idx  = op->constant_position( globals, rep_var);
  2307     fprintf(fp,"  virtual bool disp_is_oop() const {", _ident);
  2304     fprintf(fp,"  virtual bool disp_is_oop() const {");
  2308     fprintf(fp,  "  return _c%d->isa_oop_ptr();", idx);
  2305     fprintf(fp,  "  return _c%d->isa_oop_ptr();", idx);
  2309     fprintf(fp, " }\n");
  2306     fprintf(fp, " }\n");
  2310   }
  2307   }
  2311 }
  2308 }
  2312 
  2309 
  3040   return false;
  3037   return false;
  3041 }
  3038 }
  3042 
  3039 
  3043 // Recursive call collecting info on top-level operands, not transitive.
  3040 // Recursive call collecting info on top-level operands, not transitive.
  3044 // Implementation does not modify state of internal structures.
  3041 // Implementation does not modify state of internal structures.
  3045 void MatchNode::append_components(FormDict &locals, ComponentList &components,
  3042 void MatchNode::append_components(FormDict& locals, ComponentList& components,
  3046                                   bool deflag) const {
  3043                                   bool def_flag) const {
  3047   int   usedef = deflag ? Component::DEF : Component::USE;
  3044   int usedef = def_flag ? Component::DEF : Component::USE;
  3048   FormDict &globals = _AD.globalNames();
  3045   FormDict &globals = _AD.globalNames();
  3049 
  3046 
  3050   assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  3047   assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  3051   // Base case
  3048   // Base case
  3052   if (_lChild==NULL && _rChild==NULL) {
  3049   if (_lChild==NULL && _rChild==NULL) {
  3060       }
  3057       }
  3061     }
  3058     }
  3062     return;
  3059     return;
  3063   }
  3060   }
  3064   // Promote results of "Set" to DEF
  3061   // Promote results of "Set" to DEF
  3065   bool def_flag = (!strcmp(_opType, "Set")) ? true : false;
  3062   bool tmpdef_flag = (!strcmp(_opType, "Set")) ? true : false;
  3066   if (_lChild) _lChild->append_components(locals, components, def_flag);
  3063   if (_lChild) _lChild->append_components(locals, components, tmpdef_flag);
  3067   def_flag = false;   // only applies to component immediately following 'Set'
  3064   tmpdef_flag = false;   // only applies to component immediately following 'Set'
  3068   if (_rChild) _rChild->append_components(locals, components, def_flag);
  3065   if (_rChild) _rChild->append_components(locals, components, tmpdef_flag);
  3069 }
  3066 }
  3070 
  3067 
  3071 // Find the n'th base-operand in the match node,
  3068 // Find the n'th base-operand in the match node,
  3072 // recursively investigates match rules of user-defined operands.
  3069 // recursively investigates match rules of user-defined operands.
  3073 //
  3070 //
  3311 
  3308 
  3312 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
  3309 int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
  3313   static const char *needs_ideal_memory_list[] = {
  3310   static const char *needs_ideal_memory_list[] = {
  3314     "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
  3311     "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
  3315     "StoreB","StoreC","Store" ,"StoreFP",
  3312     "StoreB","StoreC","Store" ,"StoreFP",
  3316     "LoadI" ,"LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
  3313     "LoadI", "LoadUI2L", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
  3317     "LoadB" ,"LoadUS" ,"LoadS" ,"Load"   ,
  3314     "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load"   ,
  3318     "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
  3315     "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
  3319     "Store8B","Store4B","Store8C","Store4C","Store2C",
  3316     "Store8B","Store4B","Store8C","Store4C","Store2C",
  3320     "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
  3317     "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
  3321     "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
  3318     "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
  3322     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
  3319     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
  3409   const Form *form2 = globals[op2];
  3406   const Form *form2 = globals[op2];
  3410 
  3407 
  3411   return (form1 == form2);
  3408   return (form1 == form2);
  3412 }
  3409 }
  3413 
  3410 
  3414 //-------------------------cisc_spill_match------------------------------------
  3411 //-------------------------cisc_spill_match_node-------------------------------
  3415 // Recursively check two MatchRules for legal conversion via cisc-spilling
  3412 // Recursively check two MatchRules for legal conversion via cisc-spilling
  3416 int  MatchNode::cisc_spill_match(FormDict &globals, RegisterForm *registers, MatchNode *mRule2, const char * &operand, const char * &reg_type) {
  3413 int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, MatchNode* mRule2, const char* &operand, const char* &reg_type) {
  3417   int cisc_spillable  = Maybe_cisc_spillable;
  3414   int cisc_spillable  = Maybe_cisc_spillable;
  3418   int left_spillable  = Maybe_cisc_spillable;
  3415   int left_spillable  = Maybe_cisc_spillable;
  3419   int right_spillable = Maybe_cisc_spillable;
  3416   int right_spillable = Maybe_cisc_spillable;
  3420 
  3417 
  3421   // Check that each has same number of operands at this level
  3418   // Check that each has same number of operands at this level
  3432     cisc_spillable = Maybe_cisc_spillable;
  3429     cisc_spillable = Maybe_cisc_spillable;
  3433   } else {
  3430   } else {
  3434     const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;
  3431     const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;
  3435     const char *name_left  = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;
  3432     const char *name_left  = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;
  3436     const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;
  3433     const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;
       
  3434     DataType data_type = Form::none;
       
  3435     if (form->is_operand()) {
       
  3436       // Make sure the loadX matches the type of the reg
       
  3437       data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals));
       
  3438     }
  3437     // Detect reg vs (loadX memory)
  3439     // Detect reg vs (loadX memory)
  3438     if( form->is_cisc_reg(globals)
  3440     if( form->is_cisc_reg(globals)
  3439         && form2_inst
  3441         && form2_inst
  3440         && (is_load_from_memory(mRule2->_opType) != Form::none) // reg vs. (load memory)
  3442         && data_type != Form::none
       
  3443         && (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory)
  3441         && (name_left != NULL)       // NOT (load)
  3444         && (name_left != NULL)       // NOT (load)
  3442         && (name_right == NULL) ) {  // NOT (load memory foo)
  3445         && (name_right == NULL) ) {  // NOT (load memory foo)
  3443       const Form *form2_left = name_left ? globals[name_left] : NULL;
  3446       const Form *form2_left = name_left ? globals[name_left] : NULL;
  3444       if( form2_left && form2_left->is_cisc_mem(globals) ) {
  3447       if( form2_left && form2_left->is_cisc_mem(globals) ) {
  3445         cisc_spillable = Is_cisc_spillable;
  3448         cisc_spillable = Is_cisc_spillable;
  3485   }
  3488   }
  3486 
  3489 
  3487   return cisc_spillable;
  3490   return cisc_spillable;
  3488 }
  3491 }
  3489 
  3492 
  3490 //---------------------------cisc_spill_match----------------------------------
  3493 //---------------------------cisc_spill_match_rule------------------------------
  3491 // Recursively check two MatchRules for legal conversion via cisc-spilling
  3494 // Recursively check two MatchRules for legal conversion via cisc-spilling
  3492 // This method handles the root of Match tree,
  3495 // This method handles the root of Match tree,
  3493 // general recursive checks done in MatchNode
  3496 // general recursive checks done in MatchNode
  3494 int  MatchRule::cisc_spill_match(FormDict &globals, RegisterForm *registers,
  3497 int  MatchRule::matchrule_cisc_spill_match(FormDict& globals, RegisterForm* registers,
  3495                                  MatchRule *mRule2, const char * &operand,
  3498                                            MatchRule* mRule2, const char* &operand,
  3496                                  const char * &reg_type) {
  3499                                            const char* &reg_type) {
  3497   int cisc_spillable  = Maybe_cisc_spillable;
  3500   int cisc_spillable  = Maybe_cisc_spillable;
  3498   int left_spillable  = Maybe_cisc_spillable;
  3501   int left_spillable  = Maybe_cisc_spillable;
  3499   int right_spillable = Maybe_cisc_spillable;
  3502   int right_spillable = Maybe_cisc_spillable;
  3500 
  3503 
  3501   // Check that each sets a result
  3504   // Check that each sets a result
  3529 }
  3532 }
  3530 
  3533 
  3531 //----------------------------- equivalent ------------------------------------
  3534 //----------------------------- equivalent ------------------------------------
  3532 // Recursively check to see if two match rules are equivalent.
  3535 // Recursively check to see if two match rules are equivalent.
  3533 // This rule handles the root.
  3536 // This rule handles the root.
  3534 bool MatchRule::equivalent(FormDict &globals, MatchRule *mRule2) {
  3537 bool MatchRule::equivalent(FormDict &globals, MatchNode *mRule2) {
  3535   // Check that each sets a result
  3538   // Check that each sets a result
  3536   if (sets_result() != mRule2->sets_result()) {
  3539   if (sets_result() != mRule2->sets_result()) {
  3537     return false;
  3540     return false;
  3538   }
  3541   }
  3539 
  3542 
  3645   }
  3648   }
  3646 }
  3649 }
  3647 
  3650 
  3648 //-------------------------- swap_commutative_op ------------------------------
  3651 //-------------------------- swap_commutative_op ------------------------------
  3649 // Recursively swap specified commutative operation with subtree operands.
  3652 // Recursively swap specified commutative operation with subtree operands.
  3650 void MatchRule::swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) {
  3653 void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) {
  3651   assert(match_rules_cnt < 100," too many match rule clones");
  3654   assert(match_rules_cnt < 100," too many match rule clones");
  3652   // Clone
  3655   // Clone
  3653   MatchRule* clone = new MatchRule(_AD, this);
  3656   MatchRule* clone = new MatchRule(_AD, this);
  3654   // Swap operands of commutative operation
  3657   // Swap operands of commutative operation
  3655   ((MatchNode*)clone)->swap_commutative_op(true, count);
  3658   ((MatchNode*)clone)->swap_commutative_op(true, count);
  3658   clone->_result = buf;
  3661   clone->_result = buf;
  3659 
  3662 
  3660   clone->_next = this->_next;
  3663   clone->_next = this->_next;
  3661   this-> _next = clone;
  3664   this-> _next = clone;
  3662   if( (--count) > 0 ) {
  3665   if( (--count) > 0 ) {
  3663     this-> swap_commutative_op(instr_ident, count, match_rules_cnt);
  3666     this-> matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
  3664     clone->swap_commutative_op(instr_ident, count, match_rules_cnt);
  3667     clone->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
  3665   }
  3668   }
  3666 }
  3669 }
  3667 
  3670 
  3668 //------------------------------MatchRule--------------------------------------
  3671 //------------------------------MatchRule--------------------------------------
  3669 MatchRule::MatchRule(ArchDesc &ad)
  3672 MatchRule::MatchRule(ArchDesc &ad)
  3691 MatchRule::~MatchRule() {
  3694 MatchRule::~MatchRule() {
  3692 }
  3695 }
  3693 
  3696 
  3694 // Recursive call collecting info on top-level operands, not transitive.
  3697 // Recursive call collecting info on top-level operands, not transitive.
  3695 // Implementation does not modify state of internal structures.
  3698 // Implementation does not modify state of internal structures.
  3696 void MatchRule::append_components(FormDict &locals, ComponentList &components) const {
  3699 void MatchRule::append_components(FormDict& locals, ComponentList& components, bool def_flag) const {
  3697   assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  3700   assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  3698 
  3701 
  3699   MatchNode::append_components(locals, components,
  3702   MatchNode::append_components(locals, components,
  3700                                false /* not necessarily a def */);
  3703                                false /* not necessarily a def */);
  3701 }
  3704 }