README

Milky2018/machv/vcode does not have a README file

#
SafepointKind

#
ValueType

Exact target-neutral value types carried by semantic MachV SSA values.

Ptr64 is an untraced address or opaque handle. GcRef64 is a nullable managed reference and must be reported as a root at GC safepoints.

#
AllocationVerifyError

pub suberror AllocationVerifyError {
SelectedFailure(cause~ : VCodeVerifyError)
SourceMismatch
MissingValueLocation(value~ : Value)
ForeignLocation(value~ : Value)
LocationClassMismatch(value~ : Value)
MissingOperandLocation(instruction~ : Instruction, operand~ : Int)
OperandClassMismatch(instruction~ : Instruction, operand~ : Int)
RegisterConstraintViolation(instruction~ : Instruction, operand~ : Int)
FixedConstraintViolation(instruction~ : Instruction, operand~ : Int)
TiedConstraintViolation(instruction~ : Instruction, operand~ : Int)
Interference(left~ : Value, right~ : Value, location~ : Location)
ClobberViolation(instruction~ : Instruction, value~ : Value)
InvalidStackSlotLayout(slot~ : StackSlot)
InvalidEdit(index~ : Int)
MissingReload(instruction~ : Instruction, operand~ : Int)
InvalidEdgeMove(index~ : Int)
MissingSafepointRoot(instruction~ : Instruction, value~ : Value)
UnexpectedSafepointRoot(instruction~ : Instruction, value~ : Value)
} derive(Eq,
Debug
)

#
CallTransferError

pub suberror CallTransferError {
InvalidSourceClass(index~ : Int)
ForeignSourceStack(index~ : Int)
InvalidSourceStackType(index~ : Int, expected~ :
ValueType
, actual~ :
ValueType
)
InvalidSourceStackLayout(index~ : Int)
InvalidDestinationClass(index~ : Int)
InvalidStackOffset(index~ : Int, offset~ : Int)
InvalidOutgoingStackRange(start~ : Int, size~ : Int)
OutgoingStackDestinationOutOfRange(index~ : Int, offset~ : Int)
DuplicateRegisterDestination(index~ : Int, register~ : PhysicalReg)
OverlappingStackDestination(first~ : Int, second~ : Int)
ProtectedLocationOverwrite(index~ : Int, location~ : Location)
MoveResolutionFailed(cause~ : MoveResolveError)
} derive(Eq,
Debug
)

#
EmissionVerifyError

pub suberror EmissionVerifyError {
FrameFailure(cause~ : FrameVerifyError)
} derive(Eq,
Debug
)

#
FrameVerifyError

pub suberror FrameVerifyError {
AllocationFailure(cause~ : AllocationVerifyError)
SourceMismatch
InvalidFrameSize(size~ : Int)
InvalidFrameAlignment(alignment~ : Int)
MissingStackSlot(slot~ : StackSlot)
MisalignedStackSlot(slot~ : StackSlot)
OverlappingStackSlots(left~ : StackSlot, right~ : StackSlot)
StackSlotOutOfFrame(slot~ : StackSlot)
} derive(Eq,
Debug
)

#
MoveResolveError

pub suberror MoveResolveError {
MissingScratch(class~ : RegClass)
InvalidScratch(reg~ : PhysicalReg, expected~ : RegClass)
NoSafeCycleScratch(class~ : RegClass)
BrokenCycle
} derive(Eq,
Debug
)

#
VCodeBuildError

pub suberror VCodeBuildError {
InvalidParameter(index~ : Int)
InvalidBlockParameter(block~ : Block, index~ : Int)
ForeignBlock(block~ : Block)
ForeignValue(value~ : Value)
InvalidOperandConstraint
DuplicateTerminator(block~ : Block)
BlockAlreadyTerminated(block~ : Block)
InvalidLayout
} derive(Eq,
Debug
)

#
VCodeVerifyError

