ir

package
v0.0.0-...-ecbd380 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2023 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package ir2 contains an Intermediate Representation (IR) in Static Single Assignment (SSA) form.

  • Each Program contains a list of Packages.
  • Packages are a list of Globals, TypeDefs and Funcs.
  • Each Func is a list of Blocks.
  • Blocks have a list of Instrs.
  • Instrs Def (define) Values, and have Values as Args.
  • Values can be constants, types, temps, registers, memory locations, etc.

Note: Unlike other SSA representations, this representation separates the concept of instructions from the concept of values. This allows an instruction to define multiple values. This is handy to avoid needing tuples and unpacking tuples to handle instructions (like function calls) that return multiple values.

This IR is structured with ideas from Data Oriented Programming and Entity Component Systems type thinking to try to structure data to be close together in cache and avoid cache misses if possible.

As such there is an ID system that acts like a index into an array. These IDs are local to the Func in which they live. The different kinds of ID-able things are allocated in slabs of a fixed size in order to avoid invalidating pointers. Memory currently is not freed (but could be with a generation counter in the ID.)

The IR is designed to be serialized into a human readable text file and parsed back into IR to aid in creating tests.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BoolValue

func BoolValue(c Const) (bool, bool)

BoolValue returns a bool for a BoolConst

func Int64Value

func Int64Value(c Const) (int64, bool)

Int64Value returns an int64 for an IntConst

func IntValue

func IntValue(c Const) (int, bool)

IntValue returns an int for an IntConst

func StringValue

func StringValue(c Const) (string, bool)

StringValue return a string for a StringConst

Types

type Block

type Block struct {
	User
	// contains filtered or unexported fields
}

Block is a collection of Instrs which is a basic block in a control flow graph. The last Instr of a block must be a control flow Instr. Blocks can have Preds and Succs for the blocks that come before or after in the control flow graph respectively.

Blocks are also `User`s in that they are like instructions and can Def (define) values for use inside the block that act like block parameters, similar to a function call. They also have Args which are used as parameters to any successor blocks.

This system of blocks having parameters is instead of having Phi instructions. This is similar to Cranelift, and Cranelift has some good docs on how this works. But this is _not_ an extended basic block (EBB), there is only one exit from the block (excluding function calls).

func (*Block) AddPred

func (blk *Block) AddPred(pred *Block)

AddPred adds the Block to the predecessor list

func (*Block) AddSucc

func (blk *Block) AddSucc(succ *Block)

AddSucc adds the Block to the successor list

func (*Block) Control

func (blk *Block) Control() *Instr

Control returns the last instruction, which should be a control flow instruction

func (*Block) Emit

func (blk *Block) Emit(out io.Writer, dec Decorator)

func (*Block) Func

func (blk *Block) Func() *Func

Func returns the containing Func

func (*Block) InsertInstr

func (blk *Block) InsertInstr(i int, instr *Instr)

InsertInstr inserts the instruction at the ith position. -1 means append it.

func (*Block) Instr

func (blk *Block) Instr(i int) *Instr

Instr returns the ith Instr in the list

func (*Block) InstrIter

func (blk *Block) InstrIter() *BlockIter

InstrIter will return an Iter which iterates over every instruction in this block.

func (*Block) NumInstrs

func (blk *Block) NumInstrs() int

NumInstrs returns the number of instructions

func (*Block) NumPreds

func (blk *Block) NumPreds() int

NumPreds is the number of predecessors

func (*Block) NumSuccs

func (blk *Block) NumSuccs() int

NumSuccs returns the number of successors

func (*Block) Pred

func (blk *Block) Pred(i int) *Block

Pred returns the ith predecessor

func (*Block) RemoveInstr

func (blk *Block) RemoveInstr(inst *Instr)

RemoveInstr removes the Instr from the list

func (*Block) String

func (blk *Block) String() string

func (*Block) Succ

func (blk *Block) Succ(i int) *Block

Succ returns the ith successor

func (*Block) SwapInstr

func (blk *Block) SwapInstr(a *Instr, b *Instr)

SwapInstr swaps two instructions

func (*Block) SwapSuccs

func (blk *Block) SwapSuccs()

SwapSuccs swaps the successors, useful for inverting `If`

func (blk *Block) Unlink()

Unlink removes the Block from the pred/succ lists of surrounding Blocks

type BlockIter

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

BlockIter is an iterator that iterates over instructions in a Block

