Пример #1
0
/*
Return VAR if there is already related to 's',
otherwise create a new VAR.
'var_name': name of the variable, it is optional.
's': string's content.
*/
VAR * VAR_MGR::register_str(CHAR const* var_name, SYM * s, UINT align)
{
	IS_TRUE0(s != NULL);
	VAR * v;
	if ((v = m_str_tab.get(s)) != NULL) {
		return v;
	}
	v = new_var();
	CHAR buf[64];
	if (var_name == NULL) {
		sprintf(buf, ".rodata_%zu", m_str_count++);
		VAR_name(v) = m_ru_mgr->add_to_symtab(buf);
	} else {
		VAR_name(v) = m_ru_mgr->add_to_symtab(var_name);
	}
	VAR_str(v) = s;
	VAR_data_type(v) = D_STR;
	VAR_elem_type(v) = D_UNDEF;
	IS_TRUE0(sizeof(CHAR) == 1);
	VAR_data_size(v) = xstrlen(SYM_name(s)) + 1;
	VAR_align(v) = align;
	VAR_is_global(v) = 1; //store in .data or .rodata

	assign_var_id(v);
	m_str_tab.set(s, v);
	return v;
}
Пример #2
0
CHAR const* get_class_name(DexFile * df, DexClassDef const* class_info)
{
	IS_TRUE0(class_info);
	CHAR const* class_name = dexStringByTypeIdx(df, class_info->classIdx);
	IS_TRUE0(class_name);
	return class_name;
}
Пример #3
0
ABS_NODE * CFS_MGR::construct_abs_loop(
						IN IR_BB * entry,
						IN ABS_NODE * parent,
						IN BITSET * cur_region,
						IN GRAPH & cur_graph,
						IN OUT BITSET & visited)
{
	IS_TRUE0(cur_region == NULL || cur_region->is_contain(IR_BB_id(entry)));
	IR_CFG * cfg = m_ru->get_cfg();
	LI<IR_BB> * li = cfg->map_bb2li(entry);
	IS_TRUE0(li != NULL && LI_loop_head(li) == entry);

	ABS_NODE * node = new_abs_node(ABS_LOOP);
	set_map_bb2abs(entry, node);
	ABS_NODE_parent(node) = parent;
	ABS_NODE_loop_head(node) = entry;
	IR_BB * body_start;
	cfg->get_loop_two_kids(entry, NULL, &body_start);
	IS_TRUE0(body_start != NULL);

	CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
	IS_TRUE0(ci != NULL && CFS_INFO_head(ci) == entry);

	IS_TRUE0(CFS_INFO_loop_body(ci)->is_contain(*LI_bb_set(li)));
	BITSET loc_visited;
	ABS_NODE_loop_body(node) = construct_abs_tree(body_start, node,
												  LI_bb_set(li),
												  cur_graph, loc_visited);
	visited.bunion(loc_visited);
	visited.bunion(IR_BB_id(entry));
	return node;
}
Пример #4
0
EDGE * GRAPH::new_edge(VERTEX * from, VERTEX * to)
{
	IS_TRUE(m_pool != NULL, ("not yet initialized."));
	if (from == NULL || to == NULL) return NULL;
	EDGE teste;
	VERTEX testfrom, testto;
	if (m_is_unique) {
		VERTEX_id(&testfrom) = VERTEX_id(from);
		VERTEX_id(&testto) = VERTEX_id(to);
		EDGE_from(&teste) = &testfrom;
		EDGE_to(&teste) = &testto;
		if (m_is_direction) {			
			return m_edges.append((ULONG)&teste, NULL);
		} else {
			EDGE * e = NULL;
			if (m_edges.find(&teste, &e)) {
				IS_TRUE0(e);
				return e;
			}
			
			//Both check from->to and to->from
			EDGE_from(&teste) = &testto;
			EDGE_to(&teste) = &testfrom;
			return m_edges.append((ULONG)&teste, NULL);
		}
		IS_TRUE0(0);
	}
	return m_edges.append(new_edge_c(from, to));
}
Пример #5
0
//All global prs must be mapped.
bool DEX_REGION::verify_ra_res(RA & ra, PRNO2UINT & prno2v)
{
	GLTM * gltm = ra.get_gltm();
	SVECTOR<GLT*> * gltv = gltm->get_gltvec();
	for (UINT i = 0; i < gltm->get_num_of_glt(); i++) {
		GLT * g = gltv->get(i);
		if (g == NULL) { continue; }
		IS_TRUE0(g->has_allocated());
		if (GLT_bbs(g) == NULL) {
			//parameter may be have no occ.
			continue;
		}
		bool find;
		prno2v.get(GLT_prno(g), &find);
		IS_TRUE0(find);
	}

	IR_BB_LIST * bbl = get_bb_list();
	for (IR_BB * bb = bbl->get_head(); bb != NULL; bb = bbl->get_next()) {
		LTM * ltm = gltm->map_bb2ltm(bb);
		if (ltm == NULL) { continue; }
		SVECTOR<LT*> * lvec = ltm->get_lt_vec();
		for (INT i = 0; i <= lvec->get_last_idx(); i++) {
			LT * l = lvec->get(i);
			if (l == NULL) { continue; }
			IS_TRUE0(l->has_allocated());
			bool find;
			prno2v.get(LT_prno(l), &find);
			IS_TRUE0(find);
		}
	}
	return true;
}
Пример #6
0
void DEX_REGION::update_ra_res(IN RA & ra, OUT PRNO2UINT & prno2v)
{
	prno2v.maxreg = ra.get_maxreg();
	prno2v.paramnum = ra.get_paramnum();
	GLTM * gltm = ra.get_gltm();
	IR_BB_LIST * bbl = get_bb_list();
	prno2v.clean();
	for (IR_BB * bb = bbl->get_head(); bb != NULL; bb = bbl->get_next()) {
		LTM * ltm = gltm->map_bb2ltm(bb);
		if (ltm == NULL) { continue; }
		SVECTOR<LT*> * lvec = ltm->get_lt_vec();
		for (INT i = 0; i <= lvec->get_last_idx(); i++) {
			LT * l = lvec->get(i);
			if (l == NULL) { continue; }
			IS_TRUE0(l->has_allocated());
			bool find;
			UINT v = prno2v.get(LT_prno(l), &find);
			if (find) {
				//each prno is corresponding to a unqiue vreg.
				IS_TRUE0(v == LT_phy(l));
			} else {
				prno2v.set(LT_prno(l), LT_phy(l));
			}
		}
	}
	prno2v.dump();
	IS_TRUE0(verify_ra_res(ra, prno2v));
}
Пример #7
0
VN * IR_GVN::comp_sc_by_anon_domdef(IR const* exp, IR const* domdef,
									bool & change)
{
	IS_TRUE0((IR_type(exp) == IR_LD || IR_type(exp) == IR_PR) &&
			 m_du->is_may_def(domdef, exp, false));
	SCVNE2VN * vnexp_map = m_def2sctab.get(domdef);
	UINT dtsz = exp->get_dt_size(m_dm);
	MD const* md = exp->get_exact_ref();
	IS_TRUE0(md);
	VNE_SC vexp(MD_id(md), exp->get_ofst(), dtsz);
	/*
	NOTE:
		foo();
		v1; //s1
		goo();
		v1; //s2
		vn of s1 should not same with s2.
	*/
	if (vnexp_map == NULL) {
		vnexp_map = new SCVNE2VN(m_pool, 16); //bsize to be evaluate.
		m_def2sctab.set(domdef, vnexp_map);
	}
	VN * vn = vnexp_map->get(&vexp);
	if (vn == NULL) {
		vn = new_vn();
		VN_type(vn) = VN_VAR;
		vnexp_map->setv((OBJTY)&vexp, vn);
	}
	m_ir2vn.set(IR_id(exp), vn);
	change = true;
	return vn;
}
Пример #8
0
//GVN try to assign a value numbers to expressions.
bool IR_GVN::perform(OPT_CTX & oc)
{
	IR_BB_LIST * bbl = m_ru->get_bb_list();
	if (bbl->get_elem_count() == 0) { return false; }

	START_TIMER_AFTER();
	m_ru->check_valid_and_recompute(&oc, OPT_DU_CHAIN, OPT_DU_REF, OPT_RPO,
									OPT_DOM, OPT_UNDEF);

	LIST<IR_BB*> * tbbl = m_cfg->get_bblist_in_rpo();
	IS_TRUE0(tbbl->get_elem_count() == bbl->get_elem_count());

	UINT count = 0;
	bool change = true;

	#ifdef DEBUG_GVN
	while (change && count < 10) {
		change = false;
	#endif
		for (IR_BB * bb = tbbl->get_head();
			 bb != NULL; bb = tbbl->get_next()) {
			process_bb(bb, change);
		} //end for BB
		count++;
	#ifdef DEBUG_GVN
	} //end while
	IS_TRUE0(!change && count <= 2);
	#endif

	//dump();
	END_TIMER_AFTER(get_opt_name());
	IS_TRUE0(verify());
	m_is_valid = true;
	return true;
}
Пример #9
0
//Return true if gvn is able to determine the result of 'ir'.
bool IR_GVN::calc_cond_must_val(IN IR const* ir,
								bool & must_true, bool & must_false)
{
	must_true = false;
	must_false = false;
	IS_TRUE0(ir->is_judge());
	VN const* v1 = m_ir2vn.get(IR_id(BIN_opnd0(ir)));
	VN const* v2 = m_ir2vn.get(IR_id(BIN_opnd1(ir)));
	if (v1 == NULL || v2 == NULL) return false;
	switch (IR_type(ir)) {
	case IR_LT:
	case IR_GT:
		if (v1 == v2) {
			must_true = false;
			must_false = true;
			return true;
		}
		break;
	case IR_LE:
	case IR_GE:
		if (v1 == v2) {
			must_true = true;
			must_false = false;
			return true;
		}
		break;
	case IR_NE:
		if (v1 == v2) {
			must_true = false;
			must_false = true;
			return true;
		}
		if (v1 != v2) {
			must_true = true;
			must_false = false;
			return true;
		}
		IS_TRUE0(0);
		break;
	case IR_EQ:
		if (v1 == v2) {
			must_true = true;
			must_false = false;
			return true;
		}
		if (v1 != v2) {
			must_true = false;
			must_false = true;
			return true;
		}
		IS_TRUE0(0);
		break;
	case IR_LAND:
	case IR_LOR:
	case IR_LNOT:
		break;
	default: IS_TRUE0(0);
	}
	return false;
}
Пример #10
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);
}
Пример #11
0
CHAR const* AOC_DX_MGR::get_method_name(UINT method_idx)
{
	DexMethodId const* method_id = dexGetMethodId(m_df, method_idx);
	IS_TRUE0(method_id);
	CHAR const* method_name = dexStringById(m_df, method_id->nameIdx);
	IS_TRUE0(method_name);
	return method_name;
}
Пример #12
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
}
Пример #13
0
//'var_name': name of the variable, it is optional.
VAR * VAR_MGR::register_var(SYM * var_name, UINT tyid, UINT align, UINT flag)
{
	IS_TRUE0(var_name != NULL && tyid != 0);
	DTD const* d = m_dm->get_dtd(tyid);
	IS_TRUE0(d);
	return register_var(var_name, DTD_rty(d), DTD_vec_ety(d),
						DTD_ptr_base_sz(d), m_dm->get_dtd_bytesize(d),
						align, flag);
}
Пример #14
0
/*
NOTE: IPA should only be performed in top level region,
since it might incur the memory blow up.
*/
bool IPA::perform(OPT_CTX & oc)
{
	IS_TRUE0(OPTC_is_callg_valid(oc));
	REGION * top = m_ru_mgr->get_top_region();
	if (top == NULL) return false;
	IS_TRUE0(RU_type(top) == RU_PROGRAM);
	//start do cp_prop
	//...
	//
	return true;
}
Пример #15
0
//Return true if b is control dependent on a.
bool CDG::is_cd(UINT a, UINT b)
{
	IS_TRUE0(get_vertex(b));
	VERTEX * v = get_vertex(a);
	IS_TRUE0(v != NULL);
	EDGE_C * out = VERTEX_out_list(v);
	while (out != NULL) {
		if (VERTEX_id(EDGE_to(EC_edge(out))) == b) {
			return true;
		}
		out = EC_next(out);
	}
	return false;
}
Пример #16
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);
}
Пример #17
0
VN * IR_GVN::register_bin_vn(IR_TYPE irt, VN const* v0, VN const* v1)
{
	IS_TRUE0(v0 && v1);
	if (is_commutative(irt) && (VN_id(v0) > VN_id(v1))) {
		return register_bin_vn(irt, v1, v0);
	} else if (irt == IR_GT) {
		return register_bin_vn(IR_LT, v1, v0);
	} else if (irt == IR_GE) {
		return register_bin_vn(IR_LE, v1, v0);
	}
	VEC2 * v0_vec = m_irt_vec.get(irt);
	if (v0_vec == NULL) {
		v0_vec = new VEC2();
		m_vec_lst.append_tail((SVECTOR<VN*>*)v0_vec);
		m_irt_vec.set(irt, v0_vec);
	}

	VEC1 * v1_vec = v0_vec->get(VN_id(v0));
	if (v1_vec == NULL) {
		v1_vec = new VEC1();
		m_vec_lst.append_tail((SVECTOR<VN*>*)v1_vec);
		m_vnvec_lst.append_tail(v1_vec);
		v0_vec->set(VN_id(v0), v1_vec);
	}

	VN * res = v1_vec->get(VN_id(v1));
	if (res == NULL) {
		res = new_vn();
		VN_type(res) = VN_OP;
		VN_op(res) = irt;
		v1_vec->set(VN_id(v1), res);
	}
	return res;
}
Пример #18
0
LABEL_INFO * new_label(SMEM_POOL * pool)
{
	LABEL_INFO * p = (LABEL_INFO*)smpool_malloc_h(sizeof(LABEL_INFO), pool);
	IS_TRUE0(p);
	memset(p, 0, sizeof(LABEL_INFO));
	return p;
}
Пример #19
0
//Compute VN for array according to anonymous domdef.
VN * IR_GVN::comp_array_by_anon_domdef(IR const* arr, VN const* basevn,
									   VN const* ofstvn, IR const* domdef,
									   bool & change)
{
	IS_TRUE0(IR_type(arr) == IR_ARRAY && m_du->is_may_def(domdef, arr, false));
	ARR_VNE2VN * vnexp_map = m_def2arrtab.get(domdef);
	UINT dtsz = arr->get_dt_size(m_dm);
	VNE_ARR vexp(VN_id(basevn), VN_id(ofstvn), ARR_ofst(arr), dtsz);
	/* NOTE:
		foo();
		array(v1); //s1
		goo();
		array(v1); //s2
		vn of s1 should not same with s2. */
	if (vnexp_map == NULL) {
		vnexp_map = new ARR_VNE2VN(m_pool, 16); //bsize to be evaluate.
		m_def2arrtab.set(domdef, vnexp_map);
	}
	VN * vn = vnexp_map->get(&vexp);
	if (vn == NULL) {
		vn = new_vn();
		VN_type(vn) = VN_OP;
		VN_op(vn) = IR_ARRAY;
		vnexp_map->setv((OBJTY)&vexp, vn);
	}
	m_ir2vn.set(IR_id(arr), vn);
	change = true;
	return vn;
}
Пример #20
0
	//Attemp to compute POINT-TO set via the IR type.
	virtual MD * comp_point_to_via_type(IR const* ir)
	{
		IR_AI * ai = IR_ai(ir);
		IS_TRUE0(ir && ai);

		TBAA_AI * ty = (TBAA_AI*)ai->get(IRAI_TBAA);
		if (ty == NULL) { return NULL; }

		MD * md = m_tyid2md.get(ty->tyid);
		if (md != NULL) {
			return md;
		}

		CHAR buf[64];
		sprintf(buf, "dummy%d", ty->tyid);
		VAR * dummy = m_var_mgr->register_var(buf,
											D_MC, D_UNDEF,
											0, 1, 1, VAR_GLOBAL);
		VAR_is_addr_taken(dummy) = true;
		VAR_allocable(dummy) = false;
		m_ru->add_to_var_tab(dummy);

		MD dummy_md;
		MD_base(&dummy_md) = dummy;
		MD_size(&dummy_md) = 0;
		MD_ty(&dummy_md) = MD_UNBOUND;
		MD_is_addr_taken(&dummy_md) = true;
		MD * entry = m_md_sys->register_md(dummy_md);
		m_tyid2md.set(ty->tyid, entry);
		return entry;
	}