pub suberror VCodeVerifyError {
EmptyFunction
MissingTerminator(block~ : Block)
ForeignValue(instruction~ : Instruction, value~ : Value)
ForeignBlock(instruction~ : Instruction, block~ : Block)
InvalidEdgeArity(instruction~ : Instruction, block~ : Block)
EdgeClassMismatch(instruction~ : Instruction, block~ : Block, index~ : Int)
InvalidTie(instruction~ : Instruction, operand~ : Int, tied_to~ : Int)
FixedRegisterClassMismatch(instruction~ : Instruction, operand~ : Int)
InvalidOperandPreference(instruction~ : Instruction, operand~ : Int)
DuplicateClobber(instruction~ : Instruction, reg~ : PhysicalReg)
InvalidSafepointRoot(instruction~ : Instruction, value~ : Value)
InvalidStackMap(instruction~ : Instruction)
UnreachableBlock(block~ : Block)
UseBeforeDefinition(instruction~ : Instruction, value~ : Value)
DefinitionDoesNotDominate(instruction~ : Instruction, value~ : Value)
InvalidLayout
} derive(Eq,
Debug
)

#
Allocation

pub struct Allocation {
// private fields
}

#
Allocation::add_edit

fn Allocation::add_edit(self : Allocation, edit : Edit) -> Bool

#
Allocation::add_safepoint_root

fn Allocation::add_safepoint_root(self : Allocation, instruction : Instruction, value : Value, location : Location) -> Bool

#
Allocation::assign_operand

fn Allocation::assign_operand(self : Allocation, instruction : Instruction, operand_index : Int, reg : PhysicalReg) -> Bool

#
Allocation::assign_operand_location

fn Allocation::assign_operand_location(self : Allocation, instruction : Instruction, operand_index : Int, location : Location) -> Bool

#
Allocation::assign_value

fn Allocation::assign_value(self : Allocation, value : Value, location : Location) -> Bool

#
Allocation::create_stack_slot

fn Allocation::create_stack_slot(self : Allocation, ty :
ValueType
, size : Int, alignment : Int) -> StackSlot

#
Allocation::edits

fn Allocation::edits(self : Allocation) -> Array[Edit]

#
Allocation::edits_at

fn Allocation::edits_at(self : Allocation, instruction : Instruction, placement : PointPlacement) -> ArrayView[Edit]

Returns the allocation edits scheduled at one instruction point.

The returned view is read-only and remains valid while this allocation is not mutated. Target emitters should query this index instead of scanning edits() for every instruction.

#
Allocation::for_function

fn[Inst] Allocation::for_function(function : Function[Inst]) -> Allocation

#
Allocation::operand_location

fn Allocation::operand_location(self : Allocation, instruction : Instruction, operand_index : Int) -> Location?

#
Allocation::safepoint_roots

fn Allocation::safepoint_roots(self : Allocation, instruction : Instruction) -> Array[(Value, Location)]

#
Allocation::source_instruction_count

fn Allocation::source_instruction_count(self : Allocation) -> Int

#
Allocation::stack_slot_alignment

fn Allocation::stack_slot_alignment(self : Allocation, slot : StackSlot) -> Int?

#
Allocation::stack_slot_at

fn Allocation::stack_slot_at(self : Allocation, index : Int) -> StackSlot?

#
Allocation::stack_slot_count

fn Allocation::stack_slot_count(self : Allocation) -> Int

#
Allocation::stack_slot_size

fn Allocation::stack_slot_size(self : Allocation, slot : StackSlot) -> Int?

#
Allocation::stack_slot_type

fn Allocation::stack_slot_type(self : Allocation, slot : StackSlot) ->
ValueType
?

#
Allocation::statistics

fn Allocation::statistics(self : Allocation) -> AllocationStatistics

#
Allocation::summary

fn Allocation::summary(self : Allocation) -> String

#
Allocation::value_location

fn Allocation::value_location(self : Allocation, value : Value) -> Location?

Return the value's default transfer home.

A verified segmented allocation may keep the newest value in an instruction- or edge-specific location until an edit returns it here.

#
AllocationStatistics

pub struct AllocationStatistics {
spill_slots : Int
spills : Int
reloads : Int
reg_moves : Int
spill_to_spill : Int
} derive(Eq,
Debug
)

Read-only summary of the transfers introduced by register allocation.

#
Block

pub struct Block {
// private fields
}

impl Eq for Block
impl Show for Block

#
Builder

pub struct Builder[Inst] {
// private fields
}

#
Builder::append_body

fn[Inst] Builder::append_body(self : Builder[Inst], block : Block, inst : Inst, inputs : Array[Input], outputs : Array[Output], clobbers : Array[PhysicalReg], metadata : InstructionMetadata) -> (Instruction, Array[Value]) raise VCodeBuildError

#
Builder::block_parameter

fn[Inst] Builder::block_parameter(self : Builder[Inst], block : Block, index : Int) -> Value raise VCodeBuildError

#
Builder::create_block

fn[Inst] Builder::create_block(self : Builder[Inst], parameter_types : Array[
ValueType
]) -> Block

#
Builder::entry_block

fn[Inst] Builder::entry_block(self : Builder[Inst]) -> Block

#
Builder::finish

fn[Inst] Builder::finish(self : Builder[Inst]) -> Function[Inst]

#
Builder::new

fn[Inst] Builder::new(name : String, parameter_types : Array[
ValueType
]) -> Builder[Inst]

#
Builder::new_with_protocol

fn[Inst] Builder::new_with_protocol(name : String, protocol :
CallProtocol
, parameter_types : Array[
ValueType
], result_types : Array[
ValueType
]) -> Builder[Inst]

#
Builder::new_with_results

fn[Inst] Builder::new_with_results(name : String, parameter_types : Array[
ValueType
], result_types : Array[
ValueType
]) -> Builder[Inst]

#
Builder::parameter

fn[Inst] Builder::parameter(self : Builder[Inst], index : Int) -> Value raise VCodeBuildError

#
Builder::set_terminator

fn[Inst] Builder::set_terminator(self : Builder[Inst], block : Block, inst : Inst, inputs : Array[Input], successors : Array[Edge], clobbers : Array[PhysicalReg], metadata : InstructionMetadata) -> Instruction raise VCodeBuildError

#
CallTransfer

pub struct CallTransfer {
// private fields
}

One allocated source and its physical destination in a target call layout.

#
CallTransfer::to_register

fn CallTransfer::to_register(ty :
ValueType
, source : Location, destination : PhysicalReg) -> CallTransfer

#
CallTransfer::to_stack

fn CallTransfer::to_stack(ty :
ValueType
, source : Location, offset : Int) -> CallTransfer

#
CallTransferPlan

pub struct CallTransferPlan {
stack_transfers : Array[StackArgumentTransfer]
register_moves : Array[ParallelMove]
} derive(Eq,
Debug
)

#
Edge

pub struct Edge {
target : Block
arguments : Array[Value]
}

#
Edge::new

fn Edge::new(target : Block, arguments : Array[Value]) -> Edge

#
Edit

pub struct Edit {
point : ProgramPoint?
kind : EditKind
}

#
Edit::edge_move

fn Edit::edge_move(source : Block, successor_index : Int, value : Value, from : Location, to : Location) -> Edit

#
Edit::kind

fn Edit::kind(self : Edit) -> EditKind

#
Edit::point

fn Edit::point(self : Edit) -> ProgramPoint?

#
Edit::register_move

fn Edit::register_move(point : ProgramPoint, value : Value, from : PhysicalReg, to : PhysicalReg) -> Edit

#
Edit::reload

fn Edit::reload(point : ProgramPoint, value : Value, slot : StackSlot, reg : PhysicalReg) -> Edit

#
Edit::spill

fn Edit::spill(point : ProgramPoint, value : Value, reg : PhysicalReg, slot : StackSlot) -> Edit

#
EditKind

pub(all) enum EditKind {
Spill(value~ : Value, reg~ : PhysicalReg, slot~ : StackSlot)
Reload(value~ : Value, slot~ : StackSlot, reg~ : PhysicalReg)
Move(value~ : Value, from~ : PhysicalReg, to~ : PhysicalReg)
EdgeMove(source~ : Block, successor_index~ : Int, value~ : Value, from~ : Location, to~ : Location)
} derive(Eq,
Debug
)

#
FrameLayout

pub struct FrameLayout {
// private fields
}

#
FrameLayout::alignment

fn FrameLayout::alignment(self : FrameLayout) -> Int

#
FrameLayout::frame_size

fn FrameLayout::frame_size(self : FrameLayout) -> Int

