regalloc

package
v1.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2024 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package regalloc performs register allocation. The algorithm can work on any ISA by implementing the interfaces in api.go.

References:

Index

Constants

View Source
const (
	VRegIDNonReservedBegin = vRegIDReservedForRealNum

	VRegInvalid = VReg(vRegIDInvalid)
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Allocator

type Allocator struct {
	// contains filtered or unexported fields
}

Allocator is a register allocator.

func NewAllocator

func NewAllocator(allocatableRegs *RegisterInfo) Allocator

NewAllocator returns a new Allocator.

func (*Allocator) DoAllocation

func (a *Allocator) DoAllocation(f Function)

DoAllocation performs register allocation on the given Function.

func (*Allocator) Reset

func (a *Allocator) Reset()

Reset resets the allocator's internal state so that it can be reused.

type Block

type Block interface {
	// ID returns the unique identifier of this block which is ordered in the reverse post-order traversal of the CFG.
	ID() int32
	// BlockParams returns the virtual registers used as the parameters of this block.
	BlockParams(*[]VReg) []VReg
	// InstrIteratorBegin returns the first instruction in this block. Instructions added after lowering must be skipped.
	// Note: multiple Instr(s) will not be held at the same time, so it's safe to use the same impl for the return Instr.
	InstrIteratorBegin() Instr
	// InstrIteratorNext returns the next instruction in this block. Instructions added after lowering must be skipped.
	// Note: multiple Instr(s) will not be held at the same time, so it's safe to use the same impl for the return Instr.
	InstrIteratorNext() Instr
	// InstrRevIteratorBegin is the same as InstrIteratorBegin, but in the reverse order.
	InstrRevIteratorBegin() Instr
	// InstrRevIteratorNext is the same as InstrIteratorNext, but in the reverse order.
	InstrRevIteratorNext() Instr
	// FirstInstr returns the fist instruction in this block where instructions will be inserted after it.
	FirstInstr() Instr
	// EndInstr returns the end instruction in this block.
	EndInstr() Instr
	// LastInstrForInsertion returns the last instruction in this block where instructions will be inserted before it.
	// Such insertions only happen when we need to insert spill/reload instructions to adjust the merge edges.
	// At the time of register allocation, all the critical edges are already split, so there is no need
	// to worry about the case where branching instruction has multiple successors.
	// Therefore, usually, it is the nop instruction, but if the block ends with an unconditional branching, then it returns
	// the unconditional branch, not the nop. In other words it is either nop or unconditional branch.
	LastInstrForInsertion() Instr
	// Preds returns the number of predecessors of this block in the CFG.
	Preds() int
	// Pred returns the i-th predecessor of this block in the CFG.
	Pred(i int) Block
	// Entry returns true if the block is for the entry block.
	Entry() bool
	// Succs returns the number of successors of this block in the CFG.
	Succs() int
	// Succ returns the i-th successor of this block in the CFG.
	Succ(i int) Block
	// LoopHeader returns true if this block is a loop header.
	LoopHeader() bool
	// LoopNestingForestChildren returns the number of children of this block in the loop nesting forest.
	LoopNestingForestChildren() int
	// LoopNestingForestChild returns the i-th child of this block in the loop nesting forest.
	LoopNestingForestChild(i int) Block
}

Block is a basic block in the CFG of a function, and it consists of multiple instructions, and predecessor Block(s).

type Function

type Function interface {
	// PostOrderBlockIteratorBegin returns the first block in the post-order traversal of the CFG.
	// In other words, the last blocks in the CFG will be returned first.
	PostOrderBlockIteratorBegin() Block
	// PostOrderBlockIteratorNext returns the next block in the post-order traversal of the CFG.
	PostOrderBlockIteratorNext() Block
	// ReversePostOrderBlockIteratorBegin returns the first block in the reverse post-order traversal of the CFG.
	// In other words, the first blocks in the CFG will be returned first.
	ReversePostOrderBlockIteratorBegin() Block
	// ReversePostOrderBlockIteratorNext returns the next block in the reverse post-order traversal of the CFG.
	ReversePostOrderBlockIteratorNext() Block
	// ClobberedRegisters tell the clobbered registers by this function.
	ClobberedRegisters([]VReg)
	// LoopNestingForestRoots returns the number of roots of the loop nesting forest in a function.
	LoopNestingForestRoots() int
	// LoopNestingForestRoot returns the i-th root of the loop nesting forest in a function.
	LoopNestingForestRoot(i int) Block
	// LowestCommonAncestor returns the lowest common ancestor of two blocks in the dominator tree.
	LowestCommonAncestor(blk1, blk2 Block) Block
	// Idom returns the immediate dominator of the given block.
	Idom(blk Block) Block

	// SwapAtEndOfBlock swaps the two virtual registers at the end of the given block.
	SwapBefore(x1, x2, tmp VReg, instr Instr)
	// StoreRegisterBefore inserts store instruction(s) before the given instruction for the given virtual register.
	StoreRegisterBefore(v VReg, instr Instr)
	// StoreRegisterAfter inserts store instruction(s) after the given instruction for the given virtual register.
	StoreRegisterAfter(v VReg, instr Instr)
	// ReloadRegisterBefore inserts reload instruction(s) before the given instruction for the given virtual register.
	ReloadRegisterBefore(v VReg, instr Instr)
	// ReloadRegisterAfter inserts reload instruction(s) after the given instruction for the given virtual register.
	ReloadRegisterAfter(v VReg, instr Instr)
	// InsertMoveBefore inserts move instruction(s) before the given instruction for the given virtual registers.
	InsertMoveBefore(dst, src VReg, instr Instr)
}

Function is the top-level interface to do register allocation, which corresponds to a CFG containing Blocks(s).

type Instr

type Instr interface {
	fmt.Stringer
	// Next returns the next instruction in the same block.
	Next() Instr
	// Prev returns the previous instruction in the same block.
	Prev() Instr
	// Defs returns the virtual registers defined by this instruction.
	Defs(*[]VReg) []VReg
	// Uses returns the virtual registers used by this instruction.
	// Note: multiple returned []VReg will not be held at the same time, so it's safe to use the same slice for this.
	Uses(*[]VReg) []VReg
	// AssignUse assigns the RealReg-allocated virtual register used by this instruction at the given index.
	AssignUse(index int, v VReg)
	// AssignDef assigns a RealReg-allocated virtual register defined by this instruction.
	// This only accepts one register because we don't allocate registers for multi-def instructions (i.e. call instruction)
	AssignDef(VReg)
	// IsCopy returns true if this instruction is a move instruction between two registers.
	// If true, the instruction is of the form of dst = src, and if the src and dst do not interfere with each other,
	// we could coalesce them, and hence the copy can be eliminated from the final code.
	IsCopy() bool
	// IsCall returns true if this instruction is a call instruction. The result is used to insert
	// caller saved register spills and restores.
	IsCall() bool
	// IsIndirectCall returns true if this instruction is an indirect call instruction which calls a function pointer.
	//  The result is used to insert caller saved register spills and restores.
	IsIndirectCall() bool
	// IsReturn returns true if this instruction is a return instruction.
	IsReturn() bool
	// AddedBeforeRegAlloc returns true if this instruction is added before register allocation.
	AddedBeforeRegAlloc() bool
}

Instr is an instruction in a block, abstracting away the underlying ISA.

type InstrConstraint added in v1.7.0

type InstrConstraint interface {
	comparable
	Instr
}

InstrConstraint is an interface for arch-specific instruction constraints.

type RealReg

type RealReg byte

RealReg represents a physical register.

const RealRegInvalid RealReg = 0

func (RealReg) String

func (r RealReg) String() string

String implements fmt.Stringer.

type RegSet added in v1.7.0

type RegSet uint64

RegSet represents a set of registers.

func NewRegSet added in v1.7.0

func NewRegSet(regs ...RealReg) RegSet

NewRegSet returns a new RegSet with the given registers.

func (RegSet) Range added in v1.7.0

func (rs RegSet) Range(f func(allocatedRealReg RealReg))

type RegType

type RegType byte

RegType represents the type of a register.

const (
	RegTypeInvalid RegType = iota
	RegTypeInt
	RegTypeFloat
	NumRegType
)

func RegTypeOf

func RegTypeOf(p ssa.Type) RegType

RegTypeOf returns the RegType of the given ssa.Type.

func (RegType) String

func (r RegType) String() string

String implements fmt.Stringer.

type RegisterInfo

type RegisterInfo struct {
	// AllocatableRegisters is a 2D array of allocatable RealReg, indexed by regTypeNum and regNum.
	// The order matters: the first element is the most preferred one when allocating.
	AllocatableRegisters [NumRegType][]RealReg
	CalleeSavedRegisters RegSet
	CallerSavedRegisters RegSet
	RealRegToVReg        []VReg
	// RealRegName returns the name of the given RealReg for debugging.
	RealRegName func(r RealReg) string
	RealRegType func(r RealReg) RegType
}

RegisterInfo holds the statically-known ISA-specific register information.

type VReg

type VReg uint64

VReg represents a register which is assigned to an SSA value. This is used to represent a register in the backend. A VReg may or may not be a physical register, and the info of physical register can be obtained by RealReg.

func FromRealReg

func FromRealReg(r RealReg, typ RegType) VReg

FromRealReg returns a VReg from the given RealReg and RegType. This is used to represent a specific pre-colored register in the backend.

func (VReg) ID

func (v VReg) ID() VRegID

ID returns the VRegID of this VReg.

func (VReg) IsRealReg

func (v VReg) IsRealReg() bool

IsRealReg returns true if this VReg is backed by a physical register.

func (VReg) RealReg

func (v VReg) RealReg() RealReg

RealReg returns the RealReg of this VReg.

func (VReg) RegType

func (v VReg) RegType() RegType

RegType returns the RegType of this VReg.

func (VReg) SetRealReg

func (v VReg) SetRealReg(r RealReg) VReg

SetRealReg sets the RealReg of this VReg and returns the updated VReg.

func (VReg) SetRegType

func (v VReg) SetRegType(t RegType) VReg

SetRegType sets the RegType of this VReg and returns the updated VReg.

func (VReg) String

func (v VReg) String() string

String implements fmt.Stringer.

func (VReg) Valid

func (v VReg) Valid() bool

Valid returns true if this VReg is Valid.

type VRegID

type VRegID uint32

VRegID is the lower 32bit of VReg, which is the pure identifier of VReg without RealReg info.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL