Ejemplo n.º 1
0
void DEX_PASS_MGR::perform_scalar_opt(OPT_CTX & oc)
{
	LIST<IR_OPT*> opt_list; //A list of optimization.
	IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)register_opt(OPT_SSA_MGR);
	bool is_ssa_avail = false;
	if (ssamgr != NULL) {
		is_ssa_avail = ssamgr->is_ssa_construct();
	}

	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_RP));
	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_RP));
	opt_list.append_tail(register_opt(OPT_CP));
	opt_list.append_tail(register_opt(OPT_DCE));
	opt_list.append_tail(register_opt(OPT_LOOP_CVT));
	opt_list.append_tail(register_opt(OPT_LICM));
	opt_list.append_tail(register_opt(OPT_GCSE));

	((IR_DCE*)register_opt(OPT_DCE))->set_elim_cfs(false);
	((IR_DCE*)register_opt(OPT_DCE))->set_ssa_available(is_ssa_avail);

	if (opt_list.get_elem_count() != 0) {
		LOG("\tScalar optimizations for '%s'", m_ru->get_ru_name());
	}

	bool change;
	UINT count = 0;
	//do {
		change = false;
		for (IR_OPT * opt = opt_list.get_head();
			 opt != NULL; opt = opt_list.get_next()) {
			CHAR const* optn = opt->get_opt_name();
			LOG("\t\tpass %s", optn);
			IS_TRUE0(verify_ir_and_bb(m_ru->get_bb_list(), m_dm));
			ULONGLONG t = getusec();

			//dump_bbs(m_ru->get_bb_list(), "before");
			//m_ru->get_cfg()->dump_vcg("before.vcg");

			bool doit = opt->perform(oc);

			//dump_bbs(m_ru->get_bb_list(), "after");
			//m_ru->get_cfg()->dump_vcg("after.vcg");

			append_ti(opt->get_opt_name(), getusec() - t);
			if (doit) {
				LOG("\t\t\tchanged");
				change = true;
				IS_TRUE0(verify_ir_and_bb(m_ru->get_bb_list(), m_dm));
				IS_TRUE0(m_ru->get_cfg()->verify());
			}
		}
		count++;
	//} while (change && count < 20);
	//IS_TRUE0(!change);
}
Ejemplo n.º 2
0
void DEX_REGION::process_simply(OUT PRNO2UINT & prno2v, UINT param_num,
								UINT vregnum, DEX2IR & d2ir, UINT2PR * v2pr,
								IN PRNO2UINT * pr2v, TYIDR * tr)
{
	LOG("\t\t Invoke DEX_REGION::process_simply '%s'", get_ru_name());
	if (get_ir_list() == NULL) { return ; }
	OPT_CTX oc;
	OPTC_show_comp_time(oc) = g_show_comp_time;

	CHAR const* ru_name = get_ru_name();

	construct_ir_bb_list();

	IS_TRUE0(verify_ir_and_bb(get_bb_list(), get_dm()));

	RU_ana(this)->m_ir_list = NULL; //All IRs have been moved to each IR_BB.

	IR_CFG * cfg = init_cfg(oc);
	cfg->loop_analysis(oc);

	PASS_MGR * pm = new_pass_mgr();
	OPTC_pass_mgr(oc) = pm; //record pass manager.

	if (g_do_ssa && OPTC_pass_mgr(oc) != NULL) {
		//Convert program to ssa form.
		IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)OPTC_pass_mgr(oc)->
									register_opt(OPT_SSA_MGR);
		IS_TRUE0(ssamgr);
		ssamgr->construction(oc, this);
	}

	init_aa(oc);

	init_du(oc);

	IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)pm->query_opt(OPT_SSA_MGR);
	if (ssamgr != NULL && ssamgr->is_ssa_construct()) {
		//Destruct ssa form.
		ssamgr->destruction_in_bblist_order();
	}

	delete pm;

	OPTC_pass_mgr(oc) = NULL;

	#if 1
	//Do not allocate register.
	prno2v.clean();
	prno2v.copy(*d2ir.get_pr2v_map());
	return;
	#else
	//Allocate register.
	RA ra(this, tr, param_num, vregnum, v2pr, pr2v, &m_var2pr);
	LOG("\t\tdo DEX Register Allcation for '%s'", ru_name);
	ra.perform(oc);
	update_ra_res(ra, prno2v);
	#endif
}
Ejemplo n.º 3
0
void DEX_REGION::process(OUT PRNO2UINT & prno2v, UINT param_num, UINT vregnum,
						 UINT2PR * v2pr, IN PRNO2UINT * pr2v, TYIDR * tr)
{
	if (get_ir_list() == NULL) { return; }
	OPT_CTX oc;
	OPTC_show_comp_time(oc) = g_show_comp_time;

	g_indent = 0;
	note("\n==---- REGION_NAME:%s ----==", get_ru_name());
	prescan(get_ir_list());

	RU_is_pr_unique_for_same_no(this) = true;

	//g_do_ssa = true;

	PASS_MGR * pm = new_pass_mgr();

	OPTC_pass_mgr(oc) = pm;

	high_process(oc);

	middle_process(oc);

	IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)pm->query_opt(OPT_SSA_MGR);
	if (ssamgr != NULL && ssamgr->is_ssa_construct()) {
		ssamgr->destruction_in_bblist_order();
	}
	delete pm;

	OPTC_pass_mgr(oc) = NULL;

	if (RU_type(this) != RU_FUNC) { return; }

	IR_BB_LIST * bbl = get_bb_list();
	if (bbl->get_elem_count() == 0) { return; }

	IS_TRUE0(verify_ir_and_bb(bbl, get_dm()));

	RF_CTX rf;
	RC_insert_cvt(rf) = false; //Do not insert cvt for DEX code.
	refine_ir_bb_list(bbl, rf);
	IS_TRUE0(verify_ir_and_bb(bbl, get_dm()));

	RA ra(this, tr, param_num, vregnum, v2pr, pr2v, &m_var2pr);
	LOG("\t\tdo DEX Register Allcation for '%s'", get_ru_name());
	ra.perform(oc);
	update_ra_res(ra, prno2v);
}
Ejemplo n.º 4
0
bool DEX_REGION::high_process(OPT_CTX & oc)
{
	CHAR const* ru_name = get_ru_name();
	g_indent = 0;
	SIMP_CTX simp;
	SIMP_if(&simp) = 1;
	SIMP_do_loop(&simp) = 1;
	SIMP_do_while(&simp) = 1;
	SIMP_while_do(&simp) = 1;
	SIMP_switch(&simp) = 0;
	SIMP_break(&simp) = 1;
	SIMP_continue(&simp) = 1;

	RU_ana(this)->m_ir_list = simplify_stmt_list(get_ir_list(), &simp);

	IS_TRUE0(verify_simp(get_ir_list(), simp));
	IS_TRUE0(verify_irs(get_ir_list(), NULL, get_dm()));

	construct_ir_bb_list();

	IS_TRUE0(verify_ir_and_bb(get_bb_list(), get_dm()));

	RU_ana(this)->m_ir_list = NULL; //All IRs have been moved to each IR_BB.

	IS_TRUE0(g_do_cfg && g_do_aa && g_do_du_ana && g_do_cdg);

	IR_CFG * cfg = init_cfg(oc);
	cfg->loop_analysis(oc);

	if (g_do_ssa && OPTC_pass_mgr(oc) != NULL) {
		IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)OPTC_pass_mgr(oc)->
									register_opt(OPT_SSA_MGR);
		IS_TRUE0(ssamgr);
		ssamgr->construction(oc, this);
	}

	init_aa(oc);

	init_du(oc);

	if (g_opt_level == NO_OPT) {
		return false;
	}
	return true;
}
Ejemplo n.º 5
0
/*
Perform general optimizaitions.
Basis step to do:
	1. Build control flow.
	2. Compute data flow dependence.
	3. Compute live expression info.

Optimizations to be performed:
	1. GCSE
	2. DCE
	3. RVI(register variable recog)
	4. IVR(induction variable elimination)
	5. CP(constant propagation)
	6. CP(copy propagation)
	7. SCCP (Sparse Conditional Constant Propagation).
	8. PRE (Partial Redundancy Elimination) with strength reduction.
	9. Dominator-based optimizations such as copy propagation,
	    constant propagation and redundancy elimination using
	    value numbering.
	10. Must-alias analysis, to convert pointer de-references
		into regular variable references whenever possible.
	11. Scalar Replacement of Aggregates, to convert structure
		references into scalar references that can be optimized
		using the standard scalar passes.
*/
bool REGION::middle_process(OPT_CTX & oc)
{
	if (g_opt_level == NO_OPT) { return false; }
	g_indent = 0;

	CHAR const* runame = get_ru_name();

	PASS_MGR * passmgr = OPTC_pass_mgr(oc);
	IS_TRUE0(passmgr);

	IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)passmgr->query_opt(OPT_SSA_MGR);
	if (ssamgr == NULL || !ssamgr->is_ssa_construct()) {
		lower_to_do_scalar_opt(*this, oc);
	}

	//Perform scalar optimizations.
	OPTC_pass_mgr(oc)->perform_scalar_opt(oc);
	return true;
}
Ejemplo n.º 6
0
/* Perform high-level optimizaitions.
Basis step to do:
    1. Build control flow graph.
    2. Compute POINT-TO info.
    3. Compute DEF-USE info.
    4. Compute Lived Expression info.

Optimizations to be performed:
    1. Auto Parallel
    2. Loop interchange
    3. Loop reverese(may be a little helpful)
    4. Loop tiling
    5. Loop fusion
    6. Loop unrolling */
