mpdm_t mpsl_mkins(wchar_t * opcode, int args, mpdm_t a1, mpdm_t a2, mpdm_t a3, mpdm_t a4) /* creates an instruction */ { mpdm_t o; mpdm_t v; v = MPDM_A(args + 1); mpdm_ref(v); /* inserts the opcode */ o = mpdm_hget_s(mpsl_opcodes, opcode); mpdm_aset(v, o, 0); switch (args) { case 4: mpdm_aset(v, a4, 4); /* no break */ case 3: mpdm_aset(v, a3, 3); /* no break */ case 2: mpdm_aset(v, a2, 2); /* no break */ case 1: mpdm_aset(v, a1, 1); /* no break */ } mpdm_unrefnd(v); v = constant_fold(v); return v; }
bool qir_opt_constant_folding(struct vc4_compile *c) { bool progress = false; qir_for_each_inst_inorder(inst, c) { if (constant_fold(c, inst)) progress = true; } return progress; }
TREE* constant_fold(CSOUND *csound, TREE* root) { extern MYFLT MOD(MYFLT, MYFLT); TREE* current = root; while (current) { switch (current->type) { case '+': case '-': case '*': case '/': case '^': case '%': case '|': case '&': case '#': case S_BITSHIFT_LEFT: case S_BITSHIFT_RIGHT: current->left = constant_fold(csound, current->left); current->right = constant_fold(csound, current->right); //print_tree(csound, "Folding case??\n", current); if ((current->left->type == INTEGER_TOKEN || current->left->type == NUMBER_TOKEN) && (current->right->type == INTEGER_TOKEN || current->right->type == NUMBER_TOKEN)) { MYFLT lval, rval; char buf[64]; lval = (current->left->type == INTEGER_TOKEN ? (double)current->left->value->value : current->left->value->fvalue); rval = (current->right->type == INTEGER_TOKEN ? (double)current->right->value->value : current->right->value->fvalue); //printf("lval = %g rval = %g\n", lval, rval); switch (current->type) { case '+': lval = lval + rval; break; case '-': lval = lval - rval; break; case '*': lval = lval * rval; break; case '/': lval = lval / rval; break; case '^': lval = POWER(lval,rval); break; case '%': lval = MOD(lval,rval); break; case '|': lval = (MYFLT)(((int)lval)|((int)rval)); break; case '&': lval = (MYFLT)(((int)lval)&((int)rval)); break; case '#': lval = (MYFLT)(((int)lval)^((int)rval)); break; case S_BITSHIFT_LEFT: lval = (MYFLT)(((int)lval)<<((int)rval)); break; case S_BITSHIFT_RIGHT: lval = (MYFLT)(((int)lval)>>((int)rval)); break; } //printf("ans = %g\n", lval); current->value = current->left->value; current->type = NUMBER_TOKEN; current->value->fvalue = lval; snprintf(buf, 60, "%.20g", lval); csound->Free(csound, current->value->lexeme); current->value->lexeme = cs_strdup(csound, buf); csound->Free(csound, current->left); csound->Free(csound, current->right->value); csound->Free(csound, current->right); current->right = current->left = NULL; } break; case S_UMINUS: case '~': //print_tree(csound, "Folding case?\n", current); current->right = constant_fold(csound, current->right); //print_tree(csound, "Folding case??\n", current); if (current->right->type == INTEGER_TOKEN || current->right->type == NUMBER_TOKEN) { MYFLT lval; char buf[64]; lval = (current->right->type == INTEGER_TOKEN ? (double)current->right->value->value : current->right->value->fvalue); switch (current->type) { case S_UMINUS: lval = -lval; break; case '~': lval = (MYFLT)(~(int)lval); break; } current->value = current->right->value; current->type = NUMBER_TOKEN; current->value->fvalue = lval; snprintf(buf, 60, "%.20g", lval); csound->Free(csound, current->value->lexeme); current->value->lexeme = cs_strdup(csound, buf); csound->Free(csound, current->right); current->right = NULL; } break; default: current->left = constant_fold(csound, current->left); current->right = constant_fold(csound, current->right); } current = current->next; }