Production *ProductionState::getProduction(const char *result) { Production *p = (Production *)_production[result]; if( p == NULL ) { p = new Production(result, _constraint, knownInvalid); _production.Insert(result, p); } return p; }
//---------------------------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] != NULL ) { 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] != NULL ) { 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 ); } } } }