//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; }
//Register exact MD for each global variable. //Note you should call this function as early as possible, e.g, before process //all regions. Because that will assign smaller MD id to global variable. void RegionMgr::registerGlobalMD() { //Only top region can do initialize MD for global variable. ASSERT0(m_var_mgr); VarVec * varvec = m_var_mgr->get_var_vec(); for (INT i = 0; i <= varvec->get_last_idx(); i++) { VAR * v = varvec->get(i); if (v == NULL || VAR_is_local(v)) { continue; } ASSERT0(VAR_is_global(v)); //User sometime intentionally declare non-allocable //global variable to custmized usage. //ASSERT0(VAR_allocable(v)); if (v->is_string() && genDedicateStrMD() != NULL) { continue; } //We allocate MDTab for VAR which is func-decl or fake as well. //Since some Passes such as AA may need fake VAR to do analysis. MD md; MD_base(&md) = v; MD_ofst(&md) = 0; MD_size(&md) = v->getByteSize(get_type_mgr()); if (VAR_is_fake(v) || VAR_is_func_decl(v)) { MD_ty(&md) = MD_UNBOUND; } else { MD_ty(&md) = MD_EXACT; } m_md_sys->registerMD(md); } }
//Try to generate a MD to represent dedicated string md. //In case, e.g: android/external/tagsoup/src/org/ccil/cowan/tagsoup/HTMLSchema.java //There is a function allocates 3000+ string variable. //Each string has been taken address. //That will inflate may_point_to_set too much. //In this situation, AA can be conservatively regard all string variables //as same unbounded MD. MD const* RegionMgr::genDedicateStrMD() { if (!m_is_regard_str_as_same_md) { return NULL; } //Regard all string variables as same unbound MD. if (m_str_md == NULL) { SYM * s = addToSymbolTab("DedicatedVarBeRegardedAsString"); VAR * sv = get_var_mgr()->registerStringVar("DedicatedStringVar", s, 1); VAR_allocable(sv) = false; VAR_is_addr_taken(sv) = true; MD md; MD_base(&md) = sv; MD_ty(&md) = MD_UNBOUND; ASSERT0(MD_base(&md)->is_string()); MD const* e = m_md_sys->registerMD(md); ASSERT0(MD_id(e) > 0); m_str_md = e; } return m_str_md; }
void PRDF::processMay( IR const* pr, DefSBitSetCore * gen, DefSBitSetCore * use, bool is_lhs) { if (!m_handle_may) { return; } MDSet const* mds = pr->get_ref_mds(); if (mds != NULL) { MD const* prmd = pr->get_exact_ref(); ASSERT0(prmd); SEGIter * iter; for (INT i = mds->get_first(&iter); i >= 0; i = mds->get_next(i, &iter)) { MD const* md = m_md_sys->get_md(i); ASSERT0(md); if (MD_base(md) != MD_base(prmd)) { bool find; ASSERT0(m_var2pr); //One should initialize m_var2pr. UINT prno = m_var2pr->get(MD_base(md), &find); ASSERT0(find); if (is_lhs) { ASSERT0(gen && use); gen->bunion(prno, m_sbs_mgr); use->diff(prno, m_sbs_mgr); } else { ASSERT0(use); use->bunion(prno, m_sbs_mgr); } } } } }
void handle_ld(IR * ld, MD2MDS * mx) { IS_TRUE0(IR_type(ld) == IR_LD && mx); IR_AI * ai = IR_ai(ld); if (ai == NULL) { return; } TBAA_AI * ty = (TBAA_AI*)ai->get(IRAI_TBAA); if (ty == NULL) { return; } MD * md = m_tyid2md.get(ty->tyid); if (md != NULL) { MD const* t = alloc_ld_md(ld); set_point_to_set_add_md(t, *mx, md); return; } 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); MD const* t = alloc_ld_md(ld); set_point_to_set_add_md(t, *mx, entry); }