#
FrameLayout::new

fn[Inst] FrameLayout::new(function : Function[Inst], allocation : Allocation, frame_size : Int, alignment : Int) -> FrameLayout

#
FrameLayout::place_slot

fn FrameLayout::place_slot(self : FrameLayout, slot : StackSlot, offset : Int) -> Bool

#
FrameLayout::slot_offset

fn FrameLayout::slot_offset(self : FrameLayout, slot : StackSlot) -> Int?

#
Function

pub struct Function[Inst] {
// private fields
}

#
Function::after

fn[Inst] Function::after(self : Function[Inst], instruction : Instruction) -> ProgramPoint?

#
Function::before

fn[Inst] Function::before(self : Function[Inst], instruction : Instruction) -> ProgramPoint?

#
Function::block_at

fn[Inst] Function::block_at(self : Function[Inst], index : Int) -> Block?

#
Function::block_body

fn[Inst] Function::block_body(self : Function[Inst], block : Block) -> Array[Instruction]

#
Function::block_count

fn[Inst] Function::block_count(self : Function[Inst]) -> Int

#
Function::block_index

fn[Inst] Function::block_index(self : Function[Inst], block : Block) -> Int?

#
Function::block_parameters

fn[Inst] Function::block_parameters(self : Function[Inst], block : Block) -> Array[Value]

#
Function::block_terminator

fn[Inst] Function::block_terminator(self : Function[Inst], block : Block) -> Instruction?

#
Function::entry_block

fn[Inst] Function::entry_block(self : Function[Inst]) -> Block

#
Function::instruction

fn[Inst] Function::instruction(self : Function[Inst], instruction : Instruction) -> Inst?

#
Function::instruction_at

fn[Inst] Function::instruction_at(self : Function[Inst], index : Int) -> Instruction?

#
Function::instruction_clobber_at

fn[Inst] Function::instruction_clobber_at(self : Function[Inst], instruction : Instruction, index : Int) -> PhysicalReg?

#
Function::instruction_clobber_count

fn[Inst] Function::instruction_clobber_count(self : Function[Inst], instruction : Instruction) -> Int

#
Function::instruction_clobbers

fn[Inst] Function::instruction_clobbers(self : Function[Inst], instruction : Instruction) -> Array[PhysicalReg]

#
Function::instruction_count

fn[Inst] Function::instruction_count(self : Function[Inst]) -> Int

#
Function::instruction_index

fn[Inst] Function::instruction_index(self : Function[Inst], instruction : Instruction) -> Int?

#
Function::instruction_is_terminator

fn[Inst] Function::instruction_is_terminator(self : Function[Inst], instruction : Instruction) -> Bool

#
Function::instruction_metadata

fn[Inst] Function::instruction_metadata(self : Function[Inst], instruction : Instruction) -> InstructionMetadata?

#
Function::instruction_operand_at

fn[Inst] Function::instruction_operand_at(self : Function[Inst], instruction : Instruction, index : Int) -> Operand?

#
Function::instruction_operand_count

fn[Inst] Function::instruction_operand_count(self : Function[Inst], instruction : Instruction) -> Int

#
Function::instruction_operands

fn[Inst] Function::instruction_operands(self : Function[Inst], instruction : Instruction) -> Array[Operand]

#
Function::instruction_results

fn[Inst] Function::instruction_results(self : Function[Inst], instruction : Instruction) -> Array[Value]

#
Function::instruction_successor_at

fn[Inst] Function::instruction_successor_at(self : Function[Inst], instruction : Instruction, index : Int) -> Edge?

#
Function::instruction_successor_count

fn[Inst] Function::instruction_successor_count(self : Function[Inst], instruction : Instruction) -> Int

#
Function::instruction_successors

fn[Inst] Function::instruction_successors(self : Function[Inst], instruction : Instruction) -> Array[Edge]

#
Function::layout

fn[Inst] Function::layout(self : Function[Inst]) -> Array[Block]

#
Function::name

fn[Inst] Function::name(self : Function[Inst]) -> String

#
Function::parameter_at

fn[Inst] Function::parameter_at(self : Function[Inst], index : Int) -> Value?

#
Function::parameter_count

