void opt_const_unchecked(ENODE **node) { dfs.printf("<OptConst2>"); opt0(node); fold_const(node); opt0(node); dfs.printf("</OptConst2>"); }
// // apply all constant optimizations. // void opt_const(ENODE **node) { if (opt_noexpr==FALSE) { opt0(node); fold_const(node); opt0(node); } }
void opt4(ENODE ** node) /* * apply all constant optimizations. */ { opt0(node); fold_const2(node); opt0(node); }
// // apply all constant optimizations. // void opt_const(ENODE **node) { dfs.printf("<OptConst>"); if (opt_noexpr==FALSE) { opt0(node); fold_const(node); opt0(node); } dfs.printf("</OptConst>"); }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ static void opt0(ENODE **node) { ENODE *ep; int sc; int64_t val; ep = *node; if( ep == (ENODE *)NULL ) return; switch( (*node)->nodetype ) { case en_vector_ref: case en_ref32: case en_ref32u: case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_quad_ref: case en_wp_ref: case en_hp_ref: case en_ccwp: case en_cucwp: opt0(&((*node)->p[0])); return; case en_cubw: case en_cucw: case en_cuhw: case en_cubu: case en_cucu: case en_cuhu: case en_cbu: case en_ccu: case en_chu: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: opt0( &(ep->p[0])); if (ep->p[0]->nodetype == en_icon) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } return; case en_sxb: case en_sxc: case en_sxh: case en_zxb: case en_zxc: case en_zxh: case en_abs: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) dooper(*node); return; case en_compl: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ~ep->p[0]->i; } return; case en_not: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = !ep->p[0]->i; } return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_tempref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } else if (ep->constflag) { ep->nodetype = en_icon; } return; case en_tempfpref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_fcon ) { ep->nodetype = en_fcon; ep->f = ep->p[0]->f; Float128::Assign(&ep->f128,&ep->p[0]->f128); } return; case en_vadd: case en_vsub: case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if(ep->p[0]->nodetype == en_icon) { if(ep->p[1]->nodetype == en_icon) { dooper(*node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } // Place the constant node second in the add to allow // use of immediate mode instructions. if (ep->nodetype==en_add) swap_nodes(ep); } // Add or subtract of zero gets eliminated. else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_ptrdif: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[4])); if (ep->p[0]->nodetype == en_icon) { if (ep->p[1]->nodetype == en_icon && ep->p[4]->nodetype == en_icon) { dooper(*node); return; } } break; case en_i2d: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_icon) { dooper(*node); return; } break; case en_d2i: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_fcon) { ep->i = (long)ep->p[0]->f; ep->nodetype = en_icon; return; } break; case en_fadd: case en_fsub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } } break; case en_fmul: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } //else if (ep->p[1]->nodetype == en_icon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->f * ep->p[1]->i; // return; //} } //else if (ep->p[0]->nodetype == en_icon) { // if (ep->p[1]->nodetype == en_fcon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->i * ep->p[1]->f; // return; // } //} break; case en_fdiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } //else if (ep->p[1]->nodetype == en_icon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->f / ep->p[1]->i; // return; //} } break; case en_isnullptr: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_icon) dooper(*node); return; case en_mulf: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon) dooper(*node); return; case en_vmul: case en_vmuls: case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(*node); return; } if (ep->p[1]->nodetype == en_fcon) { ep->nodetype = en_icon; ep->i = ep->p[0]->i * ep->p[1]->f; return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; return; } // Place constant as oper2 swap_nodes(ep); } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; return; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(*node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; if ((*node)->nodetype == en_udiv) ep->nodetype = en_shru; else ep->nodetype = ep->p[0]->isUnsigned ? en_shru : en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(*node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon) dooper(*node); else if (ep->p[0]->nodetype == en_icon) swap_nodes(ep); break; case en_shr: case en_shru: case en_asr: case en_asl: case en_shl: case en_shlu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(*node); // Shift by zero.... else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } break; case en_land_safe: case en_land: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_lor_safe: case en_lor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_feq: case en_fne: case en_flt: case en_fle: case en_fgt: case en_fge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon && ep->p[1]->nodetype == en_fcon) dooper(*node); break; case en_veq: case en_vne: case en_vlt: case en_vle: case en_vgt: case en_vge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_safe_cond: case en_cond: opt0(&(ep->p[0])); opt0(&(ep->p[1]->p[0])); opt0(&(ep->p[1]->p[1])); if ((ep->p[0]->nodetype==en_icon||ep->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[0]->nodetype==en_icon || ep->p[1]->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[1]->nodetype==en_icon || ep->p[1]->p[1]->nodetype==en_cnacon)) dooper(*node); break; case en_chk: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[2])); break; case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_fcall: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; // en_tempref comes from typecasting case en_void: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_tempref) { (*node)->nodetype = ep->p[1]->nodetype; *node = ep->p[1]; } break; case en_addrof: opt0(&(ep->p[0])); break; case en_list: for (ep = ep->p[2]; ep; ep = ep->p[2]) opt0(&(ep->p[0])); break; } }
void opt0(ENODE ** node) /* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ { ENODE *ep; int sc,mode,val; double dval; ep = *node; if( ep == 0 ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uw_ref: /* optimize unary node */ case en_l_ref: case en_ul_ref: case en_floatref: case en_doubleref: case en_longdoubleref: case en_cb: case en_cub: case en_cw: case en_cuw: case en_cl: case en_cul: case en_cf: case en_cd: case en_cp: case en_bits: case en_cld: case en_ainc: case en_adec: case en_not: case en_compl: opt0( &((*node)->v.p[0])); return; case en_uminus: opt0( &(ep->v.p[0])); if( isintconst(ep->v.p[0]->nodetype)) { ep->nodetype = ep->v.p[0]->nodetype; ep->v.i = -ep->v.p[0]->v.i; } else if( ep->v.p[0]->nodetype == en_rcon || ep->v.p[0]->nodetype == en_fcon || ep->v.p[0]->nodetype == en_lrcon) { ep->nodetype = ep->v.p[0]->nodetype; ep->v.i = -ep->v.p[0]->v.f; } return; case en_add: case en_sub: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch (mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (ep->v.p[0]->v.i == 0) { if (ep->nodetype == en_sub) { *node = makenode(en_uminus,ep->v.p[1],0); } else *node = ep->v.p[1]; } else dooper(node,mode); break; case 6: if (ep->v.p[0]->v.f == 0) { if (ep->nodetype == en_sub) { *node = ep->v.p[1]; ep->v.p[1]->v.f = - ep->v.p[1]->v.f; } else *node = ep->v.p[1]; } else dooper(node,mode); break; case 7: if (ep->v.p[1]->v.i == 0) { *node = ep->v.p[0]; } else dooper(node,mode); break; case 8: if (ep->v.p[1]->v.f == 0) { *node = ep->v.p[0]; } else dooper(node,mode); break; } return; case en_mul: case en_umul: case en_pmul: case en_asmul: case en_asumul: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (!floatrecurse(ep->v.p[1])) { sc = pwrof2(ep->v.p[0]->v.i); if( sc != -1 ) { ENODE *temp = ep->v.p[0]; ep->v.p[0 ] = ep->v.p[1]; ep->v.p[1] = temp; ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_mul: ep->nodetype = en_alsh; break; case en_asmul: ep->nodetype = en_asalsh; break; case en_umul: case en_pmul: ep->nodetype = en_lsh; break; case en_asumul: ep->nodetype = en_aslsh; break; } break; } } val = ep->v.p[0]->v.i; if (val == 0) *node = ep->v.p[0]; else if (val == 1) *node = ep->v.p[1]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[1],0); else dooper(node,mode); break; case 6: dval = ep->v.p[0]->v.f; if (dval == 0) *node = ep->v.p[0]; else if (dval == 1) *node = ep->v.p[1]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[1],0); else dooper(node,mode); break; case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_mul: ep->nodetype = en_alsh; break; case en_asmul: ep->nodetype = en_asalsh; break; case en_umul: case en_pmul: ep->nodetype = en_lsh; break; case en_asumul: ep->nodetype = en_aslsh; break; } break; } } val = ep->v.p[1]->v.i; if (val == 0) *node = ep->v.p[1]; else if (val == 1) *node = ep->v.p[0]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; case 8: dval = ep->v.p[1]->v.f; if (dval == 0) *node = ep->v.p[1]; else if (dval == 1) *node = ep->v.p[0]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; } break; case en_pdiv: case en_div: case en_udiv: case en_asdiv: case en_asudiv: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (ep->v.p[0]->v.i == 0) *node = ep->v.p[0]; else dooper(node,mode); break; case 6: if (ep->v.p[0]->v.f == 0) *node = ep->v.p[0]; else dooper(node,mode); break; case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_div: ep->nodetype = en_arsh; break; case en_asdiv: ep->nodetype = en_asarsh; break; case en_udiv: case en_pdiv: ep->nodetype = en_rsh; break; case en_asudiv: ep->nodetype = en_asrsh; break; } break; } } val = ep->v.p[1]->v.i; if (val == 1) *node = ep->v.p[0]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; case 8: dval = ep->v.p[1]->v.f; if (dval == 1) *node = ep->v.p[0]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; } break; case en_mod: case en_umod: case en_asmod: case en_asumod: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = mod_mask(sc); if (ep->nodetype == en_asmod || ep->nodetype == en_asumod) ep->nodetype = en_asand; else ep->nodetype = en_and; break; } } case 1: case 2: case 3: case 4: case 5: case 6: case 8: dooper(node,mode); } break; case en_and: case en_or: case en_xor: case en_rsh: case en_lsh: case en_arsh: case en_alsh: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); if( isintconst(ep->v.p[0]->nodetype) && isintconst(ep->v.p[1]->nodetype) ) dooper(node,getmode(ep->v.p[0],ep->v.p[1])); break; case en_land: case en_lor: case en_lt: case en_le: case en_ugt: case en_uge: case en_ult: case en_ule: case en_gt: case en_ge: case en_eq: case en_ne: case en_asalsh: case en_asarsh: case en_asand: case en_asor: case en_asxor: case en_asadd: case en_assub: case en_asrsh: case en_aslsh: case en_cond: case en_fcall: case en_void: case en_trapcall: case en_intcall: case en_pfcall: case en_pfcallb: case en_assign: case en_moveblock: case en_stackblock: case en_callblock: case en_fcallb: case en_refassign: case en_pcallblock: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); break; } }
/* * apply all constant optimizations. */ void opt4(struct enode **node) { opt0(node); fold_const(node); opt0(node); }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ void opt0(ENODE **node) { ENODE *ep; __int64 val, sc; ep = *node; if( ep == NULL ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: case en_ainc: case en_adec: case en_not: case en_compl: opt0( &((*node)->p[0])); return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } } else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: case en_shr: case en_shru: case en_shl: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(node); break; case en_land: case en_lor: case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_cond: case en_fcall: case en_void: case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; } }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ static void opt0(ENODE **node) { ENODE *ep; int64_t val, sc; ep = *node; if( ep == (ENODE *)NULL ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_cubw: case en_cucw: case en_cuhw: case en_cubu: case en_cucu: case en_cuhu: case en_cbu: case en_ccu: case en_chu: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: case en_ainc: case en_adec: opt0( &((*node)->p[0])); return; case en_compl: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ~ep->p[0]->i; } return; case en_not: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = !ep->p[0]->i; } return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_tempref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } return; case en_tempfpref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_fcon ) { ep->nodetype = en_fcon; ep->f = ep->p[0]->f; } return; case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } } else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; if ((*node)->nodetype == en_udiv) ep->nodetype = en_shru; else ep->nodetype = ep->p[0]->isUnsigned ? en_shru : en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: case en_shr: case en_shru: case en_asr: case en_shl: case en_shlu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(node); break; case en_land: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) { dooper(node); break; } break; case en_lor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) { dooper(node); break; } break; case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(node); break; case en_feq: case en_fne: case en_flt: case en_fle: case en_fgt: case en_fge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_cond: opt0(&(ep->p[0])); opt0(&(ep->p[1]->p[0])); opt0(&(ep->p[1]->p[1])); if ((ep->p[0]->nodetype==en_icon||ep->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[0]->nodetype==en_icon || ep->p[1]->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[1]->nodetype==en_icon || ep->p[1]->p[1]->nodetype==en_cnacon)) dooper(node); break; case en_chk: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[2])); break; case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_fcall: case en_void: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; } }