func (*BlockIter) Block

func (it *BlockIter) Block() *Block

Block returns the current block

func (*BlockIter) BlockIndex

func (it *BlockIter) BlockIndex() int

BlockIndex returns the index of the Block within the Func

func (*BlockIter) Changed

func (it *BlockIter) Changed()

Changed forces `HasChanged()` to return true

func (*BlockIter) HasChanged

func (it *BlockIter) HasChanged() bool

HasChanged returns true if `Changed()` was called, or one of the mutation methods

func (*BlockIter) HasNext

func (it *BlockIter) HasNext() bool

HasNext returns whether Next() will succeed

func (*BlockIter) HasPrev

func (it *BlockIter) HasPrev() bool

HasPrev returns whether Prev() will succeed

func (*BlockIter) Insert

func (it *BlockIter) Insert(op Op, typ typ.Type, args ...interface{}) *Instr

Insert inserts an instruction at the cursor position and increments the position

func (*BlockIter) InsertAfter

func (it *BlockIter) InsertAfter(op Op, typ typ.Type, args ...interface{}) *Instr

InsertAfter inserts after an instruction at the cursor position

func (*BlockIter) Instr

func (it *BlockIter) Instr() *Instr

Instr returns the current instruction

func (*BlockIter) InstrIndex

func (it *BlockIter) InstrIndex() int

InstrIndex returns the index of the current instruction in the Block

func (*BlockIter) Last

func (it *BlockIter) Last() bool

Last fast forwards to the end of the block

func (*BlockIter) Next

func (it *BlockIter) Next() bool

Next increments the position and returns whether that was successful

func (*BlockIter) Prev

func (it *BlockIter) Prev() bool

Prev decrements the position and returns whether that was successful

func (*BlockIter) Remove

func (it *BlockIter) Remove() *Instr

Remove will remove the instruction at the current position and decrement the position, returning the removed instruction.

func (*BlockIter) RemoveInstr

func (it *BlockIter) RemoveInstr(instr *Instr)

RemoveInstr removes an instruction from the middle of the block somewhere, making sure to adjust the iterator position appropriately

func (*BlockIter) ReplaceWith

func (it *BlockIter) ReplaceWith(v *Value) *Value

func (*BlockIter) Update

func (it *BlockIter) Update(op Op, typ typ.Type, args ...interface{}) *Instr

Update updates the instruction at the cursor position

type Const

type Const interface {
	Location() Location
	Kind() ConstKind
	String() string
	// contains filtered or unexported methods
}

Const is a constant value of some sort

func ConstFor

func ConstFor(v interface{}) Const

Return a Const for a value

func MakeStructConst

func MakeStructConst(elem []Const) Const

func StructValue

func StructValue(c Const) ([]Const, bool)

type ConstKind

type ConstKind uint8

ConstKind is a kind of constant

const (
	// no const, or not a const
	NotConst ConstKind = iota

	// nil, which is different than no const at all
	NilConst

	// non-numeric values
	BoolConst
	StringConst

	// numeric values
	IntConst

	// funcs and globals
	FuncConst
	GlobalConst

	// struct const
	StructConst
)

type CrossBlockIter

type CrossBlockIter struct {
	BlockIter
	// contains filtered or unexported fields
}

func (*CrossBlockIter) HasNext

func (it *CrossBlockIter) HasNext() bool

HasNext returns whether Next() will succeed

func (*CrossBlockIter) HasPrev

func (it *CrossBlockIter) HasPrev() bool

HasPrev returns whether Prev() will succeed

func (*CrossBlockIter) Last

func (it *CrossBlockIter) Last() bool

Last fast forwards to the end of the func

func (*CrossBlockIter) Next

func (it *CrossBlockIter) Next() bool

Next increments the position and returns whether that was successful

func (*CrossBlockIter) Prev

func (it *CrossBlockIter) Prev() bool

Prev decrements the position and returns whether that was successful

type Decorator

type Decorator interface {
	Begin(out io.Writer, what interface{})
	End(out io.Writer, what interface{})

	BeginLabel(out io.Writer, what interface{})
	EndLabel(out io.Writer, what interface{})

	WrapLabel(str string, what interface{}) string
	WrapRef(str string, what interface{}) string
	WrapType(str string) string
	WrapOp(str string, what Op) string
	SSAForm() bool
}

type Func