fn[Inst] Function::parameter_count(self : Function[Inst]) -> Int

#
Function::program_point_instruction

fn[Inst] Function::program_point_instruction(self : Function[Inst], point : ProgramPoint) -> Instruction?

#
Function::protocol

fn[Inst] Function::protocol(self : Function[Inst]) ->
CallProtocol

#
Function::result_types

fn[Inst] Function::result_types(self : Function[Inst]) -> Array[
ValueType
]

#
Function::set_layout

fn[Inst] Function::set_layout(self : Function[Inst], layout : Array[Block]) -> Unit raise VCodeBuildError

#
Function::summary

fn[Inst :
Debug
] Function::summary(self : Function[Inst]) -> String

#
Function::value_at

fn[Inst] Function::value_at(self : Function[Inst], index : Int) -> Value?

#
Function::value_count

fn[Inst] Function::value_count(self : Function[Inst]) -> Int

#
Function::value_index

fn[Inst] Function::value_index(self : Function[Inst], value : Value) -> Int?

#
Function::value_type

fn[Inst] Function::value_type(self : Function[Inst], value : Value) ->
ValueType
?

#
Input

pub struct Input {
value : Value
constraint : OperandConstraint
preference : PhysicalReg?
timing : OperandTiming
}

#
Input::any

fn Input::any(value : Value) -> Input

#
Input::any_location

fn Input::any_location(value : Value) -> Input

Keep an input in its allocated register or spill slot. This is intended for target operations, such as ABI argument setup, whose emitter can consume a stack-resident value directly instead of requiring every input in a register at the same program point.

#
Input::fixed

fn Input::fixed(value : Value, reg : PhysicalReg) -> Input

#
Input::with_preference

fn Input::with_preference(self : Input, preference : PhysicalReg) -> Input

Prefer a physical register without making it an allocation constraint.

#
Input::with_timing

fn Input::with_timing(self : Input, timing : OperandTiming) -> Input

#
Instruction

pub struct Instruction {
// private fields
}

impl Eq for Instruction
impl Show for Instruction

#
InstructionMetadata

#
InstructionMetadata::empty

#
InstructionMetadata::safepoint

fn InstructionMetadata::safepoint(live_gc_roots : Array[Value]) -> InstructionMetadata

#
Location

pub(all) enum Location {
Register(PhysicalReg)
Stack(StackSlot)
} derive(Eq)

#
Operand

pub struct Operand {
value : Value
role : OperandRole
constraint : OperandConstraint
preference : PhysicalReg?
timing : OperandTiming
tie_id : Int
} derive(Eq,
Debug
)

#
OperandConstraint

pub(all) enum OperandConstraint {
Any
AnyLocation
Fixed(PhysicalReg)
TiedTo(Int)
} derive(Eq,
Debug
)

#
OperandRole

pub(all) enum OperandRole {
Use
Def
} derive(Eq,
Debug
)

#
OperandTiming

pub(all) enum OperandTiming {
Early
Late
} derive(Eq,
Debug
)

#
Output

pub struct Output {
ty :
ValueType

constraint : OperandConstraint
preference : PhysicalReg?
timing : OperandTiming
}

#
Output::any_location

Materialize the result directly in its stable register or stack home. This is intended for target ABI pseudos whose emitter owns the transfer from an implicit incoming location.

#
Output::fixed

#
Output::tied

fn Output::tied(ty :
ValueType
, operand_index : Int) -> Output

#
Output::with_preference

fn Output::with_preference(self : Output, preference : PhysicalReg) -> Output

Prefer a physical register without making it an allocation constraint.

#
Output::with_timing

fn Output::with_timing(self : Output, timing : OperandTiming) -> Output

#
ParallelMove

#
PhysicalReg

pub struct PhysicalReg {
id : Int
class : RegClass
} derive(Eq)

#
PhysicalReg::new

fn PhysicalReg::new(id : Int, class : RegClass) -> PhysicalReg

#
PointPlacement

pub(all) enum PointPlacement {
Before
After
} derive(Eq,
Debug
)

#
ProgramPoint

pub struct ProgramPoint {
// private fields
}

impl Eq for ProgramPoint

#
ProgramPoint::instruction

