Skip to main content

Builder

Struct Builder 

Source
pub struct Builder { /* private fields */ }
Expand description

The one way to build a CostTable.

Every field starts unset, and Builder::build refuses to produce a table while any of them still is. That is section 40.13’s completeness check, moved from a test into the constructor so that a target added next year cannot skip it.

Implementations§

Source§

impl Builder

Source

pub fn new() -> Self

A table with nothing set yet.

Source

pub fn add(self, value: Cycles) -> Self

A register to register add, which is the operation Cycles::ONE is defined as.

It is in the table anyway rather than assumed to be one, because a target where the unit operation is not an add should say so instead of having its whole table shifted.

Source

pub fn lea(self, value: Cycles) -> Self

An address computation that does not touch flags, x86-64’s lea.

Section 40.3 keeps this separate from add because whether it is cheaper is exactly the kind of microarchitectural fact that varies between cores of the same target.

Source

pub fn shift_const(self, value: Cycles) -> Self

A shift by an amount known at compile time.

Source

pub fn shift_var(self, value: Cycles) -> Self

A shift by an amount in a register, which on x86-64 is the expensive one because of the flags dependency and the fixed count register.

Source

pub fn mult(self, value: [Cycles; 4]) -> Self

A multiply, indexed by Width.

Source

pub fn mult_bit(self, value: Cycles) -> Self

What each set bit in a constant multiplier adds, for deciding when to expand a multiply by a constant into shifts and adds.

Source

pub fn divide(self, value: [Cycles; 4]) -> Self

A divide, indexed by Width. The most expensive integer operation on every target and the reason strength reduction of division is worth doing at all.

Source

pub fn movsx(self, value: Cycles) -> Self

A sign extension.

Source

pub fn movzx(self, value: Cycles) -> Self

A zero extension, which on x86-64 is free for the 32 to 64 case and is not for the others, so this is the cost of the ones that are not free.

Source

pub fn reg_move(self, value: Cycles) -> Self

A register to register move, as the expression evaluator sees it.

Source

pub fn move_int_load(self, value: [Cycles; 4]) -> Self

An integer load, indexed by Width, as the register allocator sees it.

Source

pub fn move_int_store(self, value: [Cycles; 4]) -> Self

An integer store, indexed by Width, as the register allocator sees it.

Source

pub fn move_int_reg(self, value: Cycles) -> Self

A move between two integer registers, as the register allocator sees it.

Separate from reg_move on purpose, per section 40.3. The allocator asks what a move it is about to insert costs, and the evaluator asks what a move already in the program costs, and gcc/config/i386/i386.h:114 says plainly that the two answers can differ.

Source

pub fn move_fp_load(self, value: [Cycles; 2]) -> Self

A floating point load, for the two widths that exist, single then double.

Source

pub fn move_fp_store(self, value: [Cycles; 2]) -> Self

A floating point store, single then double.

Source

pub fn move_fp_reg(self, value: Cycles) -> Self

A move between two floating point registers.

Source

pub fn move_fp_to_int(self, value: Cycles) -> Self

A move from a floating point register to an integer one, which goes through memory or a dedicated instruction and is never free.

Source

pub fn move_int_to_fp(self, value: Cycles) -> Self

A move from an integer register to a floating point one.

Source

pub fn addr(self, value: [Cycles; 5]) -> Self

An address of each shape, indexed by AddrMode, per section 40.9.

A mode the target does not have is Cycles::INFINITE, which is what the check that the speed and size tables agree about capability reads.

Source

pub fn branch_cost(self, value: Cycles) -> Self

What an unpredictable branch costs when optimizing for speed, per section 40.5.

Only the unpredictable case is a target number. BRANCH_COST at gcc/config/i386/i386.h:2023 makes a predictable branch free and a branch costed for size worth 2 on every target, and those two are in crate::heuristics rather than here because they are not facts about the machine.

Source

pub fn mispredict_penalty(self, value: Cycles) -> Self

What a mispredicted branch costs, per section 40.10.

The number that decides whether a switch becomes a jump table, because an indirect branch with many targets has to be priced as a mispredict and not as a branch.

Source

pub fn move_ratio(self, value: u32) -> Self

How many scalar moves a block copy may expand to before it becomes a call, per section 40.7.

GCC’s move_ratio. A count of moves rather than of bytes, because how many moves a copy takes depends on the alignment the compiler can prove.

Source

pub fn clear_ratio(self, value: u32) -> Self

The same for a block fill. GCC’s clear_ratio.

Source

pub fn cheapest_store(self, value: Bytes) -> Self

The narrowest store worth using, per section 40.7’s trimming rule.

A partially dead store is trimmed only to a width at least this wide. Narrowing an 8-byte store to a 1-byte store because seven bytes are dead is legal and is usually a store forwarding stall, which is the thing this number stops.

Source

pub fn reassoc_int(self, value: u32) -> Self

How many integer operations the machine issues in parallel, per section 40.8.

The reassociation width. A chain of eight adds becomes a tree only on a machine that can execute the tree’s independent operations at once, so this is a hardware fact rather than a tuning constant, and it defaults to 1 on a new target, meaning no reassociation.

Source

pub fn reassoc_fp(self, value: u32) -> Self

The same for floating point.

Reassociating floating point needs -ffast-math whatever this says, because the transformation is not value preserving. This is only how wide the tree may be once that question has been answered somewhere else.

Source

pub fn missing(&self) -> Vec<&'static str>

The fields nobody has set, in declaration order.

Public so that a test can name them, which turns “the table is incomplete” into “the table is missing branch_cost” without anybody reading a panic message.

Source

pub fn build(self) -> CostTable

The finished table.

§Panics

If any field was left unset, naming them. A target’s cost table is written once and is a compile time constant of the compiler in every sense that matters, so this fires during the tests of whoever added the target and never in front of a user.

Trait Implementations§

Source§

impl Clone for Builder

Source§

fn clone(&self) -> Builder

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Builder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Builder

Source§

fn default() -> Builder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.