ExpressionPtr Expression::unneededHelper() { ExpressionListPtr elist = ExpressionListPtr (new ExpressionList(getScope(), getRange(), ExpressionList::ListKindWrapped)); bool change = false; for (int i=0, n = getKidCount(); i < n; i++) { ExpressionPtr kid = getNthExpr(i); if (kid && kid->getContainedEffects()) { ExpressionPtr rep = kid->unneeded(); if (rep != kid) change = true; if (rep->is(Expression::KindOfExpressionList)) { for (int j=0, m = rep->getKidCount(); j < m; j++) { elist->addElement(rep->getNthExpr(j)); } } else { elist->addElement(rep); } } } if (change) { getScope()->addUpdates(BlockScope::UseKindCaller); } int n = elist->getCount(); assert(n); if (n == 1) { return elist->getNthExpr(0); } else { return elist; } }
void ExprDict::updateAccess(ExpressionPtr e) { int cls = e->getExprClass(); int eid = e->getCanonID(); e->clearAnticipated(); e->clearAvailable(); // bail on non-canonical expressions if (!isCanonicalStructure(eid)) { // but record we saw a type assertion belonging to this block m_avlTypeAsserts.push_back(eid); return; } if (m_anticipated && (cls & Expression::Update ? !BitOps::get_bit(eid, m_altered) : !e->getLocalEffects())) { /* Anticipated can be computed bottom up as we go. But note that we only know altered for Load/Store expressions. */ int i = e->getKidCount(); while (true) { if (!i--) { e->setAnticipated(); if (!e->hasContext(Expression::AssignmentLHS)) { setStructureOps(eid, m_anticipated, true); } break; } if (ExpressionPtr k = e->getNthExpr(i)) { if (!isCanonicalStructure(k->getCanonID())) continue; if (!k->isAnticipated()) { break; } } } } if (m_available) { /* Available has to be computed optimistically, because we dont yet know what is going to be altered between here and the end of the block So keep a list of the potentially-available accesses (avlAccess), and for each id, the last potentially-available expression (avlExpr). For each modifying expression that we process, we remove expressions from avlAccess, and at the end, we build up the available expressions bottom up. */ if ((cls & (Expression::Store|Expression::Call)) || (cls & Expression::Load && e->getContext() & (Expression::LValue| Expression::RefValue| Expression::UnsetContext| Expression::DeepReference))) { bool isLoad; int depth = 0, effects = 0; for (int i = 0, n = m_avlAccess.size(); i < n; ) { ExpressionRawPtr a = m_avlAccess[i]; if (m_am.checkAnyInterf(e, a, isLoad, depth, effects) != AliasManager::DisjointAccess) { int aid = a->getCanonID(); assert(isCanonicalStructure(aid)); if (eid != aid || cls == Expression::Load) { BitOps::set_bit(aid, m_altered, true); } if (!(cls & Expression::Store) || a != e->getStoreVariable()) { a->clearAvailable(); m_avlAccess[i] = m_avlAccess[--n]; m_avlAccess.resize(n); continue; } } i++; } } if (cls & Expression::Update || !e->getContainedEffects()) { int i = e->getKidCount(); while (true) { if (!i--) { e->setAvailable(); if (cls & Expression::Update) { m_avlAccess.push_back(e); } m_avlExpr[eid] = e; break; } if (ExpressionPtr k = e->getNthExpr(i)) { if (!isCanonicalStructure(k->getCanonID())) continue; if (!k->isAvailable()) { break; } } } } } if ((cls & (Expression::Store|Expression::Call)) || (cls & Expression::Load && e->getContext() & (Expression::LValue| Expression::RefValue| Expression::UnsetContext| Expression::DeepReference))) { ExpressionPtr cur = m_active, prev; bool isLoad; int depth = 0, effects = 0; while (cur) { ExpressionPtr next = cur->getCanonLVal(); int cid = cur->getCanonID(); assert(isCanonicalStructure(cid)); if ((cid != eid || cls == Expression::Load) && (BitOps::get_bit(cid, m_altered) || m_am.checkAnyInterf(e, cur, isLoad, depth, effects) != AliasManager::DisjointAccess)) { BitOps::set_bit(cid, m_altered, true); if (!prev) { m_active = next; } else { prev->setCanonPtr(next); } } else { prev = cur; } cur = next; } } }