type Func struct {
	Name     string
	FullName string
	Sig      *typ.Function

	Referenced bool
	NumCalls   int

	Frame StackFrame
	// contains filtered or unexported fields
}

Func is a collection of Blocks, which comprise a function or method in a Program.

func FuncValue

func FuncValue(c Const) (*Func, bool)

FuncValue returns a *Func for a FuncConst

func (*Func) AllocSpillStorage

func (fn *Func) AllocSpillStorage(size int) int

AllocSpillStorage will allocate the number of addressable units as spill area and return the current offset for the spill area in addressible units.

func (*Func) Block

func (fn *Func) Block(i int) *Block

Block returns the ith Block

func (*Func) BlockForID

func (fn *Func) BlockForID(b ID) *Block

BlockForID returns a Block by ID

func (*Func) BlockIndex

func (fn *Func) BlockIndex(blk *Block) int

BlockIndex returns the index of the Block in the list

func (*Func) EliminateDeadCode

func (fn *Func) EliminateDeadCode()

EliminateDeadCode eliminates dead code until the code stops changing.

func (*Func) Emit

func (fn *Func) Emit(out io.Writer, dec Decorator)

func (*Func) HasPlaceholders

func (fn *Func) HasPlaceholders() bool

HasPlaceholders returns whether there are unresolved placeholders or not

func (*Func) InsertBlock

func (fn *Func) InsertBlock(i int, blk *Block)

InsertBlock inserts the block at the specific location in the list

func (*Func) InstrForID

func (fn *Func) InstrForID(i ID) *Instr

InstrForID returns the Instr for the ID

func (*Func) InstrIter

func (fn *Func) InstrIter() *CrossBlockIter

InstrIter returns an iterator that will iterate over every block and instruction in the func.

func (*Func) LongString

func (fn *Func) LongString() string

func (*Func) NewBlock

func (fn *Func) NewBlock() *Block

NewBlock adds a new block

func (*Func) NewInstr

func (fn *Func) NewInstr(op Op, typ typ.Type, args ...interface{}) *Instr

NewInstr creates an unbound Instr

func (*Func) NewValue

func (fn *Func) NewValue(typ typ.Type) *Value

NewValue creates a new Value of type typ

func (*Func) NumArgSlots

func (fn *Func) NumArgSlots() int

func (*Func) NumBlocks

func (fn *Func) NumBlocks() int

NumBlocks returns the number of Blocks

func (*Func) NumValues

func (fn *Func) NumValues() int

func (*Func) Package

func (fn *Func) Package() *Package

Package returns the Func's Package

func (*Func) PlaceholderFor

func (fn *Func) PlaceholderFor(label string) *Value

PlaceholderFor creates a special placeholder value that can be later resolved with a different value. This is useful for marking and resolving forward references.

func (*Func) PlaceholderLabels

func (fn *Func) PlaceholderLabels() []string

PlaceholderLabels returns a sorted list of placeholder labels

func (*Func) RemoveBlock

func (fn *Func) RemoveBlock(blk *Block)

RemoveBlock removes the Block from the list but does not remove it from succ/pred lists. See blk.Unlink()

func (*Func) ResolvePlaceholder

func (fn *Func) ResolvePlaceholder(label string, value *Value)

ResolvePlaceholder removes the placeholder from the list, replacing its uses with the specified value

func (*Func) SpillAreaSize

func (fn *Func) SpillAreaSize() int

SpillAreaSize indicates the size of the spill area of the stack

func (*Func) Types

func (fn *Func) Types() *typ.Types

func (*Func) ValueFor

func (fn *Func) ValueFor(t typ.Type, v interface{}) *Value

ValueFor looks up an existing Value

func (*Func) ValueForID

func (fn *Func) ValueForID(v ID) *Value

ValueForID returns the Value for the ID

type Global

type Global struct {
	Name       string
	FullName   string
	Type       typ.Type
	Referenced bool

	// initial value
	Value Const
	// contains filtered or unexported fields
}

Global is a global variable or literal stored in memory

func GlobalValue

func GlobalValue(c Const) (*Global, bool)

GlobalValue returns a *Func for a GlobalConst

func (*Global) Emit

func (glob *Global) Emit(out io.Writer, dec Decorator)

func (*Global) Package

func (glob *Global) Package() *Package

func (*Global) String

func (glob *Global) String() string

func (*Global) Types

func (glob *Global) Types() *typ.Types