bool Region::HighProcess(OptCTX & oc)
{
    g_indent = 0;
    note("\n\n==== Region:%s HIGHEST LEVEL FARMAT ====\n\n", get_ru_name());

    SimpCTX simp;
    if (g_do_cfs_opt) {
        IR_CFS_OPT co(this);
        co.perform(simp);
        ASSERT0(verify_irs(get_ir_list(), NULL, this));
    }

    PassMgr * passmgr = initPassMgr();
    ASSERT0(passmgr);

    if (g_build_cfs) {
        SIMP_is_record_cfs(&simp) = true;
        CfsMgr * cfsmgr = (CfsMgr*)passmgr->registerPass(PASS_CFS_MGR);
        ASSERT0(cfsmgr);
        SIMP_cfs_mgr(&simp) = cfsmgr;
    }

    simp.set_simp_cf();
    set_ir_list(simplifyStmtList(get_ir_list(), &simp));
    ASSERT0(verify_simp(get_ir_list(), simp));
    ASSERT0(verify_irs(get_ir_list(), NULL, this));

    if (g_cst_bb_list) {
        constructIRBBlist();
        ASSERT0(verifyIRandBB(get_bb_list(), this));
        set_ir_list(NULL); //All IRs have been moved to each IRBB.
    }

    if (g_do_cfg) {
        ASSERT0(g_cst_bb_list);
        IR_CFG * cfg = (IR_CFG*)passmgr->registerPass(PASS_CFG);
        ASSERT0(cfg);
        cfg->initCfg(oc);
        if (g_do_loop_ana) {
            ASSERT0(g_do_cfg_dom);
            cfg->LoopAnalysis(oc);
        }
    }

    if (g_do_ssa) {
        //Note lowering IR now may be too early and will be
        //a hindrance to optmizations.
        //low_to_pr_mode(oc);
        IR_SSA_MGR * ssamgr = (IR_SSA_MGR*)passmgr->registerPass(PASS_SSA_MGR);
        ASSERT0(ssamgr);
        ssamgr->construction(oc);
    }

    if (g_do_aa) {
        ASSERT0(g_cst_bb_list && OC_is_cfg_valid(oc));
        IR_AA * aa = (IR_AA*)passmgr->registerPass(PASS_AA);
        ASSERT0(aa);
        aa->initAliasAnalysis();
        aa->perform(oc);
    }

    if (g_do_du_ana) {
        ASSERT0(g_cst_bb_list && OC_is_cfg_valid(oc) && OC_is_aa_valid(oc));
        IR_DU_MGR * dumgr = (IR_DU_MGR*)passmgr->registerPass(PASS_DU_MGR);
        ASSERT0(dumgr);

        UINT f = SOL_REACH_DEF|SOL_REF;
        //f |= SOL_AVAIL_REACH_DEF|SOL_AVAIL_EXPR|SOL_RU_REF;

        if (g_do_ivr) {
            f |= SOL_AVAIL_REACH_DEF|SOL_AVAIL_EXPR;
        }

        if (g_do_compute_available_exp) {
            f |= SOL_AVAIL_EXPR;
        }

        dumgr->perform(oc, f);
        dumgr->computeMDDUChain(oc);
    }

    if (g_do_expr_tab) {
        ASSERT0(g_cst_bb_list);
        IR_EXPR_TAB * exprtab =
            (IR_EXPR_TAB*)passmgr->registerPass(PASS_EXPR_TAB);
        ASSERT0(exprtab);
        exprtab->perform(oc);
    }

    if (g_do_cdg) {
        ASSERT0(g_cst_bb_list && OC_is_cfg_valid(oc));
        CDG * cdg = (CDG*)passmgr->registerPass(PASS_CDG);
        ASSERT0(cdg);
        cdg->build(oc, *get_cfg());
    }

    if (g_opt_level == NO_OPT) {
        return false;
    }

    /* Regenerate high level IR, and do high level optimizations.
    Now, I get one thing: We cannot or not very easy
    construct High Level Control IR,
    (IF,DO_LOOP,...) via analysing CFG.
        e.g:

            if (i > j) { //BB1
                ...
            } else {
                return 2; //S1
            }
        BB1 does not have a ipdom, so we can not find the indispensible 3 parts:
            True body, False body, and the Sibling node.

    Solution: We can scan IF stmt first, in order to mark
    start stmt and end stmt of IF.

    //AbsNode * an = REGION_analysis_instrument(this)->m_cfs_mgr->construct_abstract_cfs();
    //Polyhedra optimization.
    //IR_POLY * poly = newPoly();
    //if (poly->construct_poly(an)) {
    //    poly->perform_poly_trans();
    //}
    //delete poly;
    */
    return true;
}
Ejemplo n.º 7
0
void PassMgr::performScalarOpt(OptCtx & oc)
{
    TTab<Pass*> opt_tab;
    List<Pass*> passlist;
    SimpCtx simp;
    if (g_do_gvn) { registerPass(PASS_GVN); }

    if (g_do_pre) {
        //Do PRE individually.
        //Since it will incur the opposite effect with Copy-Propagation.
        Pass * pre = registerPass(PASS_PRE);
        pre->perform(oc);
        ASSERT0(verifyIRandBB(m_ru->get_bb_list(), m_ru));
    }

    if (g_do_dce) {
        IR_DCE * dce = (IR_DCE*)registerPass(PASS_DCE);
        passlist.append_tail(dce);
        if (g_do_dce_aggressive) {
            dce->set_elim_cfs(true);
        }
    }

    bool in_ssa_form = false;
    IR_SSA_MGR * ssamgr =
            (IR_SSA_MGR*)(m_ru->get_pass_mgr()->queryPass(PASS_SSA_MGR));
    if (ssamgr != NULL && ssamgr->is_ssa_constructed()) {
        in_ssa_form = true;
    }

    if (!in_ssa_form) {
        //RP can reduce the memory operations and
        //improve the effect of PR SSA, so perform
        //RP before SSA construction.
        //TODO: Do SSA renaming when after register promotion done.
        if (g_do_rp) {
            //First RP.
            passlist.append_tail(registerPass(PASS_RP));
        }
    }

    if (g_do_cp) {
        IR_CP * pass = (IR_CP*)registerPass(PASS_CP);
        pass->set_prop_kind(CP_PROP_SIMPLEX);
        passlist.append_tail(pass);
    }

    if (g_do_rp) {
        //Second RP.
        passlist.append_tail(registerPass(PASS_RP));
    }

    if (g_do_gcse) {
        passlist.append_tail(registerPass(PASS_GCSE));
    }

    if (g_do_lcse) {
        passlist.append_tail(registerPass(PASS_LCSE));
    }

    if (g_do_rce) {
        passlist.append_tail(registerPass(PASS_RCE));
    }

    if (g_do_dse) {
        passlist.append_tail(registerPass(PASS_DSE));
    }

    if (g_do_licm) {
        passlist.append_tail(registerPass(PASS_LICM));
    }

    if (g_do_ivr) {
        passlist.append_tail(registerPass(PASS_IVR));
    }

    if (g_do_loop_convert) {
        passlist.append_tail(registerPass(PASS_LOOP_CVT));
    }

    bool change;
    UINT count = 0;
    BBList * bbl = m_ru->get_bb_list();
    IR_CFG * cfg = m_ru->get_cfg();
    UNUSED(cfg);
    do {
        change = false;
        for (Pass * pass = passlist.get_head();
             pass != NULL; pass = passlist.get_next()) {
            CHAR const* passname = pass->get_pass_name();
            ASSERT0(verifyIRandBB(bbl, m_ru));
            ULONGLONG t = getusec();
            bool doit = pass->perform(oc);
            appendTimeInfo(passname, getusec() - t);
            if (doit) {
                change = true;
                ASSERT0(verifyIRandBB(bbl, m_ru));
                ASSERT0(cfg->verify());
            }
            RefineCtx rc;
            m_ru->refineBBlist(bbl, rc);
            ASSERT0(m_ru->verifyRPO(oc));
        }
        count++;
    } while (change && count < 20);
    ASSERT0(!change);

    if (g_do_lcse) {
        IR_LCSE * lcse = (IR_LCSE*)registerPass(PASS_LCSE);
        lcse->set_enable_filter(false);
        ULONGLONG t = getusec();
        lcse->perform(oc);
        t = getusec() - t;
        appendTimeInfo(lcse->get_pass_name(), t);
    }

    if (g_do_rp) {
        IR_RP * r = (IR_RP*)registerPass(PASS_RP);
        ULONGLONG t = getusec();
        r->perform(oc);
        appendTimeInfo(r->get_pass_name(), getusec() - t);
    }
}