Skip to content

Conversation

@pacheco
Copy link
Collaborator

@pacheco pacheco commented Dec 18, 2025

Superblock detection and selection from PGO

Comment on lines 144 to 169
pub type AdapterBasicBlock<A> = BasicBlock<<A as Adapter>::Instruction>;
pub type AdapterBasicBlock<A> = Block<<A as Adapter>::Instruction>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call it AdapterBlock here? Was a bit confused a few times as I was expecting this to be basic block but it's actually not.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made BasicBlock a separate type again

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in Instruction mode, it doesn't seem that we have the "select candidates" process that accounts for overlapping super blocks as in Cell. I wonder if this was intentional.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, was mostly paying attention to cell pgo, but indeed I think we should take that into account (I'll add a TODO for now)

Comment on lines 140 to 150
// by the solver.
let pc = (i == 0).then_some(block.start_pc);
let pc = if i == 0 {
Some(block.start_pc)
} else {
block
.other_pcs
.iter()
.find(|(idx, _)| *idx == i)
.map(|(_, pc_value)| *pc_value)
};
let pc_lookup_row = instr
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So these seem to create pc lookup constraints for the start pc of each basic block within the super block?

I wonder how is this different from the optimistic constraints for pc created else where.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think these are two different things:

  • at execution we need to check that an APC can be used at that given point (optimistic constraint)
  • these here are real constraints, the prover needs to enforce the jumps when a given superblock is selected

@qwang98
Copy link
Collaborator

qwang98 commented Jan 8, 2026

As an entirely separate question and maybe not this PR, but how do we select which APC to execute, for example, when we have both abc and ab?

Is it to execute the "largest" possible? I couldn't seem to locate an execution logic some where.

@pacheco
Copy link
Collaborator Author

pacheco commented Jan 12, 2026

As an entirely separate question and maybe not this PR, but how do we select which APC to execute, for example, when we have both abc and ab?

Is it to execute the "largest" possible? I couldn't seem to locate an execution logic some where.

It should pick the "best" according to cell PGO, that is total_saved_cells / apc_width.
Even with optimistic APCs i think that remains the same: pick the best option that is valid according to the execution.
Maybe this formula needs to be adjusted, depending on how expensive columns are in the backend.

@qwang98 qwang98 force-pushed the superblocks-integrate branch from ce8a789 to 5d07fb9 Compare January 13, 2026 09:44
@qwang98
Copy link
Collaborator

qwang98 commented Jan 13, 2026

FYI I incorrectly pushed two commits to this branch, which I have restored via force push, so we should still be at the prior latest commit.

Comment on lines +40 to +44
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum Block<I> {
Basic(BasicBlock<I>),
Super(SuperBlock<I>),
}
Copy link
Collaborator

@Schaeff Schaeff Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this because there are two ways to express a single basic block b:
Block::Basic(b) and Block::Super(SuperBlock { blocks: vec![b] })
I suspect we should rather rename SuperBlock to Block and use it everywhere. Then a normal block is an edge case of a superblock, and there's only one way to represent it: Block { basic_blocks: vec![b] }

Is there another reason why we would need an enum here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked again: superblock collection used to be Vec<Block> -> Vec<Block>, now it's Vec<BasicBlock> -> Vec<BasicBlock or SuperBlock> but it seems like it should be Vec<BasicBlock> -> Vec<SuperBlock>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants