📄 named_sc_op.cc
字号:
} for(int ip=0; ip<res.p(); ip++) res[ip][0][xc] += int_coeff*sc[ip][0][0]; }}static void put_index_info(operand op, named_symcoeff_ineq & res, int & too_messy, int int_factor = 1, named_lin_ineq * sc_factor = NULL){ if(op.kind() == OPER_SYM) { if(op.symbol()->is_var() == 0) { too_messy++; return; } add_sym(res, too_messy, (var_sym *)op.symbol(), int_factor, sc_factor); return; } if(op.kind() != OPER_INSTR) { too_messy++; return; } instruction * ins = op.instr(); in_rrr *i3r = (in_rrr *) ins; if(ins->format() == inf_rrr) { int val; if(is_const(operand(ins), &val)) { add_sym(res, too_messy, NULL, val*int_factor, sc_factor); return; } } else if(ins->format() == inf_ldc) { in_ldc * ld = (in_ldc *)ins; if(ld->value().is_integer()) add_sym(res, too_messy, NULL, (ld->value().integer())*int_factor, sc_factor); else too_messy++; return; } switch(ins->opcode()) { // not that io_cvt is too messy. That way we can assume that // lods have the correct type, and in general it allows us // to rebuild from the access vectors. default: too_messy++; break; case io_lod: too_messy++; break; case io_neg: put_index_info(i3r->src1_op(), res, too_messy, -int_factor, sc_factor); break; case io_cvt: put_index_info(i3r->src1_op(), res, too_messy, int_factor, sc_factor); break; case io_add: put_index_info(i3r->src1_op(), res, too_messy, int_factor, sc_factor); put_index_info(i3r->src2_op(), res, too_messy, int_factor, sc_factor); break; case io_sub: put_index_info(i3r->src1_op(), res, too_messy, int_factor, sc_factor); put_index_info(i3r->src2_op(), res, too_messy, -int_factor, sc_factor); break; case io_mul: { int val; // var*const or const*var // if(sc_factor is NULL) then var*sym_const or sym_const*var if(is_const(i3r->src1_op(), &val)) put_index_info(i3r->src2_op(), res, too_messy, int_factor * val, sc_factor); else if(is_const(i3r->src2_op(), &val)) put_index_info(i3r->src1_op(), res, too_messy, int_factor * val, sc_factor); else if(sc_factor == NULL) { boolean ind1 = is_index_var_in(i3r->src1_op(), i3r->parent()); boolean ind2 = is_index_var_in(i3r->src2_op(), i3r->parent()); named_symcoeff_ineq path; path.add_ineq(1); if(ind1 && ind2) too_messy++; else if(ind1) { put_index_info(i3r->src2_op(), path, too_messy, 1, NULL); if(path.p() > 1) too_messy++; named_lin_ineq lin_path(path.cols(), path[0]); put_index_info(i3r->src1_op(), res, too_messy, int_factor, &lin_path); } else { put_index_info(i3r->src1_op(), path, too_messy, 1, NULL); if(path.p() > 1) too_messy++; named_lin_ineq lin_path(path.cols(), path[0]); put_index_info(i3r->src2_op(), res, too_messy, int_factor, &lin_path); } } else too_messy++; } break; case io_div: case io_divfloor: case io_divceil: { int val; // var/const if(!is_const(i3r->src2_op(),&val) || (val == 0) || int_factor % val) too_messy++; else put_index_info(i3r->src1_op(), res, too_messy, int_factor / val, sc_factor); } break; case io_lsl: { int val; if(!is_const(i3r->src2_op(), &val) || val < 0) too_messy++; else put_index_info(i3r->src1_op(), res, too_messy, int_factor<<val, sc_factor); } break; case io_cpy: put_index_info(i3r->src1_op(), res, too_messy, int_factor, sc_factor); break; }}named_symcoeff_ineq * named_symcoeff_ineq::convert_exp(instruction * ins){ named_symcoeff_ineq * ret = new named_symcoeff_ineq; ret->add_ineq(1); int too_messy = 0; put_index_info(operand(ins), *ret, too_messy); if(too_messy > 0) { delete ret; return NULL; } return ret;}named_symcoeff_ineq * named_symcoeff_ineq::convert_exp(operand op){ named_symcoeff_ineq * ret = new named_symcoeff_ineq; ret->add_ineq(1); int too_messy = 0; put_index_info(op, *ret, too_messy); if(too_messy > 0) { delete ret; return NULL; } return ret;}static boolean do_mk_sc(named_symcoeff_ineq & ret, operand op, boolean lb){ named_symcoeff_ineq * curr = NULL; if(op.is_instr()) { instruction * in = op.instr(); in_rrr * rrr = (in_rrr *)in; if(in->opcode() == io_cvt) return do_mk_sc(ret, rrr->src1_op(), lb); else if(in->opcode() == io_max) { if(!lb) return FALSE; return do_mk_sc(ret, rrr->src1_op(), lb) && do_mk_sc(ret, rrr->src2_op(), lb); } else if(in->opcode() == io_min) { if(lb) return FALSE; return do_mk_sc(ret, rrr->src1_op(), lb) && do_mk_sc(ret, rrr->src2_op(), lb); } else curr = named_symcoeff_ineq::convert_exp(op); } else curr = named_symcoeff_ineq::convert_exp(op); if(curr) { ret || *curr; ret.add_ineq(0); lin_ineq * xm = curr->get_m(0); ret.set_m(0, xm); delete curr; return TRUE; } return FALSE;}named_symcoeff_ineq * named_symcoeff_ineq::mk_sc(operand op, immed ind, boolean lb){ named_symcoeff_ineq ret; if(do_mk_sc(ret, op, lb)) { ret.add_col(ind, 1); int im; for(im=0; im<ret.m(); im++) ret[0][im][1] = -1; if(lb) for(int ip=0; ip<ret.p(); ip++) for(im=0; im<ret.m(); im++) for(int in=0; in<ret.n(); in++) ret[ip][im][in] *= -1; return new named_symcoeff_ineq(ret); } return NULL; }named_symcoeff_ineq * include_sc_for(tree_for * tf){ assert(tf); boolean forward = TRUE; boolean ub_neq = FALSE; boolean lb_neq = FALSE; switch(tf->test()) { case FOR_SLTE: case FOR_ULTE: break; case FOR_SLT: case FOR_ULT: ub_neq = TRUE; break; case FOR_SGTE: case FOR_UGTE: forward = FALSE; break; case FOR_SGT: case FOR_UGT: forward = FALSE; lb_neq = TRUE; break; default: assert_msg(0, ("Test should not happen outside frontend\n")); } immed idx(tf->index()); operand lop = (forward)?(tf->lb_op()):(tf->ub_op()); named_symcoeff_ineq * cl = named_symcoeff_ineq::mk_sc(lop, idx, TRUE); if(cl == NULL) { fprintf(stderr,"Unknown lower bound for loop at line %d\n", source_line_num(tf)); return NULL; } operand uop = (forward)?(tf->ub_op()):(tf->lb_op()); named_symcoeff_ineq * cu = named_symcoeff_ineq::mk_sc(uop, idx, FALSE); if(cu == NULL) { fprintf(stderr,"Unknown upper bound for loop at line %d\n", source_line_num(tf)); delete cl; return NULL; } if(ub_neq) { // index < UB change to index <= UB-1 for(int i=0; i < cu->m(); i++) (*cu)[0][i][0] -= 1; } if(lb_neq) { // LB < index change to LB+1 <= index for(int i=0; i < cl->m(); i++) (*cl)[0][i][0] += 1; } cu = named_symcoeff_ineq::and_(cl, cu, 0, 1); named_symcoeff_ineq * stp = named_symcoeff_ineq::convert_exp(tf->step_op()); boolean stpbad = TRUE; if(stp) if((stp->n() == 1)&& // no sym variables (stp->p() == 1)&& // no sym Step (stp->m() == 1)) { // no max or mins if(ABS((*stp)[0][0][0]) == 1) // unit step stpbad = FALSE; } if(stpbad) { fprintf(stderr,"Unknown or symbolic step size for loop at line %d\n", source_line_num(tf)); delete cl; delete cu; if(stp) delete stp; return NULL; } cu->cleanup(); delete cl; delete stp; return cu;}static named_symcoeff_ineq * get_cond(operand op){ assert(op.is_instr()); assert(op.instr()->format() == inf_rrr); in_rrr * ir = (in_rrr *)op.instr(); named_symcoeff_ineq * l = named_symcoeff_ineq::convert_exp(ir->src1_op()); named_symcoeff_ineq * r = named_symcoeff_ineq::convert_exp(ir->src2_op()); if((l == NULL)||(r == NULL)) { if(l) delete l; if(r) delete r; return NULL; } named_symcoeff_ineq ret; switch(ir->opcode()) { case io_seq: // == ret = sub(*l, *r); ret = ret & sub(*r, *l); break; case io_sl: // < ret = sub(*r, *l); ret[0][0][0]--; break; case io_sle: // <= ret = sub(*r, *l); break; default: delete l; delete r; return NULL; } return new named_symcoeff_ineq(ret);} static named_symcoeff_ineq * get_cond(tree_node_list * hdr){ if(hdr->count() != 1) return NULL; assert((*hdr)[0]->is_instr()); tree_instr * ti = (tree_instr *)(*hdr)[0]; instruction * in = ti->instr(); if(in->opcode() != io_bfalse) return NULL; in_bj * ibf = (in_bj *)in; return get_cond(ibf->src_op());}named_symcoeff_ineq * include_sc_if_true(tree_if * ti){ named_symcoeff_ineq * nsi = get_cond(ti->header()); return nsi;}named_symcoeff_ineq * include_sc_if_false(tree_if * ti){ named_symcoeff_ineq * nsi = get_cond(ti->header()); if(nsi == NULL) return NULL; if(nsi->m() > 1) { delete nsi; return NULL; } *nsi = mul(*nsi, -1); (*nsi)[0][0][0] -= 1; return nsi;}named_symcoeff_ineq add(const named_symcoeff_ineq & a, const named_symcoeff_ineq & b){ named_symcoeff_ineq A(a); named_symcoeff_ineq B(b); A || B; assert(A.m() == B.m()); for(int ip =0; ip < A.p(); ip++) A[ip] = A[ip] + B[ip]; return A;}named_symcoeff_ineq sub(const named_symcoeff_ineq & a, const named_symcoeff_ineq & b){ named_symcoeff_ineq A(a); named_symcoeff_ineq B(b); A || B; assert(A.m() == B.m()); for(int ip =0; ip < A.p(); ip++) A[ip] = A[ip] - B[ip]; return A;}named_symcoeff_ineq minus(const named_symcoeff_ineq & a){ named_symcoeff_ineq A(a); for(int ip =0; ip < A.p(); ip++) A[ip] = A[ip]*-1; return A;}named_symcoeff_ineq mul(const named_symcoeff_ineq & a, int i){ named_symcoeff_ineq A(a); for(int ip =0; ip < A.p(); ip++) A[ip] = A[ip]*i; return A;}named_symcoeff_ineq mul(int i, const named_symcoeff_ineq & a){ return mul(a, i);}// BUGBUG: This is also a gross hack.named_symcoeff_ineq * mul(const named_symcoeff_ineq & a, const named_symcoeff_ineq & b){ base_symtab * bt = NULL; bt = a.const_cols().get_symtab(bt); bt = a.const_planes().get_symtab(bt); bt = b.const_cols().get_symtab(bt); bt = b.const_planes().get_symtab(bt); instruction * ina = a.create_expression(); instruction * inb = b.create_expression(); block mul = block(ina) * block(inb); instruction * inab = mul.make_instruction((block_symtab *)bt); named_symcoeff_ineq * ret = named_symcoeff_ineq::convert_exp(inab); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -