don't create a simple if it would have a multiple that causes label variable usage
diff --git a/lib/Target/JSBackend/Relooper.cpp b/lib/Target/JSBackend/Relooper.cpp index c74a634..baa2447 100644 --- a/lib/Target/JSBackend/Relooper.cpp +++ b/lib/Target/JSBackend/Relooper.cpp
@@ -859,7 +859,7 @@ #endif } - void CalculateNextEntriesForMultiple(BlockSet &Blocks, BlockSet& Entries, BlockBlockSetMap& IndependentGroups, Shape *Prev, BlockSet &NextEntries) { + void CalculateNextEntriesForMultiple(BlockSet& Entries, BlockBlockSetMap& IndependentGroups, BlockSet &NextEntries) { // Any entry that is not an independent group is a next entry for (auto Entry : Entries) { if (!contains(IndependentGroups, Entry)) { @@ -1005,7 +1005,29 @@ Make(MakeEmulated(Blocks, Curr, *NextEntries)); } if (Curr->BranchesIn.size() == 0) { - // One entry, no looping ==> Simple + // One entry, no looping ==> Simple. Unless we might cause + // multiple next entries, which can happen if the next block is + // going to be a Multiple. If we need a one-time loop for the + // Multiple, we should do it now, to not break fusing. + if (Curr->BranchesOut.size() > 1) { + // Look for a block we can put at the very end, reachable via a break in a one-time loop. + // If there is one, then we can check if it would be dangerous to make a Multiple after this Simple. + Block *Last = FindLastBlock(Blocks); + if (Last) { + // Check what would happen if we made a Multiple after us + BlockSet TempEntries; + for (auto iter : Curr->BranchesOut) { + TempEntries.insert(iter.first); + } + BlockBlockSetMap IndependentGroups; + FindIndependentGroups(TempEntries, IndependentGroups); + BlockSet PossibleNextEntries; + CalculateNextEntriesForMultiple(TempEntries, IndependentGroups, PossibleNextEntries); + if (PossibleNextEntries.size() > 1) { + Make(MakeOneTimeLoop(Blocks, *Entries, Last, *NextEntries)); + } + } + } Make(MakeSimple(Blocks, Curr, *NextEntries)); } // One entry, looping ==> Loop @@ -1087,7 +1109,7 @@ // Some groups removable, probably we should do a Multiple. But, if it // would cause multiple next entries, then we should try to avoid that BlockSet PossibleNextEntries; - CalculateNextEntriesForMultiple(Blocks, *Entries, IndependentGroups, Prev, PossibleNextEntries); + CalculateNextEntriesForMultiple(*Entries, IndependentGroups, PossibleNextEntries); if (PossibleNextEntries.size() > 1) { // Look for a block we can put at the very end, reachable via a break in a one-time loop Block *Last = FindLastBlock(Blocks);