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 != NULL); // 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]; // 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); mList = mList->get_next(); } while(mList != NULL); // 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); }
// Check each predicate in the MatchList for common sub-expressions static void cse_matchlist(MatchList *matchList) { for( MatchList *mList = matchList; mList != NULL; mList = mList->get_next() ) { Predicate* predicate = mList->get_pred_obj(); char* pred = mList->get_pred(); if( pred != NULL ) { 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); } } } }