summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-11-13 16:36:50 -0800
committerGitHub <noreply@github.com>2018-11-13 16:36:50 -0800
commit37d82ba9574d440a89b1d7f91af89cd30b35b158 (patch)
treedee891b1c91fd9511948b3f9aee0b9ed578ea71e /src
parentb67917ee7392c4d49402cb5e7320e663208390ef (diff)
downloadbinaryen-37d82ba9574d440a89b1d7f91af89cd30b35b158.tar.gz
binaryen-37d82ba9574d440a89b1d7f91af89cd30b35b158.tar.bz2
binaryen-37d82ba9574d440a89b1d7f91af89cd30b35b158.zip
Modernize relooper code (#1738)
Use c++11 auto, iterators, etc.
Diffstat (limited to 'src')
-rw-r--r--src/cfg/Relooper.cpp319
-rw-r--r--src/cfg/Relooper.h34
2 files changed, 176 insertions, 177 deletions
diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp
index 22b455aaf..2387922a8 100644
--- a/src/cfg/Relooper.cpp
+++ b/src/cfg/Relooper.cpp
@@ -107,7 +107,7 @@ Branch::Branch(std::vector<wasm::Index>&& ValuesInit, wasm::Expression* CodeInit
// otherwise, it is the default
}
-wasm::Expression* Branch::Render(RelooperBuilder& Builder, Block *Target, bool SetLabel) {
+wasm::Expression* Branch::Render(RelooperBuilder& Builder, Block* Target, bool SetLabel) {
auto* Ret = Builder.makeBlock();
if (Code) Ret->list.push_back(Code);
if (SetLabel) Ret->list.push_back(Builder.makeSetLabel(Target->Id));
@@ -126,20 +126,20 @@ wasm::Expression* Branch::Render(RelooperBuilder& Builder, Block *Target, bool S
Block::Block(wasm::Expression* CodeInit, wasm::Expression* SwitchConditionInit) : Parent(nullptr), Id(-1), Code(CodeInit), SwitchCondition(SwitchConditionInit), IsCheckedMultipleEntry(false) {}
Block::~Block() {
- for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
- delete iter->second;
+ for (auto& iter : ProcessedBranchesOut) {
+ delete iter.second;
}
- for (BlockBranchMap::iterator iter = BranchesOut.begin(); iter != BranchesOut.end(); iter++) {
- delete iter->second;
+ for (auto& iter : BranchesOut) {
+ delete iter.second;
}
}
-void Block::AddBranchTo(Block *Target, wasm::Expression* Condition, wasm::Expression* Code) {
+void Block::AddBranchTo(Block* Target, wasm::Expression* Condition, wasm::Expression* Code) {
assert(!contains(BranchesOut, Target)); // cannot add more than one branch to the same target
BranchesOut[Target] = new Branch(Condition, Code);
}
-void Block::AddSwitchBranchTo(Block *Target, std::vector<wasm::Index>&& Values, wasm::Expression* Code) {
+void Block::AddSwitchBranchTo(Block* Target, std::vector<wasm::Index>&& Values, wasm::Expression* Code) {
assert(!contains(BranchesOut, Target)); // cannot add more than one branch to the same target
BranchesOut[Target] = new Branch(std::move(Values), Code);
}
@@ -181,7 +181,7 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
// *must* appear in the Simple (the Simple is the only one reaching the
// Multiple), so we can remove the Multiple and add its independent groups
// into the Simple's branches.
- MultipleShape *Fused = Shape::IsMultiple(Parent->Next);
+ MultipleShape* Fused = Shape::IsMultiple(Parent->Next);
if (Fused) {
PrintDebug("Fusing Multiple to Simple\n", 0);
Parent->Next = Parent->Next->Next;
@@ -194,16 +194,16 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
}
}
- Block *DefaultTarget = nullptr; // The block we branch to without checking the condition, if none of the other conditions held.
+ Block* DefaultTarget = nullptr; // The block we branch to without checking the condition, if none of the other conditions held.
// Find the default target, the one without a condition
- for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin(); iter != ProcessedBranchesOut.end(); iter++) {
- if ((!SwitchCondition && !iter->second->Condition) || (SwitchCondition && !iter->second->SwitchValues)) {
+ for (auto& iter : ProcessedBranchesOut) {
+ if ((!SwitchCondition && !iter.second->Condition) || (SwitchCondition && !iter.second->SwitchValues)) {
assert(!DefaultTarget && "block has branches without a default (nullptr for the condition)"); // Must be exactly one default // nullptr
- DefaultTarget = iter->first;
+ DefaultTarget = iter.first;
}
}
- assert(DefaultTarget); // Since each block *must* branch somewhere, this must be set
+ assert(DefaultTarget); // Since each Block* must* branch somewhere, this must be set
wasm::Expression* Root = nullptr; // root of the main part, that we are about to emit
@@ -217,9 +217,9 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
wasm::Expression* RemainingConditions = nullptr;
- for (BlockBranchMap::iterator iter = ProcessedBranchesOut.begin();; iter++) {
- Block *Target;
- Branch *Details;
+ for (auto iter = ProcessedBranchesOut.begin();; iter++) {
+ Block* Target;
+ Branch* Details;
if (iter != ProcessedBranchesOut.end()) {
Target = iter->first;
if (Target == DefaultTarget) continue; // done at the end
@@ -300,8 +300,8 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
auto* Inner = Outer;
std::vector<wasm::Name> Table;
for (auto& iter : ProcessedBranchesOut) {
- Block *Target = iter.first;
- Branch *Details = iter.second;
+ Block* Target = iter.first;
+ Branch* Details = iter.second;
wasm::Name CurrName;
if (Details->SwitchValues) {
CurrName = wasm::Name(Base + "$case$" + std::to_string(Target->Id));
@@ -384,12 +384,13 @@ wasm::Expression* SimpleShape::Render(RelooperBuilder& Builder, bool InLoop) {
wasm::Expression* MultipleShape::Render(RelooperBuilder& Builder, bool InLoop) {
// TODO: consider switch
// emit an if-else chain
- wasm::If *FirstIf = nullptr, *CurrIf = nullptr;
+ wasm::If* FirstIf = nullptr;
+ wasm::If* CurrIf = nullptr;
std::vector<wasm::If*> finalizeStack;
- for (IdShapeMap::iterator iter = InnerMap.begin(); iter != InnerMap.end(); iter++) {
+ for (auto& iter : InnerMap) {
auto* Now = Builder.makeIf(
- Builder.makeCheckLabel(iter->first),
- iter->second->Render(Builder, InLoop)
+ Builder.makeCheckLabel(iter.first),
+ iter.second->Render(Builder, InLoop)
);
finalizeStack.push_back(Now);
if (!CurrIf) {
@@ -434,82 +435,87 @@ Relooper::~Relooper() {
for (unsigned i = 0; i < Shapes.size(); i++) delete Shapes[i];
}
-void Relooper::AddBlock(Block *New, int Id) {
+void Relooper::AddBlock(Block* New, int Id) {
New->Id = Id == -1 ? BlockIdCounter++ : Id;
Blocks.push_back(New);
}
-struct RelooperRecursor {
- Relooper *Parent;
- RelooperRecursor(Relooper *ParentInit) : Parent(ParentInit) {}
-};
+namespace {
typedef std::list<Block*> BlockList;
-void Relooper::Calculate(Block *Entry) {
- // Scan and optimize the input
- struct PreOptimizer : public RelooperRecursor {
- PreOptimizer(Relooper *Parent) : RelooperRecursor(Parent) {}
- BlockSet Live;
-
- void FindLive(Block *Root) {
- BlockList ToInvestigate;
- ToInvestigate.push_back(Root);
- while (ToInvestigate.size() > 0) {
- Block *Curr = ToInvestigate.front();
- ToInvestigate.pop_front();
- if (contains(Live, Curr)) continue;
- Live.insert(Curr);
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- ToInvestigate.push_back(iter->first);
- }
+struct RelooperRecursor {
+ Relooper* Parent;
+ RelooperRecursor(Relooper* ParentInit) : Parent(ParentInit) {}
+};
+
+struct Liveness : public RelooperRecursor {
+ Liveness(Relooper* Parent) : RelooperRecursor(Parent) {}
+ BlockSet Live;
+
+ void FindLive(Block* Root) {
+ BlockList ToInvestigate;
+ ToInvestigate.push_back(Root);
+ while (ToInvestigate.size() > 0) {
+ Block* Curr = ToInvestigate.front();
+ ToInvestigate.pop_front();
+ if (contains(Live, Curr)) continue;
+ Live.insert(Curr);
+ for (auto& iter : Curr->BranchesOut) {
+ ToInvestigate.push_back(iter.first);
}
}
- };
- PreOptimizer Pre(this);
- Pre.FindLive(Entry);
+ }
+};
+
+} // namespace
+
+void Relooper::Calculate(Block* Entry) {
+ // Find live blocks.
+ Liveness Live(this);
+ Live.FindLive(Entry);
// Add incoming branches from live blocks, ignoring dead code
for (unsigned i = 0; i < Blocks.size(); i++) {
- Block *Curr = Blocks[i];
- if (!contains(Pre.Live, Curr)) continue;
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- iter->first->BranchesIn.insert(Curr);
+ Block* Curr = Blocks[i];
+ if (!contains(Live.Live, Curr)) continue;
+ for (auto& iter : Curr->BranchesOut) {
+ iter.first->BranchesIn.insert(Curr);
}
}
// Recursively process the graph
struct Analyzer : public RelooperRecursor {
- Analyzer(Relooper *Parent) : RelooperRecursor(Parent) {}
+ Analyzer(Relooper* Parent) : RelooperRecursor(Parent) {}
// Add a shape to the list of shapes in this Relooper calculation
- void Notice(Shape *New) {
+ void Notice(Shape* New) {
New->Id = Parent->ShapeIdCounter++;
Parent->Shapes.push_back(New);
}
// Create a list of entries from a block. If LimitTo is provided, only results in that set
// will appear
- void GetBlocksOut(Block *Source, BlockSet& Entries, BlockSet *LimitTo = nullptr) {
- for (BlockBranchMap::iterator iter = Source->BranchesOut.begin(); iter != Source->BranchesOut.end(); iter++) {
- if (!LimitTo || contains(*LimitTo, iter->first)) {
- Entries.insert(iter->first);
+ void GetBlocksOut(Block* Source, BlockSet& Entries, BlockSet* LimitTo = nullptr) {
+ for (auto& iter : Source->BranchesOut) {
+ if (!LimitTo || contains(*LimitTo, iter.first)) {
+ Entries.insert(iter.first);
}
}
}
// Converts/processes all branchings to a specific target
- void Solipsize(Block *Target, Branch::FlowType Type, Shape *Ancestor, BlockSet &From) {
+ void Solipsize(Block* Target, Branch::FlowType Type, Shape* Ancestor, BlockSet &From) {
PrintDebug("Solipsizing branches into %d\n", Target->Id);
DebugDump(From, " relevant to solipsize: ");
- for (BlockSet::iterator iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
- Block *Prior = *iter;
+ for (auto iter = Target->BranchesIn.begin(); iter != Target->BranchesIn.end();) {
+ Block* Prior = *iter;
if (!contains(From, Prior)) {
iter++;
continue;
}
- Branch *PriorOut = Prior->BranchesOut[Target];
+ Branch* PriorOut = Prior->BranchesOut[Target];
PriorOut->Ancestor = Ancestor;
PriorOut->Type = Type;
iter++; // carefully increment iter before erasing
@@ -521,9 +527,9 @@ void Relooper::Calculate(Block *Entry) {
}
}
- Shape *MakeSimple(BlockSet &Blocks, Block *Inner, BlockSet &NextEntries) {
+ Shape* MakeSimple(BlockSet &Blocks, Block* Inner, BlockSet &NextEntries) {
PrintDebug("creating simple block with block #%d\n", Inner->Id);
- SimpleShape *Simple = new SimpleShape;
+ SimpleShape* Simple = new SimpleShape;
Notice(Simple);
Simple->Inner = Inner;
Inner->Parent = Simple;
@@ -532,34 +538,34 @@ void Relooper::Calculate(Block *Entry) {
GetBlocksOut(Inner, NextEntries, &Blocks);
BlockSet JustInner;
JustInner.insert(Inner);
- for (BlockSet::iterator iter = NextEntries.begin(); iter != NextEntries.end(); iter++) {
- Solipsize(*iter, Branch::Break, Simple, JustInner);
+ for (auto* Next : NextEntries) {
+ Solipsize(Next, Branch::Break, Simple, JustInner);
}
}
return Simple;
}
- Shape *MakeLoop(BlockSet &Blocks, BlockSet& Entries, BlockSet &NextEntries) {
+ Shape* MakeLoop(BlockSet &Blocks, BlockSet& Entries, BlockSet &NextEntries) {
// Find the inner blocks in this loop. Proceed backwards from the entries until
// you reach a seen block, collecting as you go.
BlockSet InnerBlocks;
BlockSet Queue = Entries;
while (Queue.size() > 0) {
- Block *Curr = *(Queue.begin());
+ Block* Curr = *(Queue.begin());
Queue.erase(Queue.begin());
if (!contains(InnerBlocks, Curr)) {
// This element is new, mark it as inner and remove from outer
InnerBlocks.insert(Curr);
Blocks.erase(Curr);
// Add the elements prior to it
- for (BlockSet::iterator iter = Curr->BranchesIn.begin(); iter != Curr->BranchesIn.end(); iter++) {
- Queue.insert(*iter);
+ for (auto* Prev : Curr->BranchesIn) {
+ Queue.insert(Prev);
}
#if 0
// Add elements it leads to, if they are dead ends. There is no reason not to hoist dead ends
// into loops, as it can avoid multiple entries after the loop
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- Block *Target = iter->first;
+ for (auto iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
+ Block* Target = iter->first;
if (Target->BranchesIn.size() <= 1 && Target->BranchesOut.size() == 0) {
Queue.insert(Target);
}
@@ -569,10 +575,9 @@ void Relooper::Calculate(Block *Entry) {
}
assert(InnerBlocks.size() > 0);
- for (BlockSet::iterator iter = InnerBlocks.begin(); iter != InnerBlocks.end(); iter++) {
- Block *Curr = *iter;
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- Block *Possible = iter->first;
+ for (auto* Curr : InnerBlocks) {
+ for (auto& iter : Curr->BranchesOut) {
+ Block* Possible = iter.first;
if (!contains(InnerBlocks, Possible)) {
NextEntries.insert(Possible);
}
@@ -586,10 +591,10 @@ void Relooper::Calculate(Block *Entry) {
FindIndependentGroups(NextEntries, IndependentGroups, &InnerBlocks);
while (IndependentGroups.size() > 0 && NextEntries.size() > 1) {
- Block *Min = nullptr;
+ Block* Min = nullptr;
int MinSize = 0;
- for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
- Block *Entry = iter->first;
+ for (auto iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
+ Block* Entry = iter->first;
BlockSet &Blocks = iter->second;
if (!Min || Blocks.size() < MinSize) { // TODO: code size, not # of blocks
Min = Entry;
@@ -599,10 +604,10 @@ void Relooper::Calculate(Block *Entry) {
// check how many new entries this would cause
BlockSet &Hoisted = IndependentGroups[Min];
bool abort = false;
- for (BlockSet::iterator iter = Hoisted.begin(); iter != Hoisted.end() && !abort; iter++) {
- Block *Curr = *iter;
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- Block *Target = iter->first;
+ for (auto iter = Hoisted.begin(); iter != Hoisted.end() && !abort; iter++) {
+ Block* Curr = *iter;
+ for (auto iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
+ Block* Target = iter->first;
if (!contains(Hoisted, Target) && !contains(NextEntries, Target)) {
// abort this hoisting
abort = true;
@@ -617,8 +622,8 @@ void Relooper::Calculate(Block *Entry) {
// hoist this entry
PrintDebug("hoisting %d into loop\n", Min->Id);
NextEntries.erase(Min);
- for (BlockSet::iterator iter = Hoisted.begin(); iter != Hoisted.end(); iter++) {
- Block *Curr = *iter;
+ for (auto iter = Hoisted.begin(); iter != Hoisted.end(); iter++) {
+ Block* Curr = *iter;
InnerBlocks.insert(Curr);
Blocks.erase(Curr);
}
@@ -633,20 +638,20 @@ void Relooper::Calculate(Block *Entry) {
DebugDump(Blocks, " outer blocks:");
DebugDump(NextEntries, " outer entries:");
- LoopShape *Loop = new LoopShape();
+ LoopShape* Loop = new LoopShape();
Notice(Loop);
// Solipsize the loop, replacing with break/continue and marking branches as Processed (will not affect later calculations)
// A. Branches to the loop entries become a continue to this shape
- for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
- Solipsize(*iter, Branch::Continue, Loop, InnerBlocks);
+ for (auto* Entry : Entries) {
+ Solipsize(Entry, Branch::Continue, Loop, InnerBlocks);
}
// B. Branches to outside the loop (a next entry) become breaks on this shape
- for (BlockSet::iterator iter = NextEntries.begin(); iter != NextEntries.end(); iter++) {
- Solipsize(*iter, Branch::Break, Loop, InnerBlocks);
+ for (auto* Next : NextEntries) {
+ Solipsize(Next, Branch::Break, Loop, InnerBlocks);
}
// Finish up
- Shape *Inner = Process(InnerBlocks, Entries);
+ Shape* Inner = Process(InnerBlocks, Entries);
Loop->Inner = Inner;
Loop->Entries = Entries;
return Loop;
@@ -656,7 +661,7 @@ void Relooper::Calculate(Block *Entry) {
// the entry itself, plus all the blocks it can reach that cannot be directly reached by another entry. Note that we
// ignore directly reaching the entry itself by another entry.
// @param Ignore - previous blocks that are irrelevant
- void FindIndependentGroups(BlockSet &Entries, BlockBlockSetMap& IndependentGroups, BlockSet *Ignore = nullptr) {
+ void FindIndependentGroups(BlockSet &Entries, BlockBlockSetMap& IndependentGroups, BlockSet* Ignore = nullptr) {
typedef std::map<Block*, Block*> BlockBlockMap;
struct HelperClass {
@@ -664,23 +669,23 @@ void Relooper::Calculate(Block *Entry) {
BlockBlockMap Ownership; // For each block, which entry it belongs to. We have reached it from there.
HelperClass(BlockBlockSetMap& IndependentGroupsInit) : IndependentGroups(IndependentGroupsInit) {}
- void InvalidateWithChildren(Block *New) { // TODO: rename New
+ void InvalidateWithChildren(Block* New) { // TODO: rename New
BlockList ToInvalidate; // Being in the list means you need to be invalidated
ToInvalidate.push_back(New);
while (ToInvalidate.size() > 0) {
- Block *Invalidatee = ToInvalidate.front();
+ Block* Invalidatee = ToInvalidate.front();
ToInvalidate.pop_front();
- Block *Owner = Ownership[Invalidatee];
+ Block* Owner = Ownership[Invalidatee];
if (contains(IndependentGroups, Owner)) { // Owner may have been invalidated, do not add to IndependentGroups!
IndependentGroups[Owner].erase(Invalidatee);
}
if (Ownership[Invalidatee]) { // may have been seen before and invalidated already
Ownership[Invalidatee] = nullptr;
- for (BlockBranchMap::iterator iter = Invalidatee->BranchesOut.begin(); iter != Invalidatee->BranchesOut.end(); iter++) {
- Block *Target = iter->first;
- BlockBlockMap::iterator Known = Ownership.find(Target);
+ for (auto& iter : Invalidatee->BranchesOut) {
+ Block* Target = iter.first;
+ auto Known = Ownership.find(Target);
if (Known != Ownership.end()) {
- Block *TargetOwner = Known->second;
+ Block* TargetOwner = Known->second;
if (TargetOwner) {
ToInvalidate.push_back(Target);
}
@@ -699,21 +704,20 @@ void Relooper::Calculate(Block *Entry) {
// visited.
BlockList Queue; // Being in the queue means we just added this item, and we need to add its children
- for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
- Block *Entry = *iter;
+ for (auto* Entry : Entries) {
Helper.Ownership[Entry] = Entry;
IndependentGroups[Entry].insert(Entry);
Queue.push_back(Entry);
}
while (Queue.size() > 0) {
- Block *Curr = Queue.front();
+ Block* Curr = Queue.front();
Queue.pop_front();
- Block *Owner = Helper.Ownership[Curr]; // Curr must be in the ownership map if we are in the queue
+ Block* Owner = Helper.Ownership[Curr]; // Curr must be in the ownership map if we are in the queue
if (!Owner) continue; // we have been invalidated meanwhile after being reached from two entries
// Add all children
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- Block *New = iter->first;
- BlockBlockMap::iterator Known = Helper.Ownership.find(New);
+ for (auto& iter : Curr->BranchesOut) {
+ Block* New = iter.first;
+ auto Known = Helper.Ownership.find(New);
if (Known == Helper.Ownership.end()) {
// New node. Add it, and put it in the queue
Helper.Ownership[New] = Owner;
@@ -721,7 +725,7 @@ void Relooper::Calculate(Block *Entry) {
Queue.push_back(New);
continue;
}
- Block *NewOwner = Known->second;
+ Block* NewOwner = Known->second;
if (!NewOwner) continue; // We reached an invalidated node
if (NewOwner != Owner) {
// Invalidate this and all reachable that we have seen - we reached this from two locations
@@ -737,13 +741,11 @@ void Relooper::Calculate(Block *Entry) {
// if an element has a parent which does *not* have the same owner, we must remove it
// and all its children.
- for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
- BlockSet &CurrGroup = IndependentGroups[*iter];
+ for (auto* Entry : Entries) {
+ BlockSet &CurrGroup = IndependentGroups[Entry];
BlockList ToInvalidate;
- for (BlockSet::iterator iter = CurrGroup.begin(); iter != CurrGroup.end(); iter++) {
- Block *Child = *iter;
- for (BlockSet::iterator iter = Child->BranchesIn.begin(); iter != Child->BranchesIn.end(); iter++) {
- Block *Parent = *iter;
+ for (auto* Child : CurrGroup) {
+ for (auto* Parent : Child->BranchesIn) {
if (Ignore && contains(*Ignore, Parent)) continue;
if (Helper.Ownership[Parent] != Helper.Ownership[Child]) {
ToInvalidate.push_back(Child);
@@ -751,48 +753,47 @@ void Relooper::Calculate(Block *Entry) {
}
}
while (ToInvalidate.size() > 0) {
- Block *Invalidatee = ToInvalidate.front();
+ Block* Invalidatee = ToInvalidate.front();
ToInvalidate.pop_front();
Helper.InvalidateWithChildren(Invalidatee);
}
}
// Remove empty groups
- for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
- if (IndependentGroups[*iter].size() == 0) {
- IndependentGroups.erase(*iter);
+ for (auto* Entry : Entries) {
+ if (IndependentGroups[Entry].size() == 0) {
+ IndependentGroups.erase(Entry);
}
}
#ifdef RELOOPER_DEBUG
PrintDebug("Investigated independent groups:\n");
- for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
- DebugDump(iter->second, " group: ");
+ for (auto& iter : IndependentGroups) {
+ DebugDump(iter.second, " group: ");
}
#endif
}
- Shape *MakeMultiple(BlockSet &Blocks, BlockSet& Entries, BlockBlockSetMap& IndependentGroups, BlockSet &NextEntries, bool IsCheckedMultiple) {
+ Shape* MakeMultiple(BlockSet &Blocks, BlockSet& Entries, BlockBlockSetMap& IndependentGroups, BlockSet &NextEntries, bool IsCheckedMultiple) {
PrintDebug("creating multiple block with %d inner groups\n", IndependentGroups.size());
- MultipleShape *Multiple = new MultipleShape();
+ MultipleShape* Multiple = new MultipleShape();
Notice(Multiple);
BlockSet CurrEntries;
- for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end(); iter++) {
- Block *CurrEntry = iter->first;
- BlockSet &CurrBlocks = iter->second;
+ for (auto& iter : IndependentGroups) {
+ Block* CurrEntry = iter.first;
+ BlockSet &CurrBlocks = iter.second;
PrintDebug(" multiple group with entry %d:\n", CurrEntry->Id);
DebugDump(CurrBlocks, " ");
// Create inner block
CurrEntries.clear();
CurrEntries.insert(CurrEntry);
- for (BlockSet::iterator iter = CurrBlocks.begin(); iter != CurrBlocks.end(); iter++) {
- Block *CurrInner = *iter;
+ for (auto* CurrInner : CurrBlocks) {
// Remove the block from the remaining blocks
Blocks.erase(CurrInner);
// Find new next entries and fix branches to them
- for (BlockBranchMap::iterator iter = CurrInner->BranchesOut.begin(); iter != CurrInner->BranchesOut.end();) {
- Block *CurrTarget = iter->first;
- BlockBranchMap::iterator Next = iter;
+ for (auto iter = CurrInner->BranchesOut.begin(); iter != CurrInner->BranchesOut.end();) {
+ Block* CurrTarget = iter->first;
+ auto Next = iter;
Next++;
if (!contains(CurrBlocks, CurrTarget)) {
NextEntries.insert(CurrTarget);
@@ -808,8 +809,7 @@ void Relooper::Calculate(Block *Entry) {
}
DebugDump(Blocks, " remaining blocks after multiple:");
// Add entries not handled as next entries, they are deferred
- for (BlockSet::iterator iter = Entries.begin(); iter != Entries.end(); iter++) {
- Block *Entry = *iter;
+ for (auto* Entry : Entries) {
if (!contains(IndependentGroups, Entry)) {
NextEntries.insert(Entry);
}
@@ -822,16 +822,16 @@ void Relooper::Calculate(Block *Entry) {
// The Make* functions receive a NextEntries. If they fill it with data, those are the entries for the
// ->Next block on them, and the blocks are what remains in Blocks (which Make* modify). In this way
// we avoid recursing on Next (imagine a long chain of Simples, if we recursed we could blow the stack).
- Shape *Process(BlockSet &Blocks, BlockSet& InitialEntries) {
+ Shape* Process(BlockSet &Blocks, BlockSet& InitialEntries) {
PrintDebug("Process() called\n", 0);
- BlockSet *Entries = &InitialEntries;
+ BlockSet* Entries = &InitialEntries;
BlockSet TempEntries[2];
int CurrTempIndex = 0;
- BlockSet *NextEntries;
- Shape *Ret = nullptr;
- Shape *Prev = nullptr;
+ BlockSet* NextEntries;
+ Shape* Ret = nullptr;
+ Shape* Prev = nullptr;
#define Make(call) \
- Shape *Temp = call; \
+ Shape* Temp = call; \
if (Prev) Prev->Next = Temp; \
if (!Ret) Ret = Temp; \
if (!NextEntries->size()) { PrintDebug("Process() returning\n", 0); return Ret; } \
@@ -849,7 +849,7 @@ void Relooper::Calculate(Block *Entry) {
if (Entries->size() == 0) return Ret;
if (Entries->size() == 1) {
- Block *Curr = *(Entries->begin());
+ Block* Curr = *(Entries->begin());
if (Curr->BranchesIn.size() == 0) {
// One entry, no looping ==> Simple
Make(MakeSimple(Blocks, Curr, *NextEntries));
@@ -871,12 +871,12 @@ void Relooper::Calculate(Block *Entry) {
// Note that it might be reachable by itself - a loop. But that is fine, we will create
// a loop inside the multiple block, which is both the performant order to do it, and
// preserves the property that a loop will always reach an entry.
- for (BlockBlockSetMap::iterator iter = IndependentGroups.begin(); iter != IndependentGroups.end();) {
- Block *Entry = iter->first;
+ for (auto iter = IndependentGroups.begin(); iter != IndependentGroups.end();) {
+ Block* Entry = iter->first;
BlockSet &Group = iter->second;
- BlockBlockSetMap::iterator curr = iter++; // iterate carefully, we may delete
- for (BlockSet::iterator iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
- Block *Origin = *iterBranch;
+ auto curr = iter++; // iterate carefully, we may delete
+ for (auto iterBranch = Entry->BranchesIn.begin(); iterBranch != Entry->BranchesIn.end(); iterBranch++) {
+ Block* Origin = *iterBranch;
if (!contains(Group, Origin)) {
// Reached from outside the group, so we cannot handle this
PrintDebug("Cannot handle group with entry %d because of incoming branch from %d\n", Entry->Id, Origin->Id);
@@ -896,25 +896,24 @@ void Relooper::Calculate(Block *Entry) {
// pointless.
if (IndependentGroups.size() == 2) {
// Find the smaller one
- BlockBlockSetMap::iterator iter = IndependentGroups.begin();
- Block *SmallEntry = iter->first;
+ auto iter = IndependentGroups.begin();
+ Block* SmallEntry = iter->first;
int SmallSize = iter->second.size();
iter++;
- Block *LargeEntry = iter->first;
+ Block* LargeEntry = iter->first;
int LargeSize = iter->second.size();
if (SmallSize != LargeSize) { // ignore the case where they are identical - keep things symmetrical there
if (SmallSize > LargeSize) {
- Block *Temp = SmallEntry;
+ Block* Temp = SmallEntry;
SmallEntry = LargeEntry;
LargeEntry = Temp; // Note: we did not flip the Sizes too, they are now invalid. TODO: use the smaller size as a limit?
}
// Check if dead end
bool DeadEnd = true;
BlockSet &SmallGroup = IndependentGroups[SmallEntry];
- for (BlockSet::iterator iter = SmallGroup.begin(); iter != SmallGroup.end(); iter++) {
- Block *Curr = *iter;
- for (BlockBranchMap::iterator iter = Curr->BranchesOut.begin(); iter != Curr->BranchesOut.end(); iter++) {
- Block *Target = iter->first;
+ for (auto* Curr : SmallGroup) {
+ for (auto& iter : Curr->BranchesOut) {
+ Block* Target = iter.first;
if (!contains(SmallGroup, Target)) {
DeadEnd = false;
break;
@@ -956,8 +955,7 @@ void Relooper::Calculate(Block *Entry) {
// Main
BlockSet AllBlocks;
- for (BlockSet::iterator iter = Pre.Live.begin(); iter != Pre.Live.end(); iter++) {
- Block *Curr = *iter;
+ for (auto* Curr : Live.Live) {
AllBlocks.insert(Curr);
#ifdef RELOOPER_DEBUG
PrintDebug("Adding block %d (%s)\n", Curr->Id, Curr->Code);
@@ -983,30 +981,29 @@ wasm::Expression* Relooper::Render(RelooperBuilder& Builder) {
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;
+ for (auto* Curr : Blocks) {
printf("%d:\n", Curr->Id);
- for (BlockBranchMap::iterator iter2 = Curr->BranchesOut.begin(); iter2 != Curr->BranchesOut.end(); iter2++) {
- Block *Other = iter2->first;
+ for (auto iter2 = Curr->BranchesOut.begin(); iter2 != Curr->BranchesOut.end(); iter2++) {
+ Block* Other = iter2->first;
printf(" -> %d\n", Other->Id);
assert(contains(Other->BranchesIn, Curr));
}
}
}
-void Debugging::Dump(Shape *S, const char *prefix) {
+void Debugging::Dump(Shape* S, const char *prefix) {
if (prefix) printf("%s ", prefix);
if (!S) {
printf(" (null)\n");
return;
}
printf(" %d ", S->Id);
- if (SimpleShape *Simple = Shape::IsSimple(S)) {
+ if (SimpleShape* Simple = Shape::IsSimple(S)) {
printf("<< Simple with block %d\n", Simple->Inner->Id);
- } else if (MultipleShape *Multiple = Shape::IsMultiple(S)) {
+ } else if (MultipleShape* Multiple = Shape::IsMultiple(S)) {
printf("<< Multiple\n");
- for (IdShapeMap::iterator iter = Multiple->InnerMap.begin(); iter != Multiple->InnerMap.end(); iter++) {
- printf(" with entry %d\n", iter->first);
+ for (auto& iter : Multiple->InnerMap) {
+ printf(" with entry %d\n", iter.first);
}
} else if (Shape::IsLoop(S)) {
printf("<< Loop\n");
diff --git a/src/cfg/Relooper.h b/src/cfg/Relooper.h
index 9cd6156f7..5af55a744 100644
--- a/src/cfg/Relooper.h
+++ b/src/cfg/Relooper.h
@@ -82,7 +82,7 @@ struct Branch {
Break = 1,
Continue = 2
};
- Shape *Ancestor; // If not NULL, this shape is the relevant one for purposes of getting to the target block. We break or continue on it
+ Shape* Ancestor; // If not NULL, this shape is the relevant one for purposes of getting to the target block. We break or continue on it
Branch::FlowType Type; // If Ancestor is not NULL, this says whether to break or continue
// A branch either has a condition expression if the block ends in ifs, or if the block ends in a switch, then a list of indexes, which
@@ -97,7 +97,7 @@ struct Branch {
Branch(std::vector<wasm::Index>&& ValuesInit, wasm::Expression* CodeInit = nullptr);
// Emits code for branch
- wasm::Expression* Render(RelooperBuilder& Builder, Block *Target, bool SetLabel);
+ wasm::Expression* Render(RelooperBuilder& Builder, Block* Target, bool SetLabel);
};
// like std::set, except that begin() -> end() iterates in the
@@ -223,7 +223,7 @@ struct Block {
BlockSet BranchesIn;
BlockBranchMap ProcessedBranchesOut;
BlockSet ProcessedBranchesIn;
- Shape *Parent; // The shape we are directly inside
+ Shape* Parent; // The shape we are directly inside
int Id; // A unique identifier, defined when added to relooper
wasm::Expression* Code; // The code in this block. This can be arbitrary wasm code, including internal control flow, it should just not branch to the outside
wasm::Expression* SwitchCondition; // If nullptr, then this block ends in ifs (or nothing). otherwise, this block ends in a switch, done on this condition
@@ -239,11 +239,13 @@ struct Block {
// instruction, as the relooper doesn't know whether you want control flow to stop with
// an `unreachable` or a `return` or something else (if you forget to do this, control
// flow may continue into the block that happens to be emitted right after it).
- void AddBranchTo(Block *Target, wasm::Expression* Condition, wasm::Expression* Code = nullptr);
+ // Internally, adding a branch only adds the outgoing branch. The matching incoming branch
+ // on the target is added by the Relooper itself as it works.
+ void AddBranchTo(Block* Target, wasm::Expression* Condition, wasm::Expression* Code = nullptr);
// Add a switch branch: if the switch condition is one of these values, we branch (or if the list is empty, we are the default)
// Note that there can be only one branch from A to B (if you need multiple values for the branch, that's what the array and default are for).
- void AddSwitchBranchTo(Block *Target, std::vector<wasm::Index>&& Values, wasm::Expression* Code = nullptr);
+ void AddSwitchBranchTo(Block* Target, std::vector<wasm::Index>&& Values, wasm::Expression* Code = nullptr);
// Emit code for the block, including its contents and branchings out
wasm::Expression* Render(RelooperBuilder& Builder, bool InLoop);
@@ -273,8 +275,8 @@ struct LoopShape;
struct Shape {
int Id; // A unique identifier. Used to identify loops, labels are Lx where x is the Id. Defined when added to relooper
- Shape *Next; // The shape that will appear in the code right after this one
- Shape *Natural; // The shape that control flow gets to naturally (if there is Next, then this is Next)
+ Shape* Next; // The shape that will appear in the code right after this one
+ Shape* Natural; // The shape that control flow gets to naturally (if there is Next, then this is Next)
enum ShapeType {
Simple,
@@ -288,13 +290,13 @@ struct Shape {
virtual wasm::Expression* Render(RelooperBuilder& Builder, bool InLoop) = 0;
- static SimpleShape *IsSimple(Shape *It) { return It && It->Type == Simple ? (SimpleShape*)It : NULL; }
- static MultipleShape *IsMultiple(Shape *It) { return It && It->Type == Multiple ? (MultipleShape*)It : NULL; }
- static LoopShape *IsLoop(Shape *It) { return It && It->Type == Loop ? (LoopShape*)It : NULL; }
+ static SimpleShape* IsSimple(Shape* It) { return It && It->Type == Simple ? (SimpleShape*)It : NULL; }
+ static MultipleShape* IsMultiple(Shape* It) { return It && It->Type == Multiple ? (MultipleShape*)It : NULL; }
+ static LoopShape* IsLoop(Shape* It) { return It && It->Type == Loop ? (LoopShape*)It : NULL; }
};
struct SimpleShape : public Shape {
- Block *Inner;
+ Block* Inner;
SimpleShape() : Shape(Simple), Inner(NULL) {}
wasm::Expression* Render(RelooperBuilder& Builder, bool InLoop) override;
@@ -311,7 +313,7 @@ struct MultipleShape : public Shape {
};
struct LoopShape : public Shape {
- Shape *Inner;
+ Shape* Inner;
BlockSet Entries; // we must visit at least one of these
@@ -333,7 +335,7 @@ struct LoopShape : public Shape {
struct Relooper {
std::deque<Block*> Blocks;
std::deque<Shape*> Shapes;
- Shape *Root;
+ Shape* Root;
bool MinSize;
int BlockIdCounter;
int ShapeIdCounter;
@@ -341,10 +343,10 @@ struct Relooper {
Relooper();
~Relooper();
- void AddBlock(Block *New, int Id=-1);
+ void AddBlock(Block* New, int Id=-1);
// Calculates the shapes
- void Calculate(Block *Entry);
+ void Calculate(Block* Entry);
// Renders the result.
wasm::Expression* Render(RelooperBuilder& Builder);
@@ -358,7 +360,7 @@ typedef InsertOrderedMap<Block*, BlockSet> BlockBlockSetMap;
#ifdef RELOOPER_DEBUG
struct Debugging {
static void Dump(BlockSet &Blocks, const char *prefix=NULL);
- static void Dump(Shape *S, const char *prefix=NULL);
+ static void Dump(Shape* S, const char *prefix=NULL);
};
#endif