Centralize the logic to permanently unify two instructions and make sure

it establishes a context and does a complaining diff.  Also make sure we
unify the prelude and postlude of a diff after a block-diff call.

llvm-svn: 109744
This commit is contained in:
John McCall 2010-07-29 09:20:34 +00:00
parent 8489de298e
commit eaeede9a06
1 changed files with 30 additions and 20 deletions

View File

@ -172,6 +172,18 @@ class FunctionDifferenceEngine {
Queue.insert(BlockPair(L, R));
return false;
}
/// Unifies two instructions, given that they're known not to have
/// structural differences.
void unify(Instruction *L, Instruction *R) {
DifferenceEngine::Context C(Engine, L, R);
bool Result = diff(L, R, true, true);
assert(!Result && "structural differences second time around?");
(void) Result;
if (!L->use_empty())
Values[L] = R;
}
void processQueue() {
while (!Queue.empty()) {
@ -207,22 +219,10 @@ class FunctionDifferenceEngine {
} while (LI != LE); // This is sufficient: we can't get equality of
// terminators if there are residual instructions.
// Unify everything in the block, non-tentatively this time.
TentativeValues.clear();
// Do another pass over the block, this time in complaints mode.
LI = L->begin(); RI = R->begin();
do {
assert(LI != LE && RI != RE);
bool Result = diff(&*LI, &*RI, true, true);
assert(!Result && "structural differences second time around?");
(void) Result;
// Make the mapping non-tentative this time.
if (!LI->use_empty())
Values[&*LI] = &*RI;
++LI, ++RI;
} while (LI != LE);
for (LI = L->begin(), RI = R->begin(); LI != LE; ++LI, ++RI)
unify(&*LI, &*RI);
}
bool matchForBlockDiff(Instruction *L, Instruction *R);
@ -538,6 +538,10 @@ void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart,
std::swap(Cur, Next);
}
// We don't need the tentative values anymore; everything from here
// on out should be non-tentative.
TentativeValues.clear();
SmallVectorImpl<char> &Path = Cur[NL].Path;
BasicBlock::iterator LI = LStart, RI = RStart;
@ -550,8 +554,10 @@ void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart,
// Skip leading matches.
SmallVectorImpl<char>::iterator
PI = Path.begin(), PE = Path.end();
while (PI != PE && *PI == DifferenceEngine::DC_match)
while (PI != PE && *PI == DifferenceEngine::DC_match) {
unify(&*LI, &*RI);
++PI, ++LI, ++RI;
}
for (; PI != PE; ++PI) {
switch (static_cast<DifferenceEngine::DiffChange>(*PI)) {
@ -559,9 +565,7 @@ void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart,
assert(LI != LE && RI != RE);
{
Instruction *L = &*LI, *R = &*RI;
DifferenceEngine::Context C(Engine, L, R);
diff(L, R, true, true); // complain and unify successors
Values[L] = R; // make non-tentative
unify(L, R);
Diff.addMatch(L, R);
}
++LI; ++RI;
@ -581,7 +585,13 @@ void FunctionDifferenceEngine::runBlockDiff(BasicBlock::iterator LStart,
}
}
TentativeValues.clear();
// Finishing unifying and complaining about the tails of the block,
// which should be matches all the way through.
while (LI != LE) {
assert(RI != RE);
unify(&*LI, &*RI);
++LI, ++RI;
}
}
}