type ID

type ID uint32

ID is an identifier that's unique within a Func

var Placeholder ID = idFor(PlaceholderID, -1)

Placeholder is an invalid ID meant to signal a place that needs to be filled

func (ID) BlockIn

func (id ID) BlockIn(fn *Func) *Block

BlockIn returns the Block in the Func or nil if this ID is not for a Block

func (ID) IDString

func (id ID) IDString() string

IDString returns the ID string

func (ID) Index

func (id ID) Index() int

Index returns the ID number for the ID

func (ID) InstrIn

func (id ID) InstrIn(fn *Func) *Instr

InstrIn returns the Instr in the Func or nil if this ID is not for a Instr

func (ID) IsBlock

func (id ID) IsBlock() bool

IsBlock returns if ID points to a Block

func (ID) IsInstr

func (id ID) IsInstr() bool

IsInstr returns if ID points to a Instr

func (ID) IsValue

func (id ID) IsValue() bool

IsValue returns true if ID points to a Value

func (ID) Kind

func (id ID) Kind() IDKind

Kind returns the IDKind

func (ID) ValueIn

func (id ID) ValueIn(fn *Func) *Value

ValueIn returns the Value in the Func or nil if this ID is not a value or not in the Func

type IDKind

type IDKind uint8
const (
	UnknownID IDKind = iota
	BlockID
	InstrID
	ValueID
	PlaceholderID
)

type Instr

type Instr struct {
	User
	Op

	Pos token.Pos
	// contains filtered or unexported fields
}

Instr is an instruction that may define one or more Values, and take as args (operands) one or more Values.

func (*Instr) Emit

func (in *Instr) Emit(out io.Writer, dec Decorator)

func (*Instr) Index

func (in *Instr) Index() int

Index returns the index in the Block's Instr list

func (*Instr) LineNo

func (in *Instr) LineNo() int

LineNo returns the line number in the original Go source code, or 0 if that's not known

func (*Instr) LongString

func (in *Instr) LongString() string

func (*Instr) MoveAfter

func (in *Instr) MoveAfter(other *Instr)

MoveAfter moves this instruction after other

func (*Instr) MoveBefore

func (in *Instr) MoveBefore(other *Instr)

MoveBefore moves this instruction before other

func (*Instr) Type

func (in *Instr) Type() typ.Type

func (*Instr) Update

func (in *Instr) Update(op Op, typ typ.Type, args ...interface{})

Update changes the op, type and number of defs and the args

type Iter

type Iter interface {
	// Instr returns the current instruction
	Instr() *Instr

	// InstrIndex returns the index of the current instruction in the Block
	InstrIndex() int

	// Block returns the current block
	Block() *Block

	// BlockIndex returns the index of the Block within the Func
	BlockIndex() int

	// HasNext returns whether Next() will succeed
	HasNext() bool

	// Next increments the position and returns whether that was successful
	Next() bool

	// HasPrev returns whether Prev() will succeed
	HasPrev() bool

	// Prev decrements the position and returns whether that was successful
	Prev() bool

	// Last fast forwards to the end
	Last() bool

	// Insert inserts an instruction at the cursor position and increments the position
	Insert(op Op, typ typ.Type, args ...interface{}) *Instr

	// InsertAfter inserts after an instruction at the cursor position
	InsertAfter(op Op, typ typ.Type, args ...interface{}) *Instr

	// Remove will remove the instruction at the current position and decrement the position,
	// returning the removed instruction.
	// NOTE: this only removes the instruction from the Block, it does not Unlink() it from
	// any uses.
	Remove() *Instr

	// RemoveInstr removes an instruction from anywhere and will adjust the iterator position
	// appropriately
	RemoveInstr(instr *Instr)

	// Update updates the instruction at the cursor position
	Update(op Op, typ typ.Type, args ...interface{}) *Instr

	// Replace the uses of the instruction at the cursor postion
	// with the specified value, making sure to instead insert a
	// copy if necessary
	ReplaceWith(v *Value) *Value

	// HasChanged returns true if `Changed()` was called, or one of the mutation methods
	HasChanged() bool

	// Changed forces `HasChanged()` to return true
	Changed()
}

Iter is a iterator over instructions

type Location

type Location uint8

Location is the location of a Value

const (
	InTemp Location = iota
	InConst
	InReg

	// Value is stored on the stack
	OnStack
)

type Op

