The ultimate goal of this PR is to simplify the InstructionBlock::graph and thereby improve the ability of a hardware scheduler to schedule a Quil program by reducing the number of edges between classical instructions and block start/end.
Two types of edges in the InstructionBlock::graph are deemed extraneous in this work:
An edge from two consecutive classical instructions that read from / write to different memory regions. Rather than insist on classical instruction execute in the particular order they are written in a Quil program, only represent ordering of classical Quil instructions based upon the memory regions they read and write to (this is already done with MemoryAccessQueue).
Edges from BlockStart, if the node has other incoming edges, or to BlockEnd, if the node has other outgoing edges. Note that while this could apply equally to InstructionRole::RfControl, this change set deliberately only impacts edges to and from classical instructions.
There are three invariants of the InstructionBlock::graph that remain unchanged:
There is always a path connecting the BlockStart to any classical node in the graph.
There is always a path connecting any classical node in the graph to the BlockEnd.
These invariants pertain to the BlockStart and BlockEnd as well. In other words, there is always a connecting path from the BlockStart to the BlockEnd regardless as to whether there are any instructions in the block.
Copied from #324 with
main
merged in.Per @erichulburd
The ultimate goal of this PR is to simplify the
InstructionBlock::graph
and thereby improve the ability of a hardware scheduler to schedule a Quil program by reducing the number of edges between classical instructions and block start/end.Two types of edges in the
InstructionBlock::graph
are deemed extraneous in this work:MemoryAccessQueue
).InstructionRole::RfControl
, this change set deliberately only impacts edges to and from classical instructions.Old representation of
InstructionBlock::graph
._In the original algorithm, there is an edge from LOAD1 to BlockEnd because there are pending reads on
params1
andintegers
.New representation of
InstructionBlock::graph
.There are three invariants of the
InstructionBlock::graph
that remain unchanged: