Tree building¶
From IR-code a tree is generated which can be used to select instructions.
IR to DAG
The process of instruction selection is preceeded by the creation of a selection DAG (directed acyclic graph). The dagger take ir-code as input and produces such a dag for instruction selection.
A DAG represents the logic (computation) of a single basic block.
To do selection with tree matching, the DAG is then splitted into a series of tree patterns. This is often referred to as a forest of trees.
-
class
ppci.codegen.irdag.
FunctionInfo
(frame)¶ Keeps track of global function data when generating code for part of a functions.
-
class
ppci.codegen.irdag.
Operation
(op, ty)¶ A single operation with a type
-
class
ppci.codegen.irdag.
SelectionGraphBuilder
(arch)¶ Create a selectiongraph from a function for instruction selection
-
block_to_sgraph
(ir_block: ppci.ir.Block, function_info)¶ Create dag (directed acyclic graph) from a basic block.
The resulting dag can be used for instruction selection.
-
build
(ir_function: ppci.ir.SubRoutine, function_info, debug_db)¶ Create a selection graph for the given function.
Selection graph is divided into groups for each basic block.
-
copy_phis_of_successors
(ir_block)¶ When a terminator instruction is encountered, handle the copy of phi values into the expected virtual register
-
do_address_of
(node)¶ Process ir.AddressOf instruction
-
do_alloc
(node)¶ Process the alloc instruction
-
do_binop
(node)¶ Visit a binary operator and create a DAG node
-
do_c_jump
(node)¶ Process conditional jump into dag
-
do_cast
(node)¶ Create a cast of type
-
do_const
(node)¶ Process constant instruction
-
do_copy_blob
(node)¶ Create a memcpy node.
-
do_function_call
(node)¶ Transform a function call
-
do_inline_asm
(node)¶ Create selection graph node for inline asm code.
This is a little weird, as we really do not need to select any instructions, but this special node will be filtered later on.
-
do_literal_data
(node)¶ Literal data is stored after a label
-
do_load
(node)¶ Create dag node for load operation
-
do_phi
(node)¶ Refer to the correct copy of the phi node
-
do_procedure_call
(node)¶ Transform a procedure call
-
do_return
(node)¶ Move result into result register and jump to epilog
-
do_store
(node)¶ Create a DAG node for the store operation
-
do_undefined
(node)¶ Create node for undefined value.
-
do_unop
(node)¶ Visit an unary operator and create a DAG node
-
get_address
(ir_address)¶ Determine address for load or store.
-
new_node
(name, ty, *args, value=None)¶ Create a new selection graph node, and add it to the graph
-
new_vreg
(ty)¶ Generate a new temporary fitting for the given type
-
-
ppci.codegen.irdag.
depth_first_order
(function)¶ Return blocks in depth first search order
-
ppci.codegen.irdag.
make_map
(cls)¶ Add an attribute to the class that is a map of ir types to handler functions. For example if a function is called do_phi it will be registered into f_map under key ir.Phi.
-
ppci.codegen.irdag.
prepare_function_info
(arch, function_info, ir_function)¶ Fill function info with labels for all basic blocks
DAG splitting into trees.
The selection dag is splitted into trees by this module.
-
class
ppci.codegen.dagsplit.
DagSplitter
(arch)¶ Class that splits a DAG into a forest of trees.
This series is sorted such that data dependencies are met. The trees can henceforth be used to match trees.
-
assign_vregs
(sgraph, function_info)¶ Give vreg values to values that cross block boundaries
-
check_vreg
(node, frame)¶ Determine whether node outputs need a virtual register
-
get_reg_class
(data_flow)¶ Determine the register class suited for this data flow line
-
make_op
(op, typ)¶ Construct a string opcode from an operation and a type
-
make_trees
(nodes, tail_node)¶ Create a tree from a list of sorted nodes.
-
split_into_trees
(sgraph, ir_function, function_info, debug_db)¶ Split a forest of trees into a sorted series of trees for each block.
-
-
ppci.codegen.dagsplit.
topological_sort_modified
(nodes, start)¶ Modified topological sort, start at the end and work back