Skip to content

Latest commit

 

History

History
648 lines (537 loc) · 24.2 KB

File metadata and controls

648 lines (537 loc) · 24.2 KB

##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

IR

###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_il and write_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 as 0x3f800000).

get_global_inst(op_name, type_id, operands)

Return a global instruction corresponding to the op_name, type_id, and operations. 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 inst into the module.

The instruction is appended to its section in the module (for example, adding an OpExtInstImport instruction will be added after the existing OpExtInstImport instructions, but before the OpMemoryModel instruction).

Note: Applications should in general use get_global_inst() instead of insert_global_inst().

insert_function_after(function, insert_pos_function)
Insert function function after the function insert_pos_function.
insert_function_before(function, insert_pos_function)
Insert function function before the function insert_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 _GlobalInstructions containing 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_block at the end of the function.
append_parameter(inst)
Insert the OpFunctionParameter instruction inst at 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_il and write_il.

insert_basic_block_after(basic_block, insert_pos_basic_block)
Insert basic block basic_block after the basic block insert_pos_basic_block.
insert_basic_block_before(basic_block, insert_pos_basic_block)
Insert basic block basic_block before the basic block insert_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_block at 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 OpFunctionParameter instructions for the function's parameters.
basic_blocks
A list of the basic blocks within this function.
inst
The OpFunction instruction defining this function.
end_inst
The OpFunctionEnd instruction ending this function.
module
The module this function is associated with.

###class ir.BasicBlock ####ir.BasicBlock – Methods

append_inst(inst)
Insert instruction inst at 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_il and write_il.

get_successors()
Return list of successor basic blocks.
insert_inst_after(inst, insert_pos_inst)
Insert instruction inst after the instruction insert_pos_inst.
insert_inst_before(inst, insert_pos_inst)
Insert instruction inst before the instruction insert_pos_inst.
predecessors()

Return the predecessor basic blocks.

Note: The predecessors are returned in arbitrary order.

prepend_inst(inst)
Insert instruction inst at 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 inst from the basic block.

####ir.BasicBlock – Attributes Note: The following attributes are read-only.

function
The function containing this basic block, or None if this basic block is not inserted into a function.
inst
The OpLabel instruction defining this basic block.
insts
The instructions in this basic block (not including the OpLabel instruction).
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 OpPhi instruction.
remove_from_phi(parent_id)
Remove a parent (and corresponding variable) from an OpPhi instruction.
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, the new_inst is 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 True if the instruction may have side effects, False otherwise.
is_commutative()
Return True if the instruction is commutative, False otherwise.
is_constant_value(value)

Return True if this instruction is a constant with the value value, False otherwise.

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 as 0x3f800000).

is_global_inst()
Return True if this is a global instruction, False otherwise.
copy_decorations(src_inst)
Copy the decorations from src_inst to 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. None if the instruction does not return a value.
type_id
The ID for the instructions type. None if the instruction does not have a type.
operands
A list containing the instruction's operands. ID operands are represented as class Id objects. 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 None if this instruction is not inserted into a basic block.
function
The function containing this instruction, or None if 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, or None if there is no such instruction.
is_temp
True if this is a temporary ID (i.e. an ID that has not got a real value yet), False otherwise.
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 the uses set too).
value

The 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_il and write_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, and operations. 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 inst at the end of its section among the global instructions.
prepend_inst(inst)
Insert instruction inst at the top of its section among the global instructions.
insert_inst_after(inst, insert_pos_inst)

Insert instruction inst after the instruction insert_pos_inst.

The instruction is inserted at the first valid position among the global instructions.

insert_inst_before(inst, insert_pos_inst)

Insert instruction inst before the instruction insert_pos_inst.

The instruction is inserted at the first valid position among the global instructions.

remove_inst(inst)
Remove instruction inst from 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 OpName and OpMemberName instructions.
op_capability_insts
A list containing the OpCapability instructions.
op_entry_point_insts
A list containing the OpEntryPoint instructions.
op_execution_mode_insts
A list containing the OpExecutionMode instructions.
op_extension_insts
A list containing the OpExtension instructions.
op_extinstimport_insts
A list containing the OpExtInstImport instructions.
op_line_insts
A list containing the OpLine instructions.
op_memory_model_insts
A list containing the OpMemoryModel instructions.
op_string_insts
A list containing the OpString instructions.
op_source_extension_insts
A list containing the OpSourceExtension instructions.
op_source_insts
A list containing the OpSource instructions.
type_insts
A list containing the type declaration, constant, spec-constant, and global OpVariable instructions.

Input/Output

TBD: read_il, write_il, read_spirv, write_spirv.

Optimizations

TBD: instcombine, simplify_cfg, dead_inst_elim, dead_func_elim, mem2reg.