Ghidra Decompiler Analysis Engine
|
A description of the body of a loop. More...
#include <blockaction.hh>
Public Member Functions | |
FlowBlock * | getCurrentBounds (FlowBlock **top, FlowBlock *graph) |
Return current loop bounds (head and bottom). More... | |
void | findBase (vector< FlowBlock * > &body) |
Mark the body FlowBlocks of this loop. More... | |
void | extend (vector< FlowBlock * > &body) const |
Extend body (to blocks that never exit) More... | |
void | findExit (const vector< FlowBlock * > &body) |
Choose the exit block for this loop. More... | |
void | orderTails (void) |
Find preferred tail. More... | |
void | labelExitEdges (const vector< FlowBlock * > &body) |
Label edges that exit the loop. More... | |
void | labelContainments (const vector< FlowBlock * > &body, const vector< LoopBody * > &looporder) |
Record any loops that body contains. More... | |
void | emitLikelyEdges (list< FloatingEdge > &likely, FlowBlock *graph) |
Collect likely unstructured edges. More... | |
void | setExitMarks (FlowBlock *graph) |
Mark all the exits to this loop. More... | |
void | clearExitMarks (FlowBlock *graph) |
Clear the mark on all the exits to this loop. More... | |
Static Public Member Functions | |
static void | mergeIdenticalHeads (vector< LoopBody * > &looporder) |
Merge loop bodies that share the same head. More... | |
static bool | compare_ends (LoopBody *a, LoopBody *b) |
Compare the head then tail. More... | |
static int4 | compare_head (LoopBody *a, FlowBlock *looptop) |
Compare just the head. More... | |
static LoopBody * | find (FlowBlock *looptop, const vector< LoopBody * > &looporder) |
Find a LoopBody. More... | |
static void | clearMarks (vector< FlowBlock * > &body) |
Clear the body marks. More... | |
A description of the body of a loop.
Following Tarjan, assuming there are no irreducible edges, a loop body is defined by the head (or entry-point) and 1 or more tails, which each have a back edge into the head.
void LoopBody::clearExitMarks | ( | FlowBlock * | graph | ) |
Clear the mark on all the exits to this loop.
This clears the f_loop_exit_edge on any edge exiting this loop.
graph | is the containing control-flow structure |
|
static |
Clear the body marks.
body | is the list of FlowBlock nodes that have been marked |
Compare just the head.
Compare two loops based on the indices of the head
a | is the first LoopBody to compare |
looptop | is the second |
void LoopBody::emitLikelyEdges | ( | list< FloatingEdge > & | likely, |
FlowBlock * | graph | ||
) |
Collect likely unstructured edges.
Add edges that exit from this loop body to the list of likely gotos, giving them the proper priority.
likely | will hold the exit edges in (reverse) priority order |
graph | is the containing control-flow graph |
void LoopBody::extend | ( | vector< FlowBlock * > & | body | ) | const |
Extend body (to blocks that never exit)
Extend the body of this loop to every FlowBlock that can be reached only from head without hitting the exitblock. Assume body has been filled out by findBase() and that all these blocks have their mark set.
body | contains the current loop body and will be extended |
Find a LoopBody.
Given the top FlowBlock of a loop, find corresponding LoopBody record from an ordered list. This assumes mergeIdenticalHeads() has been run so that the head is uniquely identifying.
looptop | is the top of the loop |
looporder | is the ordered list of LoopBody records |
void LoopBody::findBase | ( | vector< FlowBlock * > & | body | ) |
Mark the body FlowBlocks of this loop.
Collect all FlowBlock nodes that reach a tail of the loop without going through head. Put them in a list and mark them.
body | will contain the body nodes |
void LoopBody::findExit | ( | const vector< FlowBlock * > & | body | ) |
Choose the exit block for this loop.
A structured loop is allowed at most one exit block: pick this block. First build a set of trial exits, preferring from a tail, then from head, then from the middle. If there is no containing loop, just return the first such exit we find.
body | is the list FlowBlock objects in the loop body, which we assume are marked. |
Return current loop bounds (head and bottom).
This updates the head and tail nodes to FlowBlock in the current collapsed graph. This returns the first tail and passes back the head.
top | is where head is passed back |
graph | is the containing control-flow structure |
void LoopBody::labelContainments | ( | const vector< FlowBlock * > & | body, |
const vector< LoopBody * > & | looporder | ||
) |
Record any loops that body contains.
Search for any loop contained by this and update is depth and immed_container field.
body | is the set of FlowBlock nodes making up this loop |
looporder | is the list of known loops |
void LoopBody::labelExitEdges | ( | const vector< FlowBlock * > & | body | ) |
Label edges that exit the loop.
Label any edge that leaves the set of nodes in body. Put the edges in priority for removal, middle exit at front, head exit, then tail exit. We assume all the FlowBlock nodes in body have been marked.
body | is list of nodes in this loop body |
|
static |
void LoopBody::orderTails | ( | void | ) |
Find preferred tail.
The idea is if there is more than one tail for a loop, some tails are more "preferred" than others and should have their exit edges preserved longer and be the target of the DAG path. Currently we look for a single tail that has an outgoing edge to the exitblock and make sure it is the first tail.
void LoopBody::setExitMarks | ( | FlowBlock * | graph | ) |
Mark all the exits to this loop.
Exit edges have their f_loop_exit_edge property set.
graph | is the containing control-flow structure |