Skip to content

Select the next block based on the last jump - #506

Draft
zherczeg wants to merge 2 commits into
Samsung:mainfrom
zherczeg:codegen_next
Draft

zherczeg wants to merge 2 commits into
Samsung:mainfrom
zherczeg:codegen_next

Conversation

@zherczeg

Copy link
Copy Markdown
Collaborator

No description provided.

Add jumps after conditional branches if not present
Add several asserts to check the instruction stream integrity

Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
@zherczeg

Copy link
Copy Markdown
Collaborator Author

@makachanm this patch adds preference to the basic block system. Currently it is based on the last jump of the block. You could extend this method to support taken conditional branches. When the conditional target is preferred, the targets of the branch and its following jump should be swapped, and the conditional should be inverted. Reason: the conditional part is often merged with its preceding compare instruction, so the jumpIfTrue/jumpIfFalse is not compiled directly. To avoid checking the targets every time, it is easier to just swap the targets of the two instructions.

This patch is based on #505. Check the last commit only.

Comment thread src/jit/Backend.cpp
Label* target = lastInstr->asExtended()->value().targetLabel->finalTarget();
if (!(target->info() & Label::kIsCompiled)) {
target->addInfo(Label::kIsCompiled);
return target;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is a greedy algorithm. It could be made more sophistical later. Basic block duplication for simple blocks should also be possible (can be faster even if it increases code size).

@makachanm

Copy link
Copy Markdown
Contributor

I see. So far as I understand, We can now see the basic block into actual one piece by piece and move a actual position?

@zherczeg

zherczeg commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator Author

The trick is you don't move the blocks.
During code generation, each block has a Label::kIsCompiled flag. This flag is set if a block is compiled. At the end of the code generation, this flag must be set to all blocks.

The getNextBlock selects the next block. The returned block must not have the Label::kIsCompiled flag set. Later, we can experiment with block duplication strategies (compilers do this for simple blocks).

How this function selects the next block:

  1. If the current block ends with a conditional jump / jump instruction pair, or jump instruction, it can use their targets to select the next block. You can use branch hinting for the selection.
  2. If the first step is failed, the block is selected from the default block chain. The default block chain follows the order defined by the byte code. The next block is selected from the chain, where the Label::kIsCompiled flag is not set.

Note: the first step always fails, if the block ends with a return, unreachable, table jump, etc. In these cases the next block can be anything.

If the returned "next block" is NULL, it means all blocks are compiled.

@makachanm

Copy link
Copy Markdown
Contributor

So now all I do about branch hinting is can be moved into getNextBlock()?

@zherczeg

Copy link
Copy Markdown
Collaborator Author

Yes. You need to create the infrastructure for having branch hinting, and do the decisions in getNextBlock(). You should also invert conditional branch / jump pairs if appropriate (e.g. the taken is more likely, and the target code block has no Label::kIsCompiled flag).

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.

2 participants