Skip to main content

Module choice

Module choice 

Source
Expand description

Letting a select on a comparison read what the comparison left in the condition state.

Design: spec/10-backend.md section 10.6, and spec/optimizer/37-machine-level-optimization.md section 37.4.

A rule selects select c, t, f as a test of the byte c and a conditional move on the answer, because the byte is the only thing a rule can name. When the byte came from a comparison that is three instructions where the machine wanted one. The comparison sets the condition state, the byte is written from it, the test of the byte sets the condition state again, and only then does the move read it:

  cmpl %esi, %edi
  setg %al                  cmpl %esi, %edi
  testb %al, %al      ->    cmovgl %edx, %ecx
  cmovnel %edx, %ecx

This is the branch crate::layout folds, written as a select, and it is done the same way for the same reasons. fusable asks before allocation which comparisons have a byte that selects in the same block are the whole of what reads, because that is a question about a register that is written once. moves runs after the layout, where nothing is left that could put an instruction between the comparison and a move reading what it left, and rewrites the comparison and all of its selects together or none of them.

What it is worth is what phiopt makes. A loop keeping the largest of each of eight slots, which is if (v > best[k]) best[k] = v and becomes a select once the store is made on both paths, runs two instructions fewer on every element, and those are two of the four on the path from the load to the store.

§What stops it

Anything between the comparison and a select that writes the condition state, which the target says of every name it does not know. And anything that writes the register the byte was given, since a select reading that register afterwards is reading something else. Either one ends the walk, and a select the walk did not reach keeps the byte, so the comparison keeps it too and every select behind it stays as it was.

A comparison of floats is not in the table and is left alone. What it leaves in the condition state is two answers, one for whether the operands were ordered at all, and a move can read only one of them.

Functions§

fusable
The comparisons whose byte only selects in the same block read, each with how many do.
moves
Turns every comparison fusable found, and the selects reading its byte, into the comparison keeping nothing and the moves on its condition.