My Project
|
A control-flow block built out of sub-components. More...
#include <block.hh>
Public Member Functions | |
void | clear (void) |
Clear all component FlowBlock objects. | |
virtual | ~BlockGraph (void) |
Destructor. | |
const vector< FlowBlock * > & | getList (void) const |
Get the list of component FlowBlock objects. | |
int4 | getSize (void) const |
Get the number of components. | |
FlowBlock * | getBlock (int4 i) const |
Get the i-th component. | |
virtual block_type | getType (void) const |
Get the FlowBlock type of this. | |
virtual FlowBlock * | subBlock (int4 i) const |
Get the i-th component block. | |
virtual void | markUnstructured (void) |
Mark target blocks of any unstructured edges. | |
virtual void | markLabelBumpUp (bool bump) |
Let hierarchical blocks steal labels of their (first) components. More... | |
virtual void | scopeBreak (int4 curexit, int4 curloopexit) |
Mark unstructured edges that should be breaks. | |
virtual void | printTree (ostream &s, int4 level) const |
Print tree structure of any blocks owned by this. More... | |
virtual void | printRaw (ostream &s) const |
Print raw instructions contained in this FlowBlock. | |
virtual void | emit (PrintLanguage *lng) const |
Emit the instructions in this FlowBlock as structured code. More... | |
virtual FlowBlock * | nextFlowAfter (const FlowBlock *bl) const |
Get the leaf FlowBlock that will execute after the given FlowBlock. More... | |
virtual void | orderSwitchCases (void) const |
Order case components of any contained BlockSwitch. | |
virtual void | saveXmlBody (ostream &s) const |
Save detail about components to an XML stream. | |
virtual void | restoreXmlBody (List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver) |
Restore details about this FlowBlock from an XML stream. More... | |
void | restoreXml (const Element *el, const AddrSpaceManager *m) |
Restore this BlockGraph from an XML stream. More... | |
void | addEdge (FlowBlock *begin, FlowBlock *end) |
Add a directed edge between component FlowBlocks. More... | |
void | addLoopEdge (FlowBlock *begin, int4 outindex) |
Mark a given edge as a loop edge. More... | |
void | removeEdge (FlowBlock *begin, FlowBlock *end) |
Remove an edge between component FlowBlocks. More... | |
void | switchEdge (FlowBlock *in, FlowBlock *outbefore, FlowBlock *outafter) |
Move an edge from one out FlowBlock to another. More... | |
void | moveOutEdge (FlowBlock *blold, int4 slot, FlowBlock *blnew) |
Move indicated out edge to a new FlowBlock. More... | |
void | removeBlock (FlowBlock *bl) |
Remove a FlowBlock from this BlockGraph. More... | |
void | removeFromFlow (FlowBlock *bl) |
Remove given FlowBlock preserving flow in this. More... | |
void | removeFromFlowSplit (FlowBlock *bl, bool flipflow) |
Remove FlowBlock splitting flow between input and output edges. More... | |
void | spliceBlock (FlowBlock *bl) |
Splice given FlowBlock together with its output. More... | |
void | setStartBlock (FlowBlock *bl) |
Set the entry point FlowBlock for this graph. More... | |
FlowBlock * | getStartBlock (void) const |
Get the entry point FlowBlock. More... | |
FlowBlock * | newBlock (void) |
Build a new plain FlowBlock. More... | |
BlockBasic * | newBlockBasic (Funcdata *fd) |
Build a new BlockBasic. More... | |
BlockCopy * | newBlockCopy (FlowBlock *bl) |
Build a new BlockCopy. More... | |
BlockGoto * | newBlockGoto (FlowBlock *bl) |
Build a new BlockGoto. More... | |
BlockMultiGoto * | newBlockMultiGoto (FlowBlock *bl, int4 outedge) |
Build a new BlockMultiGoto. More... | |
BlockList * | newBlockList (const vector< FlowBlock *> &nodes) |
Build a new BlockList. More... | |
BlockCondition * | newBlockCondition (FlowBlock *b1, FlowBlock *b2) |
Build a new BlockCondition. More... | |
BlockIf * | newBlockIfGoto (FlowBlock *cond) |
Build a new BlockIfGoto. More... | |
BlockIf * | newBlockIf (FlowBlock *cond, FlowBlock *tc) |
Build a new BlockIf. More... | |
BlockIf * | newBlockIfElse (FlowBlock *cond, FlowBlock *tc, FlowBlock *fc) |
Build a new BlockIfElse. More... | |
BlockWhileDo * | newBlockWhileDo (FlowBlock *cond, FlowBlock *cl) |
Build a new BlockWhileDo. More... | |
BlockDoWhile * | newBlockDoWhile (FlowBlock *condcl) |
Build a new BlockDoWhile. More... | |
BlockInfLoop * | newBlockInfLoop (FlowBlock *body) |
Build a new BlockInfLoop. More... | |
BlockSwitch * | newBlockSwitch (const vector< FlowBlock *> &cs, bool hasExit) |
Build a new BlockSwitch. More... | |
void | orderBlocks (void) |
void | buildCopy (const BlockGraph &graph) |
Build a copy of a BlockGraph. More... | |
void | clearVisitCount (void) |
Clear the visit count in all node FlowBlocks. | |
void | calcForwardDominator (const vector< FlowBlock *> &rootlist) |
Calculate forward dominators. More... | |
void | buildDomTree (vector< vector< FlowBlock *> > &child) const |
Build the dominator tree. More... | |
int4 | buildDomDepth (vector< int4 > &depth) const |
Calculate dominator depths. More... | |
void | buildDomSubTree (vector< FlowBlock *> &res, FlowBlock *root) const |
Collect nodes from a dominator sub-tree. More... | |
void | calcLoop (void) |
Calculate loop edges. More... | |
void | collectReachable (vector< FlowBlock *> &res, FlowBlock *bl, bool un) const |
Collect reachable/unreachable FlowBlocks from a given start FlowBlock. More... | |
void | structureLoops (vector< FlowBlock *> &rootlist) |
Label loop edges. More... | |
Public Member Functions inherited from FlowBlock | |
FlowBlock (void) | |
Construct a block with no edges. | |
virtual | ~FlowBlock (void) |
Destructor. | |
int4 | getIndex (void) const |
Get the index assigned to this block. | |
FlowBlock * | getParent (void) |
Get the parent FlowBlock of this. | |
FlowBlock * | getImmedDom (void) const |
Get the immediate dominator FlowBlock. | |
FlowBlock * | getCopyMap (void) const |
Get the mapped FlowBlock. | |
const FlowBlock * | getParent (void) const |
Get the parent FlowBlock of this. | |
uint4 | getFlags (void) const |
Get the block_flags properties. | |
virtual Address | getStart (void) const |
Get the starting address of code in this FlowBlock. | |
virtual Address | getStop (void) const |
Get the ending address of code in this FlowBlock. | |
virtual void | printHeader (ostream &s) const |
Print a simple description of this to stream. More... | |
virtual const FlowBlock * | getExitLeaf (void) const |
Get the FlowBlock to which this block exits. | |
virtual PcodeOp * | lastOp (void) const |
Get the last PcodeOp executed by this FlowBlock. | |
virtual bool | negateCondition (bool toporbottom) |
Flip the condition computed by this. More... | |
virtual bool | preferComplement (Funcdata &data) |
Rearrange this hierarchy to simplify boolean expressions. More... | |
virtual FlowBlock * | getSplitPoint (void) |
Get the leaf splitting block. More... | |
virtual int4 | flipInPlaceTest (vector< PcodeOp *> &fliplist) const |
Test normalizing the conditional branch in this. More... | |
virtual void | flipInPlaceExecute (void) |
Perform the flip to normalize conditional branch executed by this block. More... | |
virtual bool | isComplex (void) const |
Is this too complex to be a condition (BlockCondition) | |
virtual void | saveXmlHeader (ostream &s) const |
Save basic information as XML attributes. More... | |
virtual void | restoreXmlHeader (const Element *el) |
Restore basic information for XML attributes. More... | |
void | saveXmlEdges (ostream &s) const |
Save edge information to an XML stream. More... | |
void | restoreXmlEdges (List::const_iterator &iter, List::const_iterator enditer, BlockMap &resolver) |
Restore edges from an XML stream. More... | |
void | saveXml (ostream &s) const |
Write out this to an XML stream. More... | |
void | restoreXml (const Element *el, BlockMap &resolver) |
Restore this from an XML stream. More... | |
const FlowBlock * | nextInFlow (void) const |
Return next block to be executed in flow. More... | |
void | setVisitCount (int4 i) |
Set the number of times this block has been visited. | |
int4 | getVisitCount (void) const |
Get the count of visits. | |
void | setGotoBranch (int4 i) |
Mark a goto branch. More... | |
void | setDefaultSwitch (int4 i) |
Mark an edge as the switch default. | |
bool | isMark (void) const |
Return true if this block has been marked. | |
void | setMark (void) |
Mark this block. | |
void | clearMark (void) |
Clear any mark on this block. | |
void | setDonothingLoop (void) |
Label this as a do nothing loop. | |
void | setDead (void) |
Label this as dead. | |
bool | hasSpecialLabel (void) const |
Return true if this uses a different label. | |
bool | isJoined (void) const |
Return true if this is a joined basic block. | |
bool | isDuplicated (void) const |
Return true if this is a duplicated block. | |
void | setLoopExit (int4 i) |
Label the edge exiting this as a loop. | |
void | clearLoopExit (int4 i) |
Clear the loop exit edge. | |
void | setBackEdge (int4 i) |
Label the back edge of a loop. | |
bool | getFlipPath (void) const |
Have out edges been flipped. | |
bool | isJumpTarget (void) const |
Return true if non-fallthru jump flows into this. More... | |
FlowBlock * | getFalseOut (void) const |
Get the false output FlowBlock. | |
FlowBlock * | getTrueOut (void) const |
Get the true output FlowBlock. | |
FlowBlock * | getOut (int4 i) |
Get the i-th output FlowBlock. | |
const FlowBlock * | getOut (int4 i) const |
Get i-th output FlowBlock. | |
int4 | getOutRevIndex (int4 i) const |
Get the input index of the i-th output FlowBlock. | |
FlowBlock * | getIn (int4 i) |
Get the i-th input FlowBlock. | |
const FlowBlock * | getIn (int4 i) const |
Get the i-th input FlowBlock. | |
int4 | getInRevIndex (int4 i) const |
Get the output index of the i-th input FlowBlock. | |
const FlowBlock * | getFrontLeaf (void) const |
Get the first leaf FlowBlock. More... | |
FlowBlock * | getFrontLeaf (void) |
Get the first leaf FlowBlock. More... | |
int4 | calcDepth (const FlowBlock *leaf) const |
Get the depth of the given component FlowBlock. More... | |
bool | dominates (const FlowBlock *subBlock) const |
Does this block dominate the given block. More... | |
bool | restrictedByConditional (const FlowBlock *cond) const |
Check if the condition from the given block holds for this block. More... | |
int4 | sizeOut (void) const |
Get the number of out edges. | |
int4 | sizeIn (void) const |
Get the number of in edges. | |
bool | hasLoopIn (void) const |
Is there a looping edge coming into this block. More... | |
bool | hasLoopOut (void) const |
Is there a looping edge going out of this block. More... | |
bool | isLoopIn (int4 i) const |
Is the i-th incoming edge a loop edge. | |
bool | isLoopOut (int4 i) const |
Is the i-th outgoing edge a loop edge. | |
int4 | getInIndex (const FlowBlock *bl) const |
Get the incoming edge index for the given FlowBlock. More... | |
int4 | getOutIndex (const FlowBlock *bl) const |
Get the outgoing edge index for the given FlowBlock. More... | |
bool | isDefaultBranch (int4 i) const |
Is the i-th out edge the switch default edge. | |
bool | isLabelBumpUp (void) const |
Are labels for this printed by the parent. | |
bool | isUnstructuredTarget (void) const |
Is this the target of an unstructured goto. | |
bool | isInteriorGotoTarget (void) const |
Is there an unstructured goto to this block's interior. | |
bool | hasInteriorGoto (void) const |
Is there an unstructured goto out of this block's interior. | |
bool | isEntryPoint (void) const |
Is the entry point of the function. | |
bool | isSwitchOut (void) const |
Is this a switch block. | |
bool | isDonothingLoop (void) const |
Is this a do nothing block. | |
bool | isDead (void) const |
Is this block dead. | |
bool | isTreeEdgeIn (int4 i) const |
Is the i-th incoming edge part of the spanning tree. | |
bool | isBackEdgeIn (int4 i) const |
Is the i-th incoming edge a back edge. | |
bool | isBackEdgeOut (int4 i) const |
Is the i-th outgoing edge a back edge. | |
bool | isIrreducibleOut (int4 i) const |
Is the i-th outgoing edge an irreducible edge. | |
bool | isIrreducibleIn (int4 i) const |
Is the i-th incoming edge an irreducible edge. | |
bool | isDecisionOut (int4 i) const |
Can this and the i-th output be merged into a BlockIf or BlockList. | |
bool | isDecisionIn (int4 i) const |
Can this and the i-th input be merged into a BlockIf or BlockList. | |
bool | isLoopDAGOut (int4 i) const |
Is the i-th outgoing edge part of the DAG sub-graph. | |
bool | isLoopDAGIn (int4 i) const |
Is the i-th incoming edge part of the DAG sub-graph. | |
bool | isGotoIn (int4 i) const |
Is the i-th incoming edge unstructured. | |
bool | isGotoOut (int4 i) const |
Is the i-th outgoing edge unstructured. | |
JumpTable * | getJumptable (void) const |
Get the JumpTable associated this block. More... | |
Protected Member Functions | |
void | swapBlocks (int4 i, int4 j) |
Swap the positions two component FlowBlocks. More... | |
Protected Member Functions inherited from FlowBlock | |
void | setFlag (uint4 fl) |
Set a boolean property. | |
void | clearFlag (uint4 fl) |
Clear a boolean property. | |
Static Protected Member Functions | |
static void | markCopyBlock (FlowBlock *bl, uint4 fl) |
Set properties on the first leaf FlowBlock. More... | |
Additional Inherited Members | |
Public Types inherited from FlowBlock | |
enum | block_type { t_plain, t_basic, t_graph, t_copy, t_goto, t_multigoto, t_ls, t_condition, t_if, t_whiledo, t_dowhile, t_switch, t_infloop } |
The possible block types. | |
enum | block_flags { f_goto_goto = 1, f_break_goto = 2, f_continue_goto = 4, f_switch_out = 0x10, f_unstructured_targ = 0x20, f_mark = 0x80, f_mark2 = 0x100, f_entry_point = 0x200, f_interior_gotoout = 0x400, f_interior_gotoin = 0x800, f_label_bumpup = 0x1000, f_donothing_loop = 0x2000, f_dead = 0x4000, f_whiledo_overflow = 0x8000, f_flip_path = 0x10000, f_joined_block = 0x20000, f_duplicate_block = 0x40000 } |
Boolean properties of blocks. More... | |
enum | edge_flags { f_goto_edge = 1, f_loop_edge = 2, f_defaultswitch_edge = 4, f_irreducible = 8, f_tree_edge = 0x10, f_forward_edge = 0x20, f_cross_edge = 0x40, f_back_edge = 0x80, f_loop_exit_edge = 0x100 } |
Boolean properties on edges. More... | |
Static Public Member Functions inherited from FlowBlock | |
static block_type | nameToType (const string &name) |
Get the block_type associated with a name string. More... | |
static string | typeToName (block_type bt) |
Get the name string associated with a block_type. More... | |
static bool | compareBlockIndex (const FlowBlock *bl1, const FlowBlock *bl2) |
Compare FlowBlock by index. More... | |
static bool | compareFinalOrder (const FlowBlock *bl1, const FlowBlock *bl2) |
Final FlowBlock comparison. More... | |
static FlowBlock * | findCommonBlock (FlowBlock *bl1, FlowBlock *bl2) |
Find the common dominator of two FlowBlocks. More... | |
static FlowBlock * | findCommonBlock (const vector< FlowBlock *> &blockSet) |
Find common dominator of multiple FlowBlocks. More... | |
A control-flow block built out of sub-components.
This is the core class for building a hierarchy of control-flow blocks. A set of control-flow blocks can be grouped together and viewed as a single block, with its own input and output blocks. All the code structuring elements (BlockList, BlockIf, BlockWhileDo, etc.) derive from this.
void BlockGraph::addLoopEdge | ( | FlowBlock * | begin, |
int4 | outindex | ||
) |
Mark a given edge as a loop edge.
begin | is a given component FlowBlock |
outindex | is the index of the out edge to mark as a loop |
void BlockGraph::buildCopy | ( | const BlockGraph & | graph | ) |
Build a copy of a BlockGraph.
Construct a copy of the given BlockGraph in this. The nodes of the copy will be official BlockCopy objects which will contain a reference to their corresponding FlowBlock in the given graph. All edges will be duplicated.
graph | is the given BlockGraph to copy |
int4 BlockGraph::buildDomDepth | ( | vector< int4 > & | depth | ) | const |
Calculate dominator depths.
Associate every FlowBlock node in this graph with its depth in the dominator tree. The dominator root has depth 1, the nodes it immediately dominates have depth 2, etc.
depth | is array that will be populated with depths |
void BlockGraph::buildDomTree | ( | vector< vector< FlowBlock *> > & | child | ) | const |
Build the dominator tree.
Associate dominator children with each node via a list (of lists) indexed by the FlowBlock index.
child | is the initially empty list of lists |
void BlockGraph::calcForwardDominator | ( | const vector< FlowBlock *> & | rootlist | ) |
Calculate forward dominators.
Calculate the immediate dominator for each FlowBlock node in this BlockGraph, for forward control-flow. The algorithm must be provided a list of entry points for the graph. We assume the blocks are in reverse post-order and this is reflected in the index field. Using an algorithm by Cooper, Harvey, and Kennedy. Softw. Pract. Exper. 2001; 4: 1-10
rootlist | is the list of entry point FlowBlocks |
void BlockGraph::calcLoop | ( | void | ) |
Calculate loop edges.
This algorithm identifies a set of edges such that, if the edges are removed, the remaining graph has NO directed cycles The algorithm works as follows: Starting from the start block, do a depth first search through the "out" edges of the block. If the outblock is already on the current path from root to node, we have found a cycle, we add the last edge to the list and continue pretending that edge didn't exist. If the outblock is not on the current path but has been visited before, we can truncate the search. This is now only applied as a failsafe if the graph has irreducible edges.
|
inlinevirtual |
Emit the instructions in this FlowBlock as structured code.
This is the main entry point, at the control-flow level, for printing structured code.
lng | is the PrintLanguage that provides details of the high-level language being printed |
Reimplemented from FlowBlock.
Reimplemented in BlockSwitch, BlockInfLoop, BlockDoWhile, BlockWhileDo, BlockIf, BlockCondition, BlockList, BlockMultiGoto, and BlockGoto.
FlowBlock * BlockGraph::getStartBlock | ( | void | ) | const |
|
staticprotected |
Set properties on the first leaf FlowBlock.
For the given BlockGraph find the first component leaf FlowBlock and set its properties
bl | is the given BlockGraph |
fl | is the property to set |
|
virtual |
Let hierarchical blocks steal labels of their (first) components.
bump | if true, mark that labels for this block are printed by somebody higher in hierarchy |
Reimplemented from FlowBlock.
Reimplemented in BlockInfLoop, BlockDoWhile, and BlockWhileDo.
FlowBlock * BlockGraph::newBlock | ( | void | ) |
BlockBasic * BlockGraph::newBlockBasic | ( | Funcdata * | fd | ) |
Build a new BlockBasic.
Add the new BlockBasic to this
fd | is the function underlying the basic block |
BlockCondition * BlockGraph::newBlockCondition | ( | FlowBlock * | b1, |
FlowBlock * | b2 | ||
) |
Build a new BlockCondition.
Add the new BlockCondition to this, collapsing its pieces into it.
BlockDoWhile * BlockGraph::newBlockDoWhile | ( | FlowBlock * | condcl | ) |
Build a new BlockDoWhile.
Add the new BlockDoWhile to this, collapsing the condition clause FlowBlock into it.
condcl | is the condition clause FlowBlock |
BlockInfLoop * BlockGraph::newBlockInfLoop | ( | FlowBlock * | body | ) |
Build a new BlockInfLoop.
Add the new BlockInfLoop to this, collapsing the body FlowBlock into it.
body | is the body FlowBlock |
BlockMultiGoto * BlockGraph::newBlockMultiGoto | ( | FlowBlock * | bl, |
int4 | outedge | ||
) |
Build a new BlockMultiGoto.
The given FlowBlock may already be a BlockMultiGoto, otherwise we add the new BlockMultiGoto to this.
bl | is the given FlowBlock with the new goto edge |
outedge | is the index of the outgoing edge to make into a goto |
BlockSwitch * BlockGraph::newBlockSwitch | ( | const vector< FlowBlock *> & | cs, |
bool | hasExit | ||
) |
Build a new BlockSwitch.
Add the new BlockSwitch to this, collapsing all the case FlowBlocks into it.
cs | is the list of case FlowBlocks |
hasExit | is true if the switch has a formal exit |
BlockWhileDo * BlockGraph::newBlockWhileDo | ( | FlowBlock * | cond, |
FlowBlock * | cl | ||
) |
Build a new BlockWhileDo.
Add the new BlockWhileDo to this, collapsing the condition and clause into it.
Get the leaf FlowBlock that will execute after the given FlowBlock.
Within the hierarchy of this FlowBlock, assume the given FlowBlock will fall-thru in its execution at some point. Return the first leaf block (BlockBasic or BlockCopy) that will execute after the given FlowBlock completes, assuming this is a unique block.
bl | is the given FlowBlock |
Reimplemented from FlowBlock.
Reimplemented in BlockSwitch, BlockInfLoop, BlockDoWhile, BlockWhileDo, BlockIf, BlockCondition, BlockMultiGoto, and BlockGoto.
|
inline |
< Sort blocks using the final ordering
|
virtual |
void BlockGraph::removeBlock | ( | FlowBlock * | bl | ) |
Remove a FlowBlock from this BlockGraph.
The indicated block is pulled out of the component list and deleted. Any edges between it and the rest of the BlockGraph are simply removed.
bl | is the indicated block |
void BlockGraph::removeFromFlow | ( | FlowBlock * | bl | ) |
Remove given FlowBlock preserving flow in this.
This should be applied only if the given FlowBlock has 0 or 1 outputs. If there is an output FlowBlock, all incoming edges to the given FlowBlock are moved so they flow into the output FlowBlock, then all remaining edges into or out of the given FlowBlock are removed. The given FlowBlock is not removed from this. This routine doesn't preserve loopedge information
bl | is the given FlowBlock component |
void BlockGraph::removeFromFlowSplit | ( | FlowBlock * | bl, |
bool | flipflow | ||
) |
Remove FlowBlock splitting flow between input and output edges.
Remove the given FlowBlock from the flow of the graph. It must have 2 inputs, and 2 outputs. The edges will be remapped so that
Or if flipflow is true:
bl | is the given FlowBlock |
flipflow | indicates how the edges are remapped |
void BlockGraph::restoreXml | ( | const Element * | el, |
const AddrSpaceManager * | m | ||
) |
Restore this BlockGraph from an XML stream.
This is currently just a wrapper around the FlowBlock::restoreXml() that sets of the BlockMap resolver
el | is the root <block> tag |
m | is the address space manager |
|
virtual |
void BlockGraph::setStartBlock | ( | FlowBlock * | bl | ) |
void BlockGraph::spliceBlock | ( | FlowBlock * | bl | ) |
Splice given FlowBlock together with its output.
The given FlowBlock must have exactly one output. That output must have exactly one input. The output FlowBlock is removed and any outgoing edges it has become outgoing edge of the given FlowBlock. The output FlowBlock is permanently removed. It is viewed as being spliced together with the given FlowBlock.
bl | is the given FlowBlock |
void BlockGraph::structureLoops | ( | vector< FlowBlock *> & | rootlist | ) |
Label loop edges.
rootlist | will contain the entry points for the graph |
|
protected |
Swap the positions two component FlowBlocks.
i | is the position of the first FlowBlock to swap |
j | is the position of the second |
Move an edge from one out FlowBlock to another.
The edge from in to outbefore must already exist. It will get removed and replaced with an edge from in to outafter. The new edge index will be the same as the removed edge, and all other edge ordering will be preserved.