⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 named_sc_op.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 3 页
字号:
        }        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 + -