Exemple #1
0
// Substitute s into all members of the set
void LocationSet::substitute(Assign& a)
{
    Exp* lhs = a.getLeft();
    if (lhs == NULL) return;
    Exp* rhs = a.getRight();
    if (rhs == NULL) return;		// ? Will this ever happen?
    std::set<Exp*, lessExpStar>::iterator it;
    // Note: it's important not to change the pointer in the set of pointers to expressions, without removing and
    // inserting again. Otherwise, the set becomes out of order, and operations such as set comparison fail!
    // To avoid any funny behaviour when iterating the loop, we use the following two sets
    LocationSet removeSet;			// These will be removed after the loop
    LocationSet removeAndDelete;	// These will be removed then deleted
    LocationSet insertSet;			// These will be inserted after the loop
    bool change;
    for (it = lset.begin(); it != lset.end(); it++)
        {
            Exp* loc = *it;
            Exp* replace;
            if (loc->search(lhs, replace))
                {
                    if (rhs->isTerminal())
                        {
                            // This is no longer a location of interest (e.g. %pc)
                            removeSet.insert(loc);
                            continue;
                        }
                    loc = loc->clone()->searchReplaceAll(lhs, rhs, change);
                    if (change)
                        {
                            loc = loc->simplifyArith();
                            loc = loc->simplify();
                            // If the result is no longer a register or memory (e.g.
                            // r[28]-4), then delete this expression and insert any
                            // components it uses (in the example, just r[28])
                            if (!loc->isRegOf() && !loc->isMemOf())
                                {
                                    // Note: can't delete the expression yet, because the
                                    // act of insertion into the remove set requires silent
                                    // calls to the compare function
                                    removeAndDelete.insert(*it);
                                    loc->addUsedLocs(insertSet);
                                    continue;
                                }
                            // Else we just want to replace it
                            // Regardless of whether the top level expression pointer has
                            // changed, remove and insert it from the set of pointers
                            removeSet.insert(*it);		// Note: remove the unmodified ptr
                            insertSet.insert(loc);
                        }
                }
        }
    makeDiff(removeSet);	   // Remove the items to be removed
    makeDiff(removeAndDelete); // These are to be removed as well
    makeUnion(insertSet);	   // Insert the items to be added
    // Now delete the expressions that are no longer needed
    std::set<Exp*, lessExpStar>::iterator dd;
    for (dd = removeAndDelete.lset.begin(); dd != removeAndDelete.lset.end();
            dd++)
        delete *dd;				// Plug that memory leak
}
void LocationSetTest::testFindDifferentRef()
{
    LocationSet set;

    SharedExp result;
    QVERIFY(!set.findDifferentRef(nullptr, result));

    set.insert(Location::regOf(REG_PENT_EAX));
    QVERIFY(!set.findDifferentRef(RefExp::get(Location::regOf(REG_PENT_EAX), nullptr), result));

    set.insert(RefExp::get(Location::regOf(REG_PENT_EAX), nullptr));
    QVERIFY(!set.findDifferentRef(RefExp::get(Location::regOf(REG_PENT_EAX), nullptr), result));

    Assign as1(Location::regOf(REG_PENT_ECX), Location::regOf(REG_PENT_EDX));
    Assign as2(Location::regOf(REG_PENT_ECX), Location::regOf(REG_PENT_EDX));

    as1.setNumber(10);
    as2.setNumber(20);

    set.insert(RefExp::get(Location::regOf(REG_PENT_ECX), &as1));
    // no other ref
    QVERIFY(!set.findDifferentRef(RefExp::get(Location::regOf(REG_PENT_ECX), &as1), result));

    set.insert(RefExp::get(Location::regOf(REG_PENT_ECX), &as2));
    // return a different ref
    QVERIFY(set.findDifferentRef(RefExp::get(Location::regOf(REG_PENT_ECX), &as1), result));
    QCOMPARE(result->toString(), QString("r25{20}"));

    // should work even when the ref is not in the set
    set.remove(RefExp::get(Location::regOf(REG_PENT_ECX), &as1));
    QVERIFY(set.findDifferentRef(RefExp::get(Location::regOf(REG_PENT_ECX), &as1), result));
    QCOMPARE(result->toString(), QString("r25{20}"));
}
Exemple #3
0
// Helper function for UserProc::propagateStatements()
// Works on basic block n; call from UserProc with n=0 (entry BB)
// If an SSA location is in usedByDomPhi it means it is used in a phi that dominates its assignment
// However, it could turn out that the phi is dead, in which case we don't want to keep the associated entries in
// usedByDomPhi. So we maintain the map defdByPhi which maps locations defined at a phi to the phi statements. Every
// time we see a use of a location in defdByPhi, we remove that map entry. At the end of the procedure we therefore have
// only dead phi statements in the map, so we can delete the associated entries in defdByPhi and also remove the dead
// phi statements.
// We add to the set usedByDomPhi0 whenever we see a location referenced by a phi parameter. When we see a definition
// for such a location, we remove it from the usedByDomPhi0 set (to save memory) and add it to the usedByDomPhi set.
// For locations defined before they are used in a phi parameter, there will be no entry in usedByDomPhi, so we ignore
// it. Remember that each location is defined only once, so that's the time to decide if it is dominated by a phi use or
// not.
void DataFlow::findLiveAtDomPhi(int n, LocationSet& usedByDomPhi, LocationSet& usedByDomPhi0,
			std::map<Exp*, PhiAssign*, lessExpStar>& defdByPhi) {
	// For each statement this BB
	BasicBlock::rtlit rit; StatementList::iterator sit;
	PBB bb = BBs[n];
	Statement* S;
	for (S = bb->getFirstStmt(rit, sit); S; S = bb->getNextStmt(rit, sit)) {
		if (S->isPhi()) {
			// For each phi parameter, insert an entry into usedByDomPhi0
			PhiAssign* pa = (PhiAssign*)S;
			PhiAssign::iterator it;
			for (it = pa->begin(); it != pa->end(); ++it) {
				if (it->e) {
					RefExp* re = new RefExp(it->e, it->def);
					usedByDomPhi0.insert(re);
				}
			}
			// Insert an entry into the defdByPhi map
			RefExp* wrappedLhs = new RefExp(pa->getLeft(), pa);
			defdByPhi[wrappedLhs] = pa;
			// Fall through to the below, because phi uses are also legitimate uses
		}
		LocationSet ls;
		S->addUsedLocs(ls);
		// Consider uses of this statement
		LocationSet::iterator it;
		for (it = ls.begin(); it != ls.end(); ++it) {
			// Remove this entry from the map, since it is not unused
			defdByPhi.erase(*it);
		}
		// Now process any definitions
		ls.clear();
		S->getDefinitions(ls);
		for (it = ls.begin(); it != ls.end(); ++it) {
			RefExp* wrappedDef = new RefExp(*it, S);
			// If this definition is in the usedByDomPhi0 set, then it is in fact dominated by a phi use, so move it to
			// the final usedByDomPhi set
			if (usedByDomPhi0.find(wrappedDef) != usedByDomPhi0.end()) {
				usedByDomPhi0.remove(wrappedDef);
				usedByDomPhi.insert(wrappedDef);
			}
		}
	}

	// Visit each child in the dominator graph
	// Note: this is a linear search!
	// Note also that usedByDomPhi0 may have some irrelevant entries, but this will do no harm, and attempting to erase
	// the irrelevant ones would probably cost more than leaving them alone
	int sz = idom.size();
	for (int c = 0; c < sz; ++c) {
		if (idom[c] != n) continue;
		// Recurse to the child
		findLiveAtDomPhi(c, usedByDomPhi, usedByDomPhi0, defdByPhi);
	}
}
void LocationSetTest::testSize()
{
    LocationSet set;
    QVERIFY(set.size() == 0);

    set.insert(Location::regOf(REG_PENT_ESI));
    QVERIFY(set.size() == 1);

    set.insert(Location::regOf(REG_PENT_EDI));
    QVERIFY(set.size() == 2);
}
void LocationSetTest::testInsert()
{
    LocationSet set;

    set.insert(Location::regOf(REG_PENT_ESI));
    QCOMPARE(set, LocationSet({ Location::regOf(REG_PENT_ESI) }));

    set.insert(Location::regOf(REG_PENT_ESI));
    QCOMPARE(set, LocationSet({ Location::regOf(REG_PENT_ESI) }));

    set.insert(Location::regOf(REG_PENT_EDI));
    QCOMPARE(set, LocationSet({ Location::regOf(REG_PENT_ESI), Location::regOf(REG_PENT_EDI) }));
}
void LocationSetTest::testContainsImplicit()
{
    LocationSet set;
    QVERIFY(!set.containsImplicit(nullptr));

    set.insert(Location::regOf(REG_PENT_ESI));
    QVERIFY(!set.containsImplicit(Location::regOf(REG_PENT_ESI)));
    QVERIFY(!set.containsImplicit(Location::regOf(REG_PENT_EDI)));

    set.insert(RefExp::get(Location::regOf(REG_PENT_EDI), nullptr));
    QVERIFY(set.containsImplicit(Location::regOf(REG_PENT_EDI)));
    QVERIFY(!set.containsImplicit(Location::regOf(REG_PENT_ESI)));
}
void LocationSetTest::testFindNS()
{
    LocationSet set;
    QVERIFY(set.findNS(nullptr) == nullptr);

    set.insert(Location::regOf(REG_PENT_ESI));
    SharedExp e = set.findNS(Location::regOf(REG_PENT_ESI));
    QVERIFY(e == nullptr);

    set.insert(RefExp::get(Location::regOf(REG_PENT_EDI), nullptr));
    e = set.findNS(Location::regOf(REG_PENT_EDI));
    QVERIFY(e != nullptr);

    QCOMPARE(e->toString(), QString("r31{-}"));
}
void LocationSetTest::testEmpty()
{
    LocationSet set;
    QVERIFY(set.empty());

    set.insert(Location::regOf(REG_PENT_EDI));
    QVERIFY(!set.empty());
}
void LocationSetTest::testAddSubscript()
{
    LocationSet set;
    set.addSubscript(nullptr);
    QCOMPARE(set, LocationSet());

    set.insert(Location::regOf(REG_PENT_ECX));
    set.addSubscript(nullptr);
    QCOMPARE(set, LocationSet({ RefExp::get(Location::regOf(REG_PENT_ECX), nullptr) }));

    set.insert(Location::regOf(REG_PENT_ECX));
    Assign as(Location::regOf(REG_PENT_ECX), Location::regOf(REG_PENT_EDX));
    as.setNumber(42);
    set.addSubscript(&as);
    QCOMPARE(set, LocationSet({
        RefExp::get(Location::regOf(REG_PENT_ECX), nullptr),
        RefExp::get(Location::regOf(REG_PENT_ECX), &as) }));
}
Exemple #10
0
void LocationSetTest::testContains()
{
    LocationSet set;

    QVERIFY(!set.contains(nullptr));

    set.insert(Location::regOf(REG_PENT_ESI));
    QVERIFY(set.contains(Location::regOf(REG_PENT_ESI)));
    QVERIFY(!set.contains(Location::regOf(REG_PENT_EDI)));
}
Exemple #11
0
void LocationSetTest::testRemove()
{
    LocationSet set;
    set.remove(nullptr);
    QVERIFY(set.empty());

    set.insert(Location::regOf(REG_PENT_ESI));
    set.remove(Location::regOf(REG_PENT_ESI));
    QVERIFY(set.empty());

    set.insert(Location::regOf(REG_PENT_ESI));
    set.insert(Location::regOf(REG_PENT_EDI));
    set.remove(Location::regOf(REG_PENT_EDI));
    QCOMPARE(set, LocationSet({ Location::regOf(REG_PENT_ESI) }));

    // removing element that does not exist
    set.remove(Location::regOf(REG_PENT_EDI));
    QCOMPARE(set, LocationSet({ Location::regOf(REG_PENT_ESI) }));
}
Exemple #12
0
void LocationSetTest::testClear()
{
    LocationSet set;

    set.clear();
    QVERIFY(set.empty());

    set.insert(Location::regOf(REG_PENT_ESI));
    set.clear();
    QVERIFY(set.empty());
}
Exemple #13
0
void BoolAssign::getDefinitions(LocationSet &defs, bool) const
{
    defs.insert(getLeft());
}