From 3c58fd7d832ce71579b3cb7cb4765d37d70102e2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Sat, 1 Jun 2013 15:07:23 -0700 Subject: improve RemoveUnneededFlows to handle flows into loops with a single entry --- src/relooper/Relooper.cpp | 31 +++++++++++++++++++++++++++++-- src/relooper/Relooper.h | 1 + src/relooper/test.txt | 9 +++------ tools/shared.py | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index cb989e20..e91c6e74 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -893,10 +893,22 @@ void Relooper::Calculate(Block *Entry) { func(Loop->Next); \ } + // Find the single block that must be hit in a shape, or NULL if there is more than one + Block *FollowNaturalFlow(Shape *S) { + SHAPE_SWITCH(S, { + return Simple->Inner; + }, { + return NULL; + }, { + return FollowNaturalFlow(Loop->Inner); + }); + } + // Remove unneeded breaks and continues. // A flow operation is trivially unneeded if the shape we naturally get to by normal code // execution is the same as the flow forces us to. void RemoveUnneededFlows(Shape *Root, Shape *Natural=NULL) { + Block *NaturalBlock = FollowNaturalFlow(Natural); Shape *Next = Root; while (Next) { Root = Next; @@ -911,7 +923,7 @@ void Relooper::Calculate(Block *Entry) { for (BlockBranchMap::iterator iter = Simple->Inner->ProcessedBranchesOut.begin(); iter != Simple->Inner->ProcessedBranchesOut.end(); iter++) { Block *Target = iter->first; Branch *Details = iter->second; - if (Details->Type != Branch::Direct && Target->Parent == Natural) { + if (Details->Type != Branch::Direct && Target == NaturalBlock) { // note: cannot handle split blocks Details->Type = Branch::Direct; if (MultipleShape *Multiple = Shape::IsMultiple(Details->Ancestor)) { Multiple->NeedLoop--; @@ -1026,7 +1038,7 @@ void Relooper::SetAsmJSMode(int On) { #if DEBUG // Debugging -void DebugDump(BlockSet &Blocks, const char *prefix) { +void Debugging::Dump(BlockSet &Blocks, const char *prefix) { if (prefix) printf("%s ", prefix); for (BlockSet::iterator iter = Blocks.begin(); iter != Blocks.end(); iter++) { Block *Curr = *iter; @@ -1039,6 +1051,21 @@ void DebugDump(BlockSet &Blocks, const char *prefix) { } } +void Debugging::Dump(Shape *S, const char *prefix) { + if (prefix) printf("%s ", prefix); + printf(" %d ", S->Id); + SHAPE_SWITCH(S, { + printf("<< Simple with block %d\n", Simple->Inner->Id); + }, { + printf("<< Multiple\n"); + for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + printf(" with entry %d\n", iter->first->Id); + } + }, { + printf("<< Loop\n"); + }); +} + static void PrintDebug(const char *Format, ...) { printf("// "); va_list Args; diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h index 5eabe827..34b6db08 100644 --- a/src/relooper/Relooper.h +++ b/src/relooper/Relooper.h @@ -211,6 +211,7 @@ typedef std::map BlockBlockSetMap; #if DEBUG struct Debugging { static void Dump(BlockSet &Blocks, const char *prefix=NULL); + static void Dump(Shape *S, const char *prefix=NULL); }; #endif diff --git a/src/relooper/test.txt b/src/relooper/test.txt index 2ff70e66..84a8c905 100644 --- a/src/relooper/test.txt +++ b/src/relooper/test.txt @@ -129,12 +129,9 @@ do { break; } } while(0); -do { - if (label == 33) { - // block C; - break; - } -} while(0); +if (label == 33) { + // block C; +} while(1) { // block E // block F diff --git a/tools/shared.py b/tools/shared.py index f9d93289..645dfbe9 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -295,7 +295,7 @@ def check_node_version(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.4.5' +EMSCRIPTEN_VERSION = '1.4.6' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() -- cgit v1.2.3-18-g5258