diff options
Diffstat (limited to 'src/relooper/Relooper.h')
-rw-r--r-- | src/relooper/Relooper.h | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/src/relooper/Relooper.h b/src/relooper/Relooper.h index f3dedf8c..85adf359 100644 --- a/src/relooper/Relooper.h +++ b/src/relooper/Relooper.h @@ -57,7 +57,7 @@ struct Block { BlockBranchMap ProcessedBranchesOut; BlockSet ProcessedBranchesIn; Shape *Parent; // The shape we are directly inside - int Id; // A unique identifier + int Id; // A unique identifier, defined when added to relooper. Note that this uniquely identifies a *logical* block - if we split it, the two instances have the same content *and* the same Id const char *Code; // The string representation of the code in this block. Owning pointer (we copy the input) const char *BranchVar; // If we have more than one branch out, the variable whose value determines where we go bool IsCheckedMultipleEntry; // If true, we are a multiple entry, so reaching us requires setting the label variable @@ -69,9 +69,6 @@ struct Block { // Prints out the instructions code and branchings void Render(bool InLoop); - - // INTERNAL - static int IdCounter; }; // Represents a structured control flow shape, one of @@ -92,24 +89,26 @@ struct Block { // setjmp returns, etc.) // -class SimpleShape; -class LabeledShape; -class MultipleShape; -class LoopShape; +struct SimpleShape; +struct LabeledShape; +struct MultipleShape; +struct LoopShape; +struct EmulatedShape; struct Shape { - int Id; // A unique identifier. Used to identify loops, labels are Lx where x is the Id. + 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) enum ShapeType { Simple, Multiple, - Loop + Loop, + Emulated }; ShapeType Type; - Shape(ShapeType TypeInit) : Id(Shape::IdCounter++), Next(NULL), Type(TypeInit) {} + Shape(ShapeType TypeInit) : Id(-1), Next(NULL), Type(TypeInit) {} virtual ~Shape() {} virtual void Render(bool InLoop) = 0; @@ -118,9 +117,7 @@ struct Shape { 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 LabeledShape *IsLabeled(Shape *It) { return IsMultiple(It) || IsLoop(It) ? (LabeledShape*)It : NULL; } - - // INTERNAL - static int IdCounter; + static EmulatedShape *IsEmulated(Shape *It) { return It && It->Type == Emulated ? (EmulatedShape*)It : NULL; } }; struct SimpleShape : public Shape { @@ -162,12 +159,15 @@ struct LoopShape : public LabeledShape { void Render(bool InLoop); }; -/* -struct EmulatedShape : public Shape { - std::deque<Block*> Blocks; +// TODO EmulatedShape is only partially functional. Currently it can be used for the +// entire set of blocks being relooped, but not subsets. +struct EmulatedShape : public LabeledShape { + Block *Entry; + BlockSet Blocks; + + EmulatedShape() : LabeledShape(Emulated) { Labeled = true; } void Render(bool InLoop); }; -*/ // Implements the relooper algorithm for a function's blocks. // @@ -184,11 +184,14 @@ struct Relooper { std::deque<Block*> Blocks; std::deque<Shape*> Shapes; Shape *Root; + bool Emulate; + int BlockIdCounter; + int ShapeIdCounter; Relooper(); ~Relooper(); - void AddBlock(Block *New); + void AddBlock(Block *New, int Id=-1); // Calculates the shapes void Calculate(Block *Entry); @@ -197,13 +200,21 @@ struct Relooper { void Render(); // Sets the global buffer all printing goes to. Must call this or MakeOutputBuffer. + // XXX: this is deprecated, see MakeOutputBuffer static void SetOutputBuffer(char *Buffer, int Size); - // Creates an output buffer. Must call this or SetOutputBuffer. + // Creates an internal output buffer. Must call this or SetOutputBuffer. Size is + // a hint for the initial size of the buffer, it can be resized later one demand. + // For that reason this is more recommended than SetOutputBuffer. static void MakeOutputBuffer(int Size); + static char *GetOutputBuffer(); + // Sets asm.js mode on or off (default is off) static void SetAsmJSMode(int On); + + // Sets whether we must emulate everything with switch-loop code + void SetEmulate(int E) { Emulate = E; } }; typedef std::map<Block*, BlockSet> BlockBlockSetMap; |