📄 opt_macro.mx
字号:
ns[k++] = mb->stmt[i]; GDKfree(mb->stmt); mb->stmt = ns; mb->ssize = l; mb->stop = k; return pc;}@-The macro processor should be carefull in replacing theinstruction. In particular, any RETURN or YIELD statementshould be replaced by a jump. For the time being,we only allow for a single return statement at the endof the block.The semantic test is encapsulated in a routines.@cstatic strMACROvalidate(MalBlkPtr mb){ int retseen = 0; int i; InstrPtr p = 0; if (getArgType(mb, getInstrPtr(mb, 0), 0) == TYPE_void) return MAL_SUCCEED; for (i = 1; retseen == 0 && i < mb->stop; i++) { p = getInstrPtr(mb, i); retseen = p->token == RETURNsymbol || p->token == YIELDsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol; } if (retseen && i != mb->stop - 1) throw(MAL, "optimizer.MACROvalidate", "RETURN statement is not the last one"); return MAL_SUCCEED;}strMACROprocessor(MalBlkPtr mb, Symbol t){ InstrPtr q; int i, cnt = 0, last = -1; str msg = MAL_SUCCEED;#ifdef DEBUG_OPT_MACRO printf("calling the MACRO processor\n");#endif if (t == NULL) return msg; msg = MACROvalidate(t->def); if (msg) return msg; for (i = 0; i < mb->stop; i++) { q = getInstrPtr(mb, i); if (getFunctionId(q) && idcmp(getFunctionId(q), t->name) == 0 && getSignature(t)->token == FUNCTIONsymbol) {#ifdef DEBUG_OPT_MACRO printf("Hit, replace macro call %s\n", t->name);#endif if (i == last) throw(MAL, "optimizer.MACROoptimizer", "duplicate macro expansion"); last = i; i = inlineMALblock(mb, i, t->def); cnt++; if (cnt > MAXEXPANSION) throw(MAL, "optimizer.MACROoptimizer", "too many macro expansions"); } } return msg;}@- Macro inversionsMacro inversions map a consecutive sequences of MAL instructionsinto a single call. Subsequence resolution will bind it with the properfunction. The pattern being replaced should be a self-standingassignment. [could be improved]The function being replaced should assign the result tothe signature variables. Otherwise it will be difficultto assess which result to retain.@cstatic intreplaceMALblock(MalBlkPtr mb, int pc, MalBlkPtr mc){ int i, j, k, lim; InstrPtr p, q, rq; int *cvar, *mvar; int ctop = 0, mtop = 0; /* collect variable map */ cvar = (int *) alloca(mc->vtop * MAXARG); mvar = (int *) alloca(mb->vtop * MAXARG); lim = pc + mc->stop - 2; k = 1; for (i = pc; i < lim; i++, k++) { p = getInstrPtr(mb, i); q = getInstrPtr(mc, k); for (j = 0; j < p->argc; j++) cvar[ctop++] = getArg(q, j); for (j = 0; j < p->argc; j++) mvar[mtop++] = getArg(p, j); } assert(mtop == ctop); /*shouldn;t happen */#ifdef DEBUG_OPT_MACRO for (i = 0; i < ctop; i++) printf("match %d %d\n", cvar[i], mvar[i]);#endif p = getInstrPtr(mb, pc); q = copyInstruction(getInstrPtr(mc, 0)); /* the signature */ q->token = ASSIGNsymbol; mb->stmt[pc] = q; for (i = q->retc; i < q->argc; i++) for (j = 0; j < ctop; j++) if (q->argv[i] == cvar[j]) { q->argv[i] = mvar[j]; break; } rq = getInstrPtr(mc, mc->stop - 2); for (i = 0; i < rq->retc; i++) for (j = 0; j < ctop; j++) if (rq->argv[i] == cvar[j]) { q->argv[i] = mvar[j]; break; } freeInstruction(p); /* strip signature, return, and end statements */ k = mc->stop - 3; j = pc + k; for (i = pc + 1; i < pc + k; i++) freeInstruction(mb->stmt[i]); for (i = pc + 1; i < mb->stop - k; i++) mb->stmt[i] = mb->stmt[j++]; k = i; for (; i < mb->stop; i++) mb->stmt[i] = 0; mb->stop = k; return pc;}static strORCAMprocessor(MalBlkPtr mb, Symbol t){ MalBlkPtr mc = t->def; int i; str msg = MAL_SUCCEED; if (t == NULL || mc->stop < 3) return msg;#ifdef DEBUG_OPT_MACRO printf("calling the ORCAM processor for %s\n", t->name);#endif /* strip signature, return, and end statements */ for (i = 1; i < mb->stop - mc->stop + 3; i++) if (malFcnMatch(mc, mb, i)) {#ifdef DEBUG_OPT_MACRO printf("found match for %s at %d \n", t->name, i);#endif msg = MACROvalidate(mc); if (msg == MAL_SUCCEED) replaceMALblock(mb, i, mc); else break; } chkProgram(MCgetClient()->nspace, mb); return msg;}@-The optimizer call infrastructure is identical to the linersfunction with the exception that here we inline all possiblefunctions, regardless their@c@= implementationstatic intOPT@1Implementation(MalBlkPtr mb, MalStkPtr stk, InstrPtr p){ MalBlkPtr target= mb; Module s; Symbol t; str mod,fcn; int j; (void) p; (void) stk; if( p->argc == 3){ mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); } else { mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); s = findModule(MCgetClient()->nspace, putName(mod, strlen(mod))); if (s == 0) return 0; t= findSymbolInModule(s, fcn); if( t == 0) return 0; target= t->def; mod= getArgDefault(mb,p,3); fcn= getArgDefault(mb,p,4); } s = findModule(MCgetClient()->nspace, putName(mod, strlen(mod))); if (s == 0) return 0; if (s->subscope) { j = getSubScope(fcn); for (t = s->subscope[j]; t != NULL; t = t->peer) if (t->def->errors == 0) { if (getSignature(t)->token == FUNCTIONsymbol) @2processor(target, t); } } return 1;}@c@:implementation(macro,MACRO)@@:implementation(orcam,ORCAM)@@- Optimizer code wrapperThe optimizer wrapper code is the interface to the MAL optimizer calls.It prepares the environment for the optimizers to do their work and removesthe call itself to avoid endless recursions.Before an optimizer is finished, it should leave a clean state behind.Moreover, the information of the optimization step is saved fordebugging and analysis.The wrapper expects the optimizers to return the number ofactions taken, i.e. number of succesful changes to the code.This code is slightly different from other optimizerwrappers, because the mod.fcn argument is optional.@= exportOptimizeropt_export str OPT@1(MalBlkPtr mb, MalStkPtr stk, InstrPtr p);@= wrapOptimizerstr OPT@1(MalBlkPtr mb, MalStkPtr stk, InstrPtr p){ Module s; Symbol t; str msg,mod,fcn; lng clk= GDKusec(); int actions = 0; optimizerInit(); if( p->argc == 3){ mod= getArgDefault(mb,p,1); fcn= getArgDefault(mb,p,2); } else { mod= getArgDefault(mb,p,3); fcn= getArgDefault(mb,p,4); } s = findModule(MCgetClient()->nspace, putName(mod, strlen(mod))); if (s == 0) return 0; t= findSymbolInModule(s, fcn); if( t == 0) return 0; msg = MACROvalidate(t->def); if( msg) return msg; if( mb->errors == 0) actions= OPT@1Implementation(mb,stk,p); if( p ) removeInstruction(mb, p); optimizerCheck(mb, "optimizer.@1", actions, GDKusec() - clk, OPT_CHECK_ALL); return MAL_SUCCEED;}@h@:exportOptimizer(macro)@@c@:wrapOptimizer(macro)@@h@:exportOptimizer(orcam)@@c@:wrapOptimizer(orcam,OPT_CHECK_ALL)@@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -