Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende Überarbeitung | |||
software:deep:dev:crosscompiler:cfg [2014-06-26 13:58] – graf | software:deep:dev:crosscompiler:cfg [Unbekanntes Datum] (aktuell) – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== Control Flow Graph ====== | ||
- | The Control Flow Graph is an intermediate form where the instructions and the control flow are shown as a directed graph. It enables certain optimizations. For each method of a class an own CFG is built. Nodes in such a CFG represent a sequence of instructions with no branches. Further, there must be no branch target within a node. Branches in a method are represented by directed edges which connect the nodes. Each node has n predecessors and m successors as well as an index to the address of the first and the last Bytecode instruktion of this node. | ||
- | |||
- | [{{ .: | ||
- | |||
- | In order to build the CFG of a method, unconditional and conditional jumps or branches have to be found. | ||
- | |||
- | ===== Implementation ===== | ||
- | At the beginning the whole code of a method is a single node. Now the first branch is searched. This could be instructions such as //if_xx//, //goto//, //goto_w//, // | ||
- | For searching this branch instructions all Bytecode instructions are stored in a lookup table together with attributes. These attributes indicate for example whether they are branch instructions. Special care has to be taken for instructions whithout a fixed length, among them are //wide//, // | ||
- | |||
- | As soon as a branch instruction is found, the node is split. The node which contains the branch target must be split as well. | ||
- | |||
- | ==== Splitting at Branch Instruction ==== | ||
- | * Split after branch. New node is successor of the actual node if conditional branch (// | ||
- | * If branch instruction is last instruction of a node -> no splitting. | ||
- | |||
- | ==== Splitting at Branch Target ==== | ||
- | * If branch target is first instruction of a node -> no splitting. | ||
- | * New node is successor of node with the original branch instruction. | ||
- | * If target instruction is //goto//: That means the target node of the branch consists of an unconditional branch. We can therefore omit this node and directly enter the node, which is the target of this unconditional branch, as a successor of the actual node. | ||
- | |||
- | ===== Handling of Exceptions ===== | ||
- | Methods with catch clauses must be handled with special care. Nodes, which represent catch clauses must be determined with the help of the exception table. Further, these nodes must be added as predecessors to their corresponding try-nodes. Such nodes are marked with the field // | ||
- | [{{ .: | ||
- | |||
- | ===== Loop Headers ===== | ||
- | As a next step, all nodes are traversed and the loop headers marked. This information is later needed for the SSA. \\ | ||
- | Starting from the root node the graph is recursively traversed. For each node with the flag //visited// already set the field // | ||
- | [{{ .: | ||
- | |||
- | |||
- | ===== Dead Code Elimination ===== | ||
- | If a node has a single //goto// instruction, | ||
- | |||
- | ===== Predecessors ===== | ||
- | For all nodes its predecessor can be added. For the case that several successors of a node point to the same target node, only one predecessor must be entered. | ||
- | |||
- | ===== Dominator ===== | ||
- | Finally the dominator of each node has to be determined. The resulting structure is called dominator tree and is a n-fold tree, since every node has exactly one reference to another node (its dominator). The dominator tree is used when generating the SSA. | ||
- | |||
- | [{{ .: | ||
- | Special care must be given to the case where the root node already has one or more predecessors. | ||
- | |||
- | |||
- | |||
- | |||
- | |||