type Op interface {
	String() string
	IsCall() bool
	IsCompare() bool
	IsCopy() bool
	IsCommutative() bool
	IsSink() bool
	ClobbersArg() bool
	IsBranch() bool
	IsReturn() bool
}

Op describes an operation (instruction) type Note: Implementations of Op should attempt to be uint8 type, since this is optimized by Go.

type Package

type Package struct {
	Name string
	Path string
	// contains filtered or unexported fields
}

Package is a collection of Funcs and Globals which comprise a part of a program.

func (*Package) Emit

func (pkg *Package) Emit(out io.Writer, dec Decorator)

func (*Package) Func

func (pkg *Package) Func(name string) *Func

Func finds a func by either Name or FullName

func (*Package) Funcs

func (pkg *Package) Funcs() []*Func

Funcs returns a copy of the func list

func (*Package) Global

func (pkg *Package) Global(name string) *Global

Global finds the Global by Name or FullName

func (*Package) Globals

func (pkg *Package) Globals() []*Global

Globals returns a copy of the global list

func (*Package) NewFunc

func (pkg *Package) NewFunc(name string, sig *typ.Function) *Func

NewFunc adds a func to the list

func (*Package) NewGlobal

func (pkg *Package) NewGlobal(name string, typ typ.Type) *Global

NewGlobal adds a global to the list

func (*Package) NewStringLiteral

func (pkg *Package) NewStringLiteral(funcname, str string) *Global

NewStringLiteral creates a global with a string literal value

func (*Package) NewTypeDef

func (pkg *Package) NewTypeDef(name string, typ typ.Type) *TypeDef

NewTypeDef adds a typedef to the list

func (*Package) Program

func (pkg *Package) Program() *Program

Program that the package belongs to

func (*Package) TypeDef

func (pkg *Package) TypeDef(name string) *TypeDef

TypeDef finds a func by either Name or FullName

func (*Package) TypeDefs

func (pkg *Package) TypeDefs() []*TypeDef

TypeDefs returns a copy of the func list

func (*Package) Types

func (pkg *Package) Types() *typ.Types

type Program

type Program struct {
	FileSet *token.FileSet
	// contains filtered or unexported fields
}

Program is a collection of packages, which comprise a whole program.

func NewProgram

func NewProgram() *Program

func (*Program) AddPackage

func (prog *Program) AddPackage(pkg *Package)

AddPackage adds a package to the list

func (*Program) Emit

func (prog *Program) Emit(out io.Writer, dec Decorator)

func (*Program) Func

func (prog *Program) Func(name string) *Func

Func searches each package for a func

func (*Program) Global

func (prog *Program) Global(name string) *Global

Global searches each package for a global

func (*Program) Package

func (prog *Program) Package(name string) *Package

Package finds a package first by full name, then if there is no match, by short name.

func (*Program) Packages

func (prog *Program) Packages() []*Package

Packages returns a copy of the package list

func (*Program) StringLiteral

func (prog *Program) StringLiteral(str string, fullname string) *Global

func (*Program) Types

func (prog *Program) Types() *typ.Types

type SSAString

type SSAString struct{}

SSAString emits a plain string in SSA form

func (SSAString) Begin

func (ss SSAString) Begin(out io.Writer, what interface{})

func (SSAString) BeginLabel

func (ss SSAString) BeginLabel(out io.Writer, what interface{})

func (SSAString) End

func (ss SSAString) End(out io.Writer, what interface{})

func (SSAString) EndLabel

func (ss SSAString) EndLabel(out io.Writer, what interface{})

func (SSAString) SSAForm

func (ss SSAString) SSAForm() bool

func (SSAString) WrapLabel

func (ss SSAString) WrapLabel(str string, what interface{}) string

func (SSAString) WrapOp

func (ss SSAString) WrapOp(str string, what Op) string

func (SSAString) WrapRef

func (ss SSAString) WrapRef(str string, what interface{}) string

func (SSAString) WrapType

func (ss SSAString) WrapType(str string) string

type SlotID

type SlotID uint32

SlotID represents a variable width "slot" where a value is stored on the stack frame.

func (SlotID) Index

func (sid SlotID) Index() int

func (SlotID) Kind

func (sid SlotID) Kind() SlotKind

func (SlotID) String

func (sid SlotID) String() string

type SlotKind