fn ProgramPoint::instruction(self : ProgramPoint) -> Instruction

#
ProgramPoint::placement

fn ProgramPoint::placement(self : ProgramPoint) -> PointPlacement

#
RegClass

pub(all) enum RegClass {
Int
FpVector
} derive(Eq, Hash,
Debug
)

#
ResolvedCallTransferPlan

pub struct ResolvedCallTransferPlan {
stack_transfers : Array[StackArgumentTransfer]
register_moves : ResolvedMovePlan
} derive(Eq,
Debug
)

#
ResolvedMovePlan

pub struct ResolvedMovePlan {
steps : Array[ResolvedMoveStep]
requires_emergency : Bool
} derive(Eq,
Debug
)

#
ResolvedMoveStep

pub(all) enum ResolvedMoveStep {
Transfer(ParallelMove)
SpillScratchToEmergency(ty~ :
ValueType
, scratch~ : PhysicalReg)
ReloadScratchFromEmergency(ty~ :
ValueType
, scratch~ : PhysicalReg)
} derive(Eq,
Debug
)

#
StackArgumentTransfer

pub struct StackArgumentTransfer {
ty :
ValueType

source : Location
offset : Int
scratch : PhysicalReg?
} derive(Eq,
Debug
)

#
StackSlot

pub struct StackSlot {
// private fields
}

impl Eq for StackSlot

#
TargetCompileEvent

pub(all) enum TargetCompileEvent {
RegallocStarted
RegallocPhaseStarted(String)
RegallocPhasesFinished
RegallocFinished(AllocationStatistics)
FramePlanningStarted
FramePlanningFinished
EmissionStarted
EmissionFinished
} derive(Eq,
Debug
)

Target-compilation boundaries exposed to an embedding-owned observer.

The observer must not mutate compiler inputs from inside the callback.

#
Value

pub struct Value {
// private fields
}

impl Eq for Value
impl Show for Value

#
plan_call_transfers

fn plan_call_transfers(allocation : Allocation, transfers : Array[CallTransfer], outgoing_stack_start : Int, outgoing_stack_size : Int, scratch_int : Array[PhysicalReg], scratch_fp : Array[PhysicalReg], protected_locations : Array[Location]) -> CallTransferPlan raise CallTransferError

#
plan_parallel_moves

fn plan_parallel_moves(moves : Array[ParallelMove], scratch_int : PhysicalReg, scratch_fp : PhysicalReg) -> ResolvedMovePlan raise MoveResolveError

#
plan_resolved_call_transfers

fn plan_resolved_call_transfers(allocation : Allocation, transfers : Array[CallTransfer], outgoing_stack_start : Int, outgoing_stack_size : Int, stack_scratch_int : Array[PhysicalReg], stack_scratch_fp : Array[PhysicalReg], move_scratch_int : PhysicalReg, move_scratch_fp : PhysicalReg, protected_locations : Array[Location]) -> ResolvedCallTransferPlan raise CallTransferError

#
reg_class_for_value_type

fn reg_class_for_value_type(ty :
ValueType
) -> RegClass

#
resolve_parallel_moves

fn resolve_parallel_moves(moves : Array[ParallelMove], scratch_int : Array[PhysicalReg], scratch_fp : Array[PhysicalReg]) -> Array[ParallelMove] raise MoveResolveError

#
verify_allocated

fn[Inst] verify_allocated(function : Function[Inst], allocation : Allocation) -> Unit raise AllocationVerifyError

#
verify_allocation_invariants

fn[Inst] verify_allocation_invariants(function : Function[Inst], allocation : Allocation) -> Unit raise AllocationVerifyError

Verifies allocation-specific invariants for VCode that has already passed verify_selected. The caller must not mutate function between the two checks.

#
verify_emission_input

fn[Inst] verify_emission_input(function : Function[Inst], allocation : Allocation, frame : FrameLayout) -> Unit raise EmissionVerifyError

#
verify_framed

fn[Inst] verify_framed(function : Function[Inst], allocation : Allocation, frame : FrameLayout) -> Unit raise FrameVerifyError

#
verify_selected

fn[Inst] verify_selected(function : Function[Inst]) -> Unit raise VCodeVerifyError