Пример #21
0
void dump_lab(LABEL_INFO const* li)
{
	if (g_tfile == NULL) return;
	if (LABEL_INFO_type(li) == L_ILABEL) {
		fprintf(g_tfile, "\nilabel(" ILABEL_STR_FORMAT ")",
				ILABEL_CONT(li));
	} else if (LABEL_INFO_type(li) == L_CLABEL) {
		fprintf(g_tfile, "\nclabel(" CLABEL_STR_FORMAT ")",
				CLABEL_CONT(li));
	} else if (LABEL_INFO_type(li) == L_PRAGMA) {
		fprintf(g_tfile, "\npragms(%s)",
				SYM_name(LABEL_INFO_pragma(li)));
	} else { IS_TRUE0(0); }

	if (LABEL_INFO_b1(li) != 0) {
		fprintf(g_tfile, "(");
	}
	if (LABEL_INFO_is_try_start(li)) {
		fprintf(g_tfile, "try_start ");
	}
	if (LABEL_INFO_is_try_end(li)) {
		fprintf(g_tfile, "try_end ");
	}
	if (LABEL_INFO_is_catch_start(li)) {
		fprintf(g_tfile, "catch_start ");
	}
	if (LABEL_INFO_is_used(li)) {
		fprintf(g_tfile, "used ");
	}
	if (LABEL_INFO_b1(li) != 0) {
		fprintf(g_tfile, ")");
	}
	fflush(g_tfile);
}
Пример #22
0
CHAR const* AOC_DX_MGR::get_class_name_by_declaration_id(UINT cls_def_idx)
{
	DexClassDef const* class_info = dexGetClassDef(m_df, cls_def_idx);
	CHAR const* class_name = dexStringByTypeIdx(m_df, class_info->classIdx);
	IS_TRUE0(class_name);
	return class_name;
}
Пример #23
0
void DGRAPH::sort_dom_tree_in_preorder(IN GRAPH & dom_tree, IN VERTEX * root,
									   OUT LIST<VERTEX*> & lst)
{
	IS_TRUE0(root);
	BITSET is_visited;
	is_visited.bunion(VERTEX_id(root));
	lst.append_tail(root);
	
	VERTEX * v;
	SSTACK<VERTEX*> stk;
	stk.push(root);
	while ((v = stk.pop()) != NULL) {
		if (!is_visited.is_contain(VERTEX_id(v))) {
			is_visited.bunion(VERTEX_id(v));
			stk.push(v);
			//The only place to process vertex.
			lst.append_tail(v);			
		}
		
		//Visit children.
		EDGE_C * el = VERTEX_out_list(v);
		VERTEX * succ;
		while (el != NULL) {
			succ = EDGE_to(EC_edge(el));
			if (!is_visited.is_contain(VERTEX_id(succ))) {
				stk.push(v);
				stk.push(succ);
				break;
			}
			el = EC_next(el);
		}		
	}
}
Пример #24
0
CHAR const* AOC_DX_MGR::get_class_name_by_method_id(UINT method_idx)
{
	DexMethodId const* method_id = dexGetMethodId(m_df, method_idx);
	IS_TRUE0(method_id);
	CHAR const* class_name = dexStringByTypeIdx(m_df, method_id->classIdx);
	return class_name;
}
Пример #25
0
//'cur_region' covered 'entry'.
ABS_NODE * CFS_MGR::construct_abs_if(
						IN IR_BB * entry,
						IN ABS_NODE * parent,
						IN GRAPH & cur_graph,
						IN OUT BITSET & visited)
{
	ABS_NODE * node = new_abs_node(ABS_IF);
	set_map_bb2abs(entry, node);
	ABS_NODE_parent(node) = parent;
	ABS_NODE_if_head(node) = entry;

	IR_BB * true_body, * false_body;
	IR_CFG * cfg = m_ru->get_cfg();
	cfg->get_if_three_kids(entry, &true_body, &false_body, NULL);
	CFS_INFO * ci = map_ir2cfsinfo(cfg->get_last_xr(entry));
	IS_TRUE0(ci != NULL && CFS_INFO_head(ci) == entry);

	BITSET loc_visited;
	ABS_NODE_true_body(node) = construct_abs_tree(true_body, node, CFS_INFO_true_body(ci), cur_graph, loc_visited);
	visited.bunion(loc_visited);
	loc_visited.clean();
	ABS_NODE_false_body(node) = construct_abs_tree(false_body, node, CFS_INFO_false_body(ci), cur_graph, loc_visited);
	visited.bunion(loc_visited);
	visited.bunion(IR_BB_id(entry));
	return node;
}
Пример #26
0
void DGRAPH::sort_dom_tree_in_postorder(IN GRAPH & dom_tree, IN VERTEX * root,
										OUT LIST<VERTEX*> & lst)
{
	IS_TRUE0(root);
	BITSET is_visited;

	//Find the leaf node.
	VERTEX * v;
	SSTACK<VERTEX*> stk;
	stk.push(root);
	while ((v = stk.pop()) != NULL) {
		//Visit children first.
		EDGE_C * el = VERTEX_out_list(v);
		bool find = false; //find unvisited kid.
		VERTEX * succ;
		while (el != NULL) {
			succ = EDGE_to(EC_edge(el));
			if (!is_visited.is_contain(VERTEX_id(succ))) {
				stk.push(v);
				stk.push(succ);
				find = true;
				break;
			}
			el = EC_next(el);
		}
		if (!find) {
			is_visited.bunion(VERTEX_id(v));
			//The only place to process vertex.
			lst.append_tail(v);
		}
	}	
}
Пример #27
0
static void * xmalloc(ULONG size)
{
	void * p = smpool_malloc_h(size, g_pool_general_used);
	IS_TRUE0(p);
	memset(p, 0, size);
	return p;
} 
Пример #28
0
//Compute VN for ild according to anonymous domdef.
VN * IR_GVN::comp_ild_by_anon_domdef(IR const* ild, VN const* mlvn,
									 IR const* domdef, bool & change)
{
	IS_TRUE0(IR_type(ild) == IR_ILD && m_du->is_may_def(domdef, ild, false));
	ILD_VNE2VN * vnexp_map = m_def2ildtab.get(domdef);
	UINT dtsz = ild->get_dt_size(m_dm);
	VNE_ILD vexp(VN_id(mlvn), ILD_ofst(ild), dtsz);
	/*
	NOTE:
		foo();
		ild(v1); //s1
		goo();
		ild(v1); //s2
		vn of s1 should not same with s2.
	*/
	if (vnexp_map == NULL) {
		vnexp_map = new ILD_VNE2VN(m_pool, 16); //bsize to be evaluate.
		m_def2ildtab.set(domdef, vnexp_map);
	}
	VN * ildvn = vnexp_map->get(&vexp);
	if (ildvn == NULL) {
		ildvn = new_vn();
		VN_type(ildvn) = VN_OP;
		VN_op(ildvn) = IR_ILD;
		vnexp_map->setv((OBJTY)&vexp, ildvn);
	}
	m_ir2vn.set(IR_id(ild), ildvn);
	change = true;
	return ildvn;
}
Пример #29
0
//'var_name': name of the variable, it is optional.
VAR * VAR_MGR::register_var(CHAR const* var_name, UINT tyid,
							UINT align, UINT flag)
{
	IS_TRUE0(var_name != NULL && tyid != 0);
	SYM * sym = m_ru_mgr->add_to_symtab(var_name);
	return register_var(sym, tyid, align, flag);
}
Пример #30
0
/* Find preheader BB. If it does not exist, insert one before loop 'li'.

'insert_bb': return true if this function insert a new bb before loop,
	otherwise return false.

'force': force to insert preheader BB whatever it has exist.
	Return the new BB if insertion is successful.

Note if we find the preheader, the last IR of it may be call.
So if you are going to insert IR at the tail of preheader, the best is
force to insert a new bb. */
IR_BB * find_and_insert_prehead(LI<IR_BB> const* li, REGION * ru,
								OUT bool & insert_bb,
								bool force)
{
	IS_TRUE0(li && ru);
	insert_bb = false;
	IR_CFG * cfg = ru->get_cfg();
	IR_BB_LIST * bblst = ru->get_bb_list();
	IR_BB * head = LI_loop_head(li);

	C<IR_BB*> * bbholder = NULL;
	bblst->find(head, &bbholder);
	IS_TRUE0(bbholder);
	C<IR_BB*> * tt = bbholder;
	IR_BB * prev = bblst->get_prev(&tt);

	//Find appropriate BB to be prehead.
	bool find_appropriate_prev_bb = false;
	EDGE_C const* ec = VERTEX_in_list(cfg->get_vertex(IR_BB_id(head)));
	while (ec != NULL) {
		UINT pred = VERTEX_id(EDGE_from(EC_edge(ec)));
		if (pred == IR_BB_id(prev)) {
			find_appropriate_prev_bb = true;
			break;
		}
		ec = EC_next(ec);
	}

	if (!force && find_appropriate_prev_bb) { return prev; }

	LIST<IR_BB*> preds;
	cfg->get_preds(preds, head);
	insert_bb = true;
	IR_BB * newbb = ru->new_bb();
	bblst->insert_before(newbb, bbholder);
	BITSET * loop_body = LI_bb_set(li);
	for (IR_BB * p = preds.get_head(); p != NULL; p = preds.get_next()) {
		if (loop_body->is_contain(IR_BB_id(p))) {
			continue;
		}
		cfg->add_bb(newbb);
		cfg->insert_vertex_between(IR_BB_id(p), IR_BB_id(head),
								   IR_BB_id(newbb));
		IR_BB_is_fallthrough(newbb) = 1;
	}
	return newbb;
}