type SlotKind uint8
const (
	// InvalidSlot is an invalid unassigned slot
	InvalidSlot SlotKind = iota

	// Param slots are where a function's parameters live, which
	// are Args passed in from a calling function
	ParamSlot

	// SavedSlot is where callee saved registers live on the stack
	SavedSlot

	// AllocaSlot is where stack allocated data lives on the stack
	AllocaSlot

	// SpillSlot is where the register allocator stores spilled variables
	// These slots are reused when their previous values are no longer required
	SpillSlot

	// ArgSlot is where a caller stores a callee's parameters before a function
	// call. In other words they are "Args" before a function is called, and
	// become "Params" once the called function starts executing
	ArgSlot

	NumStackAreas
)

type StackFrame

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

StackFrame represents the stack frame layout of the current function. "Slot" IDs are handed out for offsets to values which are stored on the stack, and space is allocated according to the largest value that will be assigned to that stack slot.

A stack frame looks like this:

low mem addresses
+------------------------+
|                        |   <-- SP
+------------------------+ \
| callee stack arg 0     |  |
+------------------------+  |
| callee stack arg 1     |  |
+------------------------+  |
| spill 0                |  |
+------------------------+  |
| spill 1                |  |
+------------------------+  |
| alloca 0               |  |
+------------------------+   > stack frame
| alloca 1               |  |
+------------------------+  |
| saved reg 0            |  |
+------------------------+  |
| saved reg 1            |  |
+------------------------+  |
| saved RA               |  |
+------------------------+  |
| saved SP               |  | <-- previous SP
+------------------------+ /
| stack param 0          | \
+------------------------+  |
| stack param 1          |   > caller's stack frame
+------------------------+  |
high mem addresses

The SP is saved instead of a frame pointer to save a register. A frame pointer may be required to support dynamic stack allocations, but other than that, it is not needed. SP is saved to aide in unwinding the stack for debugging purposes.

The stack parameters of a called function reside in the caller's stack frame.

The order of items on the stack frame is an attempt to limit the size of offsets on load/store instructions that may appear frequently, such as variables spilled to the stack during register allocation.

func (*StackFrame) FrameSize

func (frame *StackFrame) FrameSize() int

FrameSize is the total stack frame size minus

func (*StackFrame) Func

func (frame *StackFrame) Func() *Func

func (*StackFrame) NewSlotID

func (frame *StackFrame) NewSlotID(kind SlotKind) SlotID

NewSlotID returns the next unused SlotID of the given kind

func (*StackFrame) ReplaceOffsets

func (frame *StackFrame) ReplaceOffsets()

ReplaceOffsets replaces all the stack offset variables with the actual calculated stack offsets. `Scan` must be called first.

func (*StackFrame) Scan

func (frame *StackFrame) Scan()

Scan the function for stack variables and calculate the SP offset for them.

func (*StackFrame) SlotID

func (frame *StackFrame) SlotID(kind SlotKind, index int) SlotID

SlotID returns a specific slot, making sure that NewSlotID will return the next unused one after this if it's not already been given out.

type TypeDef

type TypeDef struct {
	Name       string
	Referenced bool

	Type typ.Type
	// contains filtered or unexported fields
}

TypeDef is a type definition

func (*TypeDef) Emit

func (td *TypeDef) Emit(out io.Writer, dec Decorator)

type User

type User struct {
	ID
	// contains filtered or unexported fields
}

User uses and defines Values. Blocks and Instrs are Users.

func (*User) AddDef

func (use *User) AddDef(val *Value) *Value

AddDef adds a Value definition

func (*User) Arg

func (use *User) Arg(i int) *Value

Arg returns the ith argument

func (*User) ArgIndex

func (use *User) ArgIndex(arg *Value) int

ArgIndex returns the index of the arg, or -1 if not found

func (*User) Args

func (use *User) Args() []*Value

Args returns a copy of the arguments

func (*User) Block

func (use *User) Block() *Block

Block returns either the User Block or parent Block

func (*User) Def

func (use *User) Def(i int) *Value

Def returns the ith Value defined

func (*User) Defs

func (use *User) Defs() []*Value

Defs returns a copy of the list of Values defined by this user

func (*User) Destroy

func (use *User) Destroy()

Destroy removes all args and defs, thus removing references to other instructions

func (*User) Func

func (use *User) Func() *Func

Func returns the containing function

func (*User) InsertArg

func (use *User) InsertArg(i int, arg *Value)

InsertArg inserts the Value in the argument list at position i, or appending if i is -1

func (*User) Instr

func (use *User) Instr() *Instr

Instr returns either the Instr or an empty Instr to cut down on having to check IsInstr() everywhere.

func (*User) NumArgs

func (use *User) NumArgs() int

NumArgs returns the number of arguments

func (*User) NumDefs

func (use *User) NumDefs() int

NumDefs returns the number of Values defined

func (*User) RemoveArg

func (use *User) RemoveArg(arg *Value)

RemoveArg removes the value from the arguments list

func (*User) RemoveDef

func (use *User) RemoveDef(def *Value)

RemoveDef removes the value from the defs list

func (*User) RemoveDefAt

func (use *User) RemoveDefAt(index int)

RemoveDefAt removes the value from the defs list at the index

func (*User) ReplaceArg

func (use *User) ReplaceArg(i int, arg *Value)

ReplaceArg replaces the ith argument with the value specified. Will call InsertArg instead if i == NumArgs().

func (*User) SetCallRegisters

func (use *User) SetCallRegisters(args bool, kind SlotKind)

type Value

type Value struct {
	ID

	// Type is the type of the Value
	Type typ.Type
	// contains filtered or unexported fields
}

Value is a single value that may be stored in a single place. This may be a constant or variable, stored in a temp, register or on the stack.

func (*Value) Const

func (val *Value) Const() Const

Const returns the constant value of the Value or NotConst if not constant.

func (*Value) Def

func (val *Value) Def() *User

Def returns the Instr defining the Value, or nil if it's not defined

func (*Value) ForceAlive

func (val *Value) ForceAlive()

ForceAlive ensures dead code elimination sees this value as alive

func (*Value) Func

func (val *Value) Func() *Func

Func returns the containing Func.

func (*Value) HasConstValue

func (val *Value) HasConstValue(v interface{}) bool

HasConstValue returns if the value is constant and equals the provided constant. If provided a register it also checks that the register matches

func (*Value) InReg

func (val *Value) InReg() bool

InReg indicates if the Value is in a register.

func (*Value) InTemp

func (val *Value) InTemp() bool

InTemp indicates the value is in a temp.

func (*Value) IsConst

func (val *Value) IsConst() bool

IsConst returns if the Value is constant.

func (*Value) IsDefinedByOp

func (val *Value) IsDefinedByOp(op Op) bool

func (*Value) MoveToStack

func (val *Value) MoveToStack(kind SlotKind)

MoveToStack moves the value onto the stack in the next slot available

func (*Value) NeedsReg

func (val *Value) NeedsReg() bool

NeedsReg indicates if this Value should be allocated a register

func (*Value) NumUses

func (val *Value) NumUses() int

NumUses returns the number of uses

func (*Value) OnStack

func (val *Value) OnStack() bool

OnStack returns whether the value is stored on the stack.

func (*Value) Op

func (val *Value) Op() Op

If def of value is an instr, return it's op else return nil

func (*Value) Reg

func (val *Value) Reg() reg.Reg

Reg returns which register the Value is in, otherwise reg.None if its not in a register.

func (*Value) ReplaceUsesWith

func (val *Value) ReplaceUsesWith(other *Value)

ReplaceUsesWith will go through each use of val and replace it with other. Does not modify any definitions.

func (*Value) SetConst

func (val *Value) SetConst(con Const)

SetConst makes the Value the specified constant.

func (*Value) SetReg

func (val *Value) SetReg(reg reg.Reg)

SetReg puts the value in the specified register.

func (*Value) SetSlotIndex

func (val *Value) SetSlotIndex(kind SlotKind, index int)

SetSlotIndex sets the stack slot to a specific index

func (*Value) SetStackSlot

func (val *Value) SetStackSlot(slot SlotID)

SetStackSlot puts the Value on the stack at the specified slot.

func (*Value) SetTemp

func (val *Value) SetTemp()

SetTemp turns the value into a temp.

func (*Value) StackSlotID

func (val *Value) StackSlotID() SlotID

StackSlotID returns which spill slot the Value is in, or -1 if not in a spill slot.

func (*Value) String

func (val *Value) String() string

func (*Value) Temp

func (val *Value) Temp() ID

Temp returns which temp if the value is in a temp.

func (*Value) Use

func (val *Value) Use(i int) *User

Use returns the ith Instr using this Value

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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