📄 optimize.c
字号:
break; case en_test: ep0 = ep->v.p[0]; switch (ep0->nodetype) { case en_test: ep = ep0->v.p[0]; return optnode (ep); case en_not: ep = ep0; return optnode (ep); case en_icon: case en_fcon: ep = dooper (ep); return ep; case en_labcon: case en_sym: ep->nodetype = en_icon; ep->v.i = 1L; return ep; default: break; } break; case en_not: ep0 = ep->v.p[0]; switch (ep0->nodetype) { case en_not: /* * !(!a) => a */ ep->nodetype = en_test; ep->v.p[0] = ep0->v.p[0]; return optnode (ep); case en_icon: case en_fcon: ep = dooper (ep); return ep; case en_test: ep->v.p[0] = ep0->v.p[0]; return optnode (ep); case en_lor: /* * !(a || b) => !a && !b */ ep = ep0; ep->nodetype = en_land; ep->v.p[0] = mk_node (en_not, ep->v.p[0], NIL_EXPR, tp); ep->v.p[1] = mk_node (en_not, ep->v.p[1], NIL_EXPR, tp); return optnode (ep); case en_land: /* * !(a && b) => !a || !b */ ep = ep0; ep->nodetype = en_lor; ep->v.p[0] = mk_node (en_not, ep->v.p[0], NIL_EXPR, tp); ep->v.p[1] = mk_node (en_not, ep->v.p[1], NIL_EXPR, tp); return optnode (ep); case en_cond: /* * !(a ? b : c) => a ? !b : !c */ ep = ep0; ep1 = ep->v.p[1]; ep1->v.p[0] = mk_node (en_not, ep1->v.p[0], NIL_EXPR, tp); ep1->v.p[1] = mk_node (en_not, ep1->v.p[1], NIL_EXPR, tp); return optnode (ep); case en_labcon: case en_sym: ep->nodetype = en_icon; ep->v.i = 0L; return ep; default: break; } break; case en_cast: ep0 = ep->v.p[0]; if (is_compatible_type (tp, ep0->etp)) { ep0->etp = tp; return optnode (ep0); /* redundant cast */ } switch (ep0->nodetype) { case en_icon: case en_fcon: ep = dooper (ep); return ep; case en_register: if ((ep0->etp->size == 4L) && (tp->size == 4L) && is_integral_type (ep0->etp) && is_integral_type (tp)) { ep0->etp = tp; return ep0; } break; case en_add: case en_sub: case en_mul: case en_div: case en_mod: case en_and: case en_or: case en_xor: case en_lsh: case en_rsh: case en_land: case en_lor: case en_eq: case en_ne: case en_lt: case en_le: case en_gt: case en_ge: /* * Find where the operands to an operator have been cast to * a wider type only for the result to be cast back to the * narrower type. */ if (is_subtype (ep0->etp, tp)) { ep1 = ep0->v.p[0]; ep2 = ep0->v.p[1]; if ((ep1->nodetype == en_cast) && (ep2->nodetype == en_cast)) { if (is_subtype (tp, ep1->v.p[0]->etp) && is_subtype (tp, ep2->v.p[0]->etp)) { ep1->etp = tp; ep2->etp = tp; ep0->etp = tp; return optnode (ep0); } } else if ((ep1->nodetype == en_cast) && (is_icon (ep2))) { if (is_subtype (tp, ep1->v.p[0]->etp) && is_constant_in_range (ep2, tp)) { ep1->etp = tp; ep0->etp = tp; return optnode (ep0); } } else if (is_icon (ep1) && (ep2->nodetype == en_cast)) { if (is_subtype (tp, ep2->v.p[0]->etp) && is_constant_in_range (ep1, tp)) { ep2->etp = tp; ep0->etp = tp; return optnode (ep0); } } } break; default: break; } break; case en_add: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; if (is_icon (ep->v.p[0]) || (ep0->nodetype == en_uminus) || (ep1->nodetype == en_autocon)) { swap_nodes (ep); ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; } /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (ep1->nodetype == en_uminus) { /* * a + (-b) => a - b */ ep->v.p[1] = ep1->v.p[0]; ep->nodetype = en_sub; return optnode (ep); } if (is_icon (ep1)) { switch (ep0->nodetype) { case en_autocon: ep = ep0; ep->v.i += ep1->v.i; ep->etp = tp; return ep; default: if (ep1->v.i == 0L) { /* * a + 0 => a */ ep = ep0; ep->etp = tp; return ep; } break; } } break; case en_sub: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (ep1->nodetype == en_uminus) { /* * a - (-b) => a + b */ ep->v.p[1] = ep1->v.p[0]; ep->nodetype = en_add; return optnode (ep); } if (ep1->nodetype == en_sub) { /* * a - (b - c) => a + (c - b) */ swap_nodes (ep1); ep->nodetype = en_add; return optnode (ep); } if (is_icon (ep1) && (ep1->v.i == 0L)) { /* * a - 0 => a */ ep = ep0; ep->etp = tp; return ep; } if (is_icon (ep0) && (ep0->v.i == 0L)) { /* * 0 - a => -a */ ep->v.p[0] = ep1; ep->nodetype = en_uminus; return optnode (ep); } break; case en_mul: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; if (is_icon (ep0) || (ep0->nodetype == en_uminus)) { swap_nodes (ep); ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; } /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (ep1->nodetype == en_uminus) { /* * a * (-b) => -(a * b) */ ep->v.p[1] = ep1->v.p[0]; ep1->v.p[0] = ep; return optnode (ep1); } if (is_icon (ep1)) { val = ep1->v.i; if (val == (IVAL) 0) { /* * a * 0 => a , 0 */ ep = mk_node (en_comma, ep0, ep1, tp); return optnode (ep); } if (val == (IVAL) 1) { /* * a * 1 => a */ ep = ep0; return ep; } sc = (IVAL) pwrof2 (val); if (sc != (IVAL) -1) { /* * a * (2**n) => a << n */ ep->v.p[1]->v.i = sc; ep->nodetype = en_lsh; return optnode (ep); } } break; case en_div: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (ep1->nodetype == en_uminus) { /* * a / (-b) => -(a / b) */ ep->v.p[1] = ep1->v.p[0]; ep1->v.p[0] = ep; return optnode (ep1); } if (is_icon (ep0)) { if (ep0->v.i == 0L) { /* * 0/x => x,0 */ ep = mk_node (en_comma, ep1, ep0, tp); return optnode (ep); } } else if (is_icon (ep1)) { val = ep1->v.i; if (val == (IVAL) 1) { /* * x/1 => x */ ep = ep0; return optnode (ep); } if (is_unsigned_type (tp)) { sc = (IVAL) pwrof2 (val); if (sc != (IVAL) -1) { /* * x / (y**2) => x>>y */ ep->v.p[1]->v.i = sc; ep->nodetype = en_rsh; return optnode (ep); } } } break; case en_mod: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (is_icon (ep0)) { if (ep0->v.i == 0L) { /* * 0%x => x,0 */ ep = mk_node (en_comma, ep1, ep0, tp); return optnode (ep); } } if (is_icon (ep1)) { if (is_unsigned_type (tp)) { sc = (IVAL) pwrof2 (ep1->v.i); if (sc != (IVAL) -1) { /* * x % (y**2) => x & (y-1) */ ep->v.p[1]->v.u = bitmask ((BITSIZE) sc); ep->nodetype = en_and; return optnode (ep); } } } break; case en_lor: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (is_icon (ep0)) { if (ep0->v.i) { /* * 1 || a => 1 */ ep = ep0; ep->v.i = (IVAL) TRUE; } else { /* * 0 || a => a */ ep = ep1; } return optnode (ep); } if (is_icon (ep1) && (ep0->v.i == 0L)) { /* * a || 0 => a */ ep = ep0; return optnode (ep); } break; case en_land: ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (is_icon (ep0)) { /* * 0 && a => 0 * 1 && a => a */ /* short-circuit! */ ep = (ep0->v.i) ? ep1 : ep0; return optnode (ep); } if (is_icon (ep1) && (ep1->v.i != 0L)) { /* * a && 1 => a */ ep = ep0; return optnode (ep); } break; case en_eq: case en_ne: if (is_icon (ep->v.p[0]) || is_fcon (ep->v.p[0])) { swap_nodes (ep); } ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (is_icon (ep1) && (ep1->v.i == 0L)) { /* * a == 0 => !a * a != 0 => a */ ep->nodetype = (ep->nodetype == en_eq) ? en_not : en_test; return optnode (ep); }#ifdef FLOAT_SUPPORT if (is_fcon (ep1) && FEQ (ep1->v.f, F_zero)) { ep->nodetype = (ep->nodetype == en_eq) ? en_not : en_test; return optnode (ep); }#endif /* FLOAT_SUPPORT */ break; case en_and: case en_or: case en_xor: if (is_icon (ep->v.p[0])) { swap_nodes (ep); } ep0 = ep->v.p[0]; ep1 = ep->v.p[1]; /* * constant expressions */ if ((is_icon (ep0) && is_icon (ep1)) || (is_fcon (ep0) && is_fcon (ep1))) { ep = dooper (ep); return ep; } if (is_icon (ep1)) { switch (ep->nodetype) { case en_and: if (ep1->v.i == 0L) { /* * a & 0 => 0 */ ep = ep1; #ifndef LONGLONG_BOOTSTRAP } else if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) { /* * a & ~0 => a */ ep = optnode (ep0); #endif /* LONGLONG_BOOTSTRAP */ } break; case en_or: if (ep1->v.i == 0L) { /* * a | 0 => a */ ep = optnode (ep0); #ifndef LONGLONG_BOOTSTRAP } else if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) { /* * a | ~0 => ~0 */ ep = ep1; #endif /* LONGLONG_BOOTSTRAP */ } break; case en_xor: if (ep1->v.i == 0L) { /* * a ^ 0 => a */ ep = optnode (ep0); #ifndef LONGLONG_BOOTSTRAP } else if (ep1->v.i == (IVAL) ~(UVAL) 0x0UL) { /* * a ^ ~0 => ~a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -