Working with functions and control flow graphs — gcc-python-plugin 0.16 documentation (original) (raw)
Many of the plugin events are called for each function within the source code being compiled. Each time, the plugin passes a gcc.Functioninstance as a parameter to your callback, so that you can work on it.
You can get at the control flow graph of a gcc.Function via itscfg
attribute. This is an instance of gcc.Cfg.
class gcc.
Function
¶
Wrapper around one of GCC’s struct function *
cfg
¶
An instance of gcc.Cfg for this function (or None during early passes)
decl
¶
The declaration of this function, as a gcc.FunctionDecl
local_decls
¶
List of gcc.VarDecl for the function’s local variables. It does not contain arguments; for those see the arguments property of the function’s decl.
Note that for locals with initializers, initial only seems to get set on those local_decls that are static variables. For other locals, it appears that you have to go into the gimple representation to locate assignments.
start
¶
The gcc.Location of the beginning of the function
end
¶
The gcc.Location of the end of the function
funcdef_no
¶
Integer: a sequence number for profiling, debugging, etc.
class gcc.
Cfg
¶
A gcc.Cfg
is a wrapper around GCC’s struct control_flow_graph.
basic_blocks
¶
List of gcc.BasicBlock, giving all of the basic blocks within this CFG
entry
¶
Instance of gcc.BasicBlock: the entrypoint for this CFG
exit
¶
Instance of gcc.BasicBlock: the final one within this CFG
get_block_for_label
(labeldecl)¶
Given a gcc.LabelDecl
, get the correspondinggcc.BasicBlock
You can use gccutils.cfg_to_dot
to render a gcc.Cfg as a graphviz diagram. It will render the diagram, showing each basic block, with source code on the left-hand side, interleaved with the “gimple” representation on the right-hand side. Each block is labelled with its index, and edges are labelled with appropriate flags.
For example, given this sample C code:
int main(int argc, char **argv) { int i;
printf("argc: %i\n", argc);
for (i = 0; i < argc; i++) { printf("argv[%i]: %s\n", argv[i]); }
helper_function();
return 0; }
then the following Python code:
dot = gccutils.cfg_to_dot(fun.cfg) gccutils.invoke_dot(dot)
will render a CFG bitmap like this:
class gcc.
BasicBlock
¶
A gcc.BasicBlock
is a wrapper around GCC’s basic_block type.
index
¶
The index of the block (an int), as seen in the cfg_to_dot rendering.
preds
¶
The list of predecessor gcc.Edge instances leading into this block
succs
¶
The list of successor gcc.Edge instances leading out of this block
phi_nodes
¶
The list of gcc.GimplePhi phoney functions at the top of this block, if appropriate for this pass, or None
gimple
¶
The list of gcc.Gimple instructions, if appropriate for this pass, or None
rtl
¶
The list of gcc.Rtl expressions, if appropriate for this pass, or None
class gcc.
Edge
¶
A wrapper around GCC’s edge type.
src
¶
The source gcc.BasicBlock of this edge
dest
¶
The destination gcc.BasicBlock of this edge
true_value
¶
Boolean: True if this edge is taken when a gcc.GimpleCondconditional is true, False otherwise
false_value
¶
Boolean: True if this edge is taken when a gcc.GimpleCondconditional is false, False otherwise
complex
¶
Boolean: True if this edge is “special” e.g. due to exception-handling, or some other kind of “strange” control flow transfer,False otherwise