diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-04-16 14:12:00 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-04-16 14:12:00 -0700 |
commit | 0f8f1e94e02ead602699c816794d238e642ec1ca (patch) | |
tree | 5bace2a20c84013ab1aba7533511bb6ac993a294 /src | |
parent | 11dfeed10d0fe74d9c47fd0396b87b99f7dde0dc (diff) |
optimize multiple shape to contain a map based on ids, not blocks, so we re-merge split nodes early
Diffstat (limited to 'src')
-rw-r--r-- | src/relooper/Relooper.cpp | 24 | ||||
-rw-r--r-- | src/relooper/Relooper.h | 7 |
2 files changed, 16 insertions, 15 deletions
diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index 780a6d59..c396e990 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -243,7 +243,7 @@ void Block::Render(bool InLoop) { Details = ProcessedBranchesOut[DefaultTarget]; } bool SetCurrLabel = (SetLabel && Target->IsCheckedMultipleEntry) || ForceSetLabel; - bool HasFusedContent = Fused && contains(Fused->InnerMap, Target); + bool HasFusedContent = Fused && contains(Fused->InnerMap, Target->Id); bool HasContent = SetCurrLabel || Details->Type != Branch::Direct || HasFusedContent || Details->Code; if (iter != ProcessedBranchesOut.end()) { // If there is nothing to show in this branch, omit the condition @@ -286,7 +286,7 @@ void Block::Render(bool InLoop) { if (!First) Indenter::Indent(); Details->Render(Target, SetCurrLabel); if (HasFusedContent) { - Fused->InnerMap.find(Target)->second->Render(InLoop); + Fused->InnerMap.find(Target->Id)->second->Render(InLoop); } else if (Details->Type == Branch::Nested) { // Nest the parent content here, and remove it from showing up afterwards as Next assert(Parent->Next); @@ -335,14 +335,14 @@ void MultipleShape::Render(bool InLoop) { // We know that blocks with the same Id were split from the same source, so their contents are identical and they are logically the same, so re-merge them here typedef std::map<int, Shape*> IdShapeMap; IdShapeMap IdMap; - for (BlockShapeMap::iterator iter = InnerMap.begin(); iter != InnerMap.end(); iter++) { - int Id = iter->first->Id; + for (IdShapeMap::iterator iter = InnerMap.begin(); iter != InnerMap.end(); iter++) { + int Id = iter->first; IdShapeMap::iterator Test = IdMap.find(Id); if (Test != IdMap.end()) { assert(Shape::IsSimple(iter->second) && Shape::IsSimple(Test->second)); // we can only merge simple blocks, something horrible has gone wrong if we see anything else continue; } - IdMap[iter->first->Id] = iter->second; + IdMap[iter->first] = iter->second; } bool First = true; @@ -853,7 +853,7 @@ void Relooper::Calculate(Block *Entry) { iter = Next; // increment carefully because Solipsize can remove us } } - Multiple->InnerMap[CurrEntry] = Process(CurrBlocks, CurrEntries, NULL); + Multiple->InnerMap[CurrEntry->Id] = Process(CurrBlocks, CurrEntries, NULL); // If we are not fused, then our entries will actually be checked if (!Fused) { CurrEntry->IsCheckedMultipleEntry = true; @@ -1021,7 +1021,7 @@ void Relooper::Calculate(Block *Entry) { PostOptimizer(Relooper *ParentInit) : Parent(ParentInit), Closure(NULL) {} #define RECURSE_Multiple(shape, func) \ - for (BlockShapeMap::iterator iter = shape->InnerMap.begin(); iter != shape->InnerMap.end(); iter++) { \ + for (IdShapeMap::iterator iter = shape->InnerMap.begin(); iter != shape->InnerMap.end(); iter++) { \ func(iter->second); \ } #define RECURSE_Loop(shape, func) \ @@ -1042,7 +1042,7 @@ void Relooper::Calculate(Block *Entry) { SHAPE_SWITCH(S, { Out.insert(Simple->Inner); }, { - for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { FollowNaturalFlow(iter->second, Out); } FollowNaturalFlow(Multiple->Next, Out); @@ -1061,7 +1061,7 @@ void Relooper::Calculate(Block *Entry) { SHAPE_SWITCH(Root, { }, { - for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { FindNaturals(iter->second, Root->Natural); } }, { @@ -1142,7 +1142,7 @@ void Relooper::Calculate(Block *Entry) { } } }, { - for (BlockShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { RemoveUnneededFlows(iter->second, Multiple->Next, Multiple->NeedLoop ? NULL : LastLoop); } Next = Multiple->Next; @@ -1290,8 +1290,8 @@ void Debugging::Dump(Shape *S, const char *prefix) { 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); + for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) { + printf(" with entry %d\n", iter->first); } }, { printf("<< Loop\n"); diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h index 152bae0e..7d80e162 100644 --- a/src/relooper/Relooper.h +++ b/src/relooper/Relooper.h @@ -132,8 +132,6 @@ struct SimpleShape : public Shape { } }; -typedef std::map<Block*, Shape*> BlockShapeMap; - // A shape that may be implemented with a labeled loop. struct LabeledShape : public Shape { bool Labeled; // If we have a loop, whether it needs to be labeled @@ -141,8 +139,11 @@ struct LabeledShape : public Shape { LabeledShape(ShapeType TypeInit) : Shape(TypeInit), Labeled(false) {} }; +// Blocks with the same id were split and are identical, so we just care about ids in Multiple entries +typedef std::map<int, Shape*> IdShapeMap; + struct MultipleShape : public LabeledShape { - BlockShapeMap InnerMap; // entry block -> shape + IdShapeMap InnerMap; // entry block ID -> shape int NeedLoop; // If we have branches, we need a loop. This is a counter of loop requirements, // if we optimize it to 0, the loop is unneeded |