##API Overview This API is meant to be used for basic analysis and manipulation of SPIR-V binaries, and it tries to keep its representation close to the real binary; the IR consists of the SPIR-V instructions, and iterators traverse the IR in the order they are stored in the binary. But there is one layer of abstraction on top of this to represent functions and basic blocks, in order to simplify implementation of analysis and transformation passes.
The IR is encapsulated in a Module object. This consists of a list of global
instructions and a list of functions. The Function class represents
one function, that is, all instructions from an OpFunction to the
OpFunctionEnd. The instructions are grouped in the BasicBlock class,
which consists of all instructions from an OpLabel to the branch or return
instruction. Finally the instructions are represented by the Instruction
class, where the SPIR-V IDs are represented by the Id class.
Most class attributes (such as lists of functions, basic blocks, instructions) are meant to be used by applications, but applications must not modify the information directly. Instead, the objects have methods for updating the data. The reason for this is so the IR implementation may update data structures keeping track of various information in order to make the API more efficient, or for validity checking.
The Instruction object consists of the result ID, opcode name, type ID, and
operands. The fields are mostly represented in the same form as in the
high level assembly language used by the spirv-as/spirv-dis; the IDs
are represented as objects of the Id class that contains the value of the ID
and a link to the instruction that defines the ID. An application should in general
never create ID values itself; the only exception is when implementing an assembler.
All other IDs should be created implicitly by creating the instructions without
providing an ID. The opcode is represented by
the operation name (such as 'OpFAdd'). The operands for the enumerated constants (such as
the Storage Class) are represented as strings of the values (such as
'Input'), and masks are represented as a list of enumerated constants.
Integer and string literals are represented as integers and strings.
The result_id and type_id values are None for operations not using
them, and operands is an empty list for instructions without operands.
Instructions are immutable, so it is not possible to modify an instruction
after it is created. The way of modifying instructions is to create a new
(nearly) identical instruction, and to substitute the original with the new.
For example, to switch the order of two operands of inst:
new_inst = ir.Instruction(module, inst.op_name, inst.type_id,
[inst.operands[1], inst.operands[0]])
inst.replace_with(new_inst)
This changes the ID of the instruction, and it may be argued that it is useful to modify one instruction (i.e. to keep the original ID) in order to make minimal change in the binary. This is not directly supported in the API, but it can be accomplished by inserting a temporary instruction
tmp_inst = ir.Instruction(module, 'OpUndef', inst.type_id, [])
tmp_inst.insert_after(inst)
inst.replace_uses_with(tmp_inst)
new_inst = ir.Instruction(module, inst.op_name, inst.type_id,
[inst.operands[1], inst.operands[0]],
result_id=inst.result_id)
tmp_inst.replace_with(new_inst)
inst.destroy()
It is possible to iterate
over all instructions in the module by module.instructions(). The
instructions are retrieved in the same order as in the binary. It is
allowed to modify the IR while iterating over the instructions, but
instruction added to the current basic block will not be seen by the
iterator. Instructions that are moved (i.e. removed and re-inserted)
in the current basic block may be returned as if it was in its old
position.
TBD - Decorations, debug instructions etc.
TBD - Global instructions
TBD - Functions and basic blocks
###class ir.Module ####ir.Module – Methods
append_function(function)- Insert function at the end of the module.
dump(stream=sys.stdout)Write a debug dump of the module to
stream.The format of the dump is similar to the high level assembly syntax used by
read_ilandwrite_il.get_constant()Return a constant instruction with the provided value and type. An existing instruction is returned if it exists, otherwise a newly created instruction is returned and inserted into the module.
For vector types, the value need to be a list of the same length as the vector size, or a scalar, in which case the value is replicated for all elements.
For matrix types, the value need to be a list of the same length as the column count (where each element is a list of the column with or a scalar), or a scalar, in which case the value is replicated for all elements.
Floating point values can be provided as either a floating point number (such as.
1.0), or as an integer representing the bits of the value (such as0x3f800000).get_global_inst(op_name, type_id, operands)Return a global instruction corresponding to the
op_name,type_id, andoperations. An existing instruction is returned if it exists, otherwise a newly created instruction is returned and inserted into the module.This method is the preferred way of creating global instructions. For example, creating a type instruction for a 32-bit signed integer is done as
get_global_inst('OpTypeInt', 32, 1)insert_global_inst(inst)Insert the global instruction
instinto the module.The instruction is appended to its section in the module (for example, adding an
OpExtInstImportinstruction will be added after the existingOpExtInstImportinstructions, but before theOpMemoryModelinstruction).Note: Applications should in general use
get_global_inst()instead ofinsert_global_inst().insert_function_after(function, insert_pos_function)- Insert function
functionafter the functioninsert_pos_function. insert_function_before(function, insert_pos_function)- Insert function
functionbefore the functioninsert_pos_function. instructions()Iterator for iterating over the module's instructions in the order they are located in the SPIR-V binary.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
It is not allowed to insert/remove basic blocks or functions while iterating over the instructions.
instructions_reversed()Iterator for iterating over the module's instructions in reverse order.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
It is not allowed to insert/remove basic blocks or functions while iterating over the instructions.
prepend_function(function)- Insert function at the top of the module.
renumber_temp_ids()- Convert temp IDs to real IDs.
####ir.Module – Attributes Note: The following attributes are read-only.
bound- The SPIR-V ID bound.
global_instructions- The pseudo-basic block of class
_GlobalInstructionscontaining the module's global instructions. functions- A list of the functions in this module.
###class ir.Function ####ir.Function – Methods
append_basic_block(basic_block)- Insert basic block
basic_blockat the end of the function. append_parameter(inst)- Insert the
OpFunctionParameterinstructioninstat the end of the function's parameter list. destroy()Destroy this function.
This removes the function from the module (if it is attached to a module), and destroys the function's basic blocks and instructions.
The function must not be used after it is destroyed.
dump(stream=sys.stdout)Write a debug dump of the function to
stream.The format of the dump is similar to the high level assembly syntax used by
read_ilandwrite_il.insert_basic_block_after(basic_block, insert_pos_basic_block)- Insert basic block
basic_blockafter the basic blockinsert_pos_basic_block. insert_basic_block_before(basic_block, insert_pos_basic_block)- Insert basic block
basic_blockbefore the basic blockinsert_pos_basic_block. instructions()Iterator for iterating over the function's instructions in the order they are located in the SPIR-V binary.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
It is not allowed to insert/remove basic blocks while iterating over the instructions.
instructions_reversed()Iterator for iterating over the function's instructions in reverse order.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
It is not allowed to insert/remove basic blocks while iterating over the instructions.
prepend_basic_block(basic_block)- Insert basic block
basic_blockat the top of the function. remove()- Remove this function from the module.
####ir.Function – Attributes Note: The following attributes are read-only.
parameters- A list of the
OpFunctionParameterinstructions for the function's parameters. basic_blocks- A list of the basic blocks within this function.
inst- The
OpFunctioninstruction defining this function. end_inst- The
OpFunctionEndinstruction ending this function. module- The module this function is associated with.
###class ir.BasicBlock ####ir.BasicBlock – Methods
append_inst(inst)- Insert instruction
instat the end of the basic block. destroy()Destroy this basic block.
This removes the basic block from the function (if it is attached to a function), and destroys all the basic block's instructions.
The basic block must not be used after it is destroyed.
dump(stream=sys.stdout)Write a debug dump of the basic block to
stream.The format of the dump is similar to the high level assembly syntax used by
read_ilandwrite_il.get_successors()- Return list of successor basic blocks.
insert_inst_after(inst, insert_pos_inst)- Insert instruction
instafter the instructioninsert_pos_inst. insert_inst_before(inst, insert_pos_inst)- Insert instruction
instbefore the instructioninsert_pos_inst. predecessors()Return the predecessor basic blocks.
Note: The predecessors are returned in arbitrary order.
prepend_inst(inst)- Insert instruction
instat the top of the basic block. insert_after(insert_pos_bb)- Insert this basic block after the basic block
insert_pos_bb. insert_before(insert_pos_bb)- Insert this basic block before the basic block
insert_pos_bb. remove()- Remove this basic block from function.
remove_inst(inst)- Remove instruction
instfrom the basic block.
####ir.BasicBlock – Attributes Note: The following attributes are read-only.
function- The function containing this basic block, or
Noneif this basic block is not inserted into a function. inst- The
OpLabelinstruction defining this basic block. insts- The instructions in this basic block (not including the
OpLabelinstruction). module- The module this basic block is associated with.
###class ir.Instruction ####ir.Instruction – Methods
insert_after(insert_pos_inst)- Insert this instruction after the instruction
insert_pos_inst. insert_before(insert_pos_inst)- Insert this instruction before the instruction
insert_pos_inst. remove()- Remove this instruction from its basic block.
destroy()Destroy this instruction.
This removes the instruction from the basic block (if it is in a basic block).
The instruction must not be used after it is destroyed.
add_to_phi(variable_inst, parent_inst)- Add a variable/parent to an
OpPhiinstruction. remove_from_phi(parent_id)- Remove a parent (and corresponding variable) from an
OpPhiinstruction. uses()Return all instructions using this instruction.
Debug and decoration instructions are not returned.
get_decorations()- Return all decorations for this instruction.
replace_uses_with(new_inst)Replace all uses of this instruction with
new_inst.Decoration and debug instructions are not updated, as they are considered being a part of the instruction they reference.
replace_with(new_inst)Replace this instruction with
new_inst.All uses of this instruction is replaced by
new_inst, thenew_instis inserted in the location of this instruction, and this instruction is destroyed.Decoration and debug instructions are not updated, as they are considered being a part of the instruction they reference.
has_side_effects()- Return
Trueif the instruction may have side effects,Falseotherwise. is_commutative()- Return
Trueif the instruction is commutative,Falseotherwise. is_constant_value(value)Return
Trueif this instruction is a constant with the valuevalue,Falseotherwise.For vector types, the value need to be a list of the same length as the vector size, or a scalar, in which case the value is replicated for all elements.
For matrix types, the value need to be a list of the same length as the column count (where each element is a list of the column with or a scalar), or a scalar, in which case the value is replicated for all elements.
Floating point values can be provided as either a floating point number (such as.
1.0), or as an integer representing the bits of the value (such as0x3f800000).is_global_inst()- Return
Trueif this is a global instruction,Falseotherwise. copy_decorations(src_inst)- Copy the decorations from
src_instto this instruction.
####ir.Instruction – Attributes Note: The following attributes are read-only.
module- The module this instruction is associated with.
op_name- The operation name for this instruction.
result_id- The ID for the instructions return value.
Noneif the instruction does not return a value. type_id- The ID for the instructions type.
Noneif the instruction does not have a type. operands- A list containing the instruction's operands. ID operands are represented
as
class Idobjects. Operands for enumerated constants (such as the Storage Class) are represented as strings of the values (such as'Input'). Literal strings and integers are represented as strings and integers. basic_block- The basic block containing this instruction, or
Noneif this instruction is not inserted into a basic block. function- The function containing this instruction, or
Noneif this instruction is not inserted into a function. value- The value of a constant instruction.
The constant may be of scalar, vector, or matrix type, and the value is
returned as a scalar value or a list in the same way as the input format to
Module.get_constant. value_signed- The value of an integer constant instruction as signed integer.
The constant may be of scalar, vector, or matrix type, and the value is
returned as a scalar value or a list in the same way as the input format to
Module.get_constant. value_unsigned- The value of an integer constant instruction as unsigned integer.
The constant may be of scalar, vector, or matrix type, and the value is
returned as a scalar value or a list in the same way as the input format to
Module.get_constant.
###class ir.Id ####ir.Id – Methods
destroy()Destroy this ID.
The ID must not be used after it is destroyed.
####ir.Id – Attributes Note: The following attributes are read-only.
inst- The instruction which has this ID as
result_id, orNoneif there is no such instruction. is_tempTrueif this is a temporary ID (i.e. an ID that has not got a real value yet),Falseotherwise.uses- A set containing all instructions in the module that are using this ID
(excluding the instruction in
inst). Only instructions that have been inserted into the module are included in the set (i.e. removing an instruction from a basic block will get it removed from theusesset too). valueThe ID's value.
Temporary IDs have a value outside of the valid range.
###class ir._GlobalInstructions ####ir._GlobalInstructions – Methods
dump(stream=sys.stdout)Write a debug dump of the global instructions to
stream.The format of the dump is similar to the high level assembly syntax used by
read_ilandwrite_il.instructions()Iterator for iterating over the global instructions in the order they are located in the SPIR-V binary.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
instructions_reversed()Iterator for iterating over the global instructions in reverse order.
It is allowed to insert or remove instructions while iterating, although instructions inserted during iteration are not guaranteed to be seen during the iteration.
get_inst(op_name, type_id, operands)-
Return a global instruction corresponding to the
op_name,type_id, andoperations. An existing instruction is returned if it exists, otherwise a newly created instruction is returned and inserted into the module. append_inst(inst)- Insert instruction
instat the end of its section among the global instructions. prepend_inst(inst)- Insert instruction
instat the top of its section among the global instructions. insert_inst_after(inst, insert_pos_inst)Insert instruction
instafter the instructioninsert_pos_inst.The instruction is inserted at the first valid position among the global instructions.
insert_inst_before(inst, insert_pos_inst)Insert instruction
instbefore the instructioninsert_pos_inst.The instruction is inserted at the first valid position among the global instructions.
remove_inst(inst)- Remove instruction
instfrom the global instructions.
####ir._GlobalInstructions – Attributes Note: The following attributes are read-only.
decoration_insts- A list containing the decoration instructions.
name_insts- A list containing the
OpNameandOpMemberNameinstructions. op_capability_insts- A list containing the
OpCapabilityinstructions. op_entry_point_insts- A list containing the
OpEntryPointinstructions. op_execution_mode_insts- A list containing the
OpExecutionModeinstructions. op_extension_insts- A list containing the
OpExtensioninstructions. op_extinstimport_insts- A list containing the
OpExtInstImportinstructions. op_line_insts- A list containing the
OpLineinstructions. op_memory_model_insts- A list containing the
OpMemoryModelinstructions. op_string_insts- A list containing the
OpStringinstructions. op_source_extension_insts- A list containing the
OpSourceExtensioninstructions. op_source_insts- A list containing the
OpSourceinstructions. type_insts- A list containing the type declaration, constant, spec-constant, and
global
OpVariableinstructions.
TBD: read_il, write_il, read_spirv, write_spirv.
TBD: instcombine, simplify_cfg, dead_inst_elim, dead_func_elim,
mem2reg.