iropt

package
v1.46.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2025 License: Apache-2.0 Imports: 2 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var RegoVMIROptimizationPassSchedule []*IROptPass

Functions

func BlockTransformPassBlock

func BlockTransformPassBlock(block *ir.Block, f func(*ir.Block) (*ir.Block, bool)) (*ir.Block, bool)

Recursively applies the transform for lower blocks, and after assembling the (possibly transformed) instructions into a block, applies the transform at this level of the plan before returning the results.

func BlockTransformPassBlocks

func BlockTransformPassBlocks(blocks []*ir.Block, f func(*ir.Block) (*ir.Block, bool)) ([]*ir.Block, bool)

Recursively descends the block list, applying the block transformation to the deepest-nested blocks first.

func EmptyLoopReplacement

func EmptyLoopReplacement(block *ir.Block) (*ir.Block, bool)

Replaces empty ScanStmt loops with a short sequence of non-looping instructions with the same early-exit effects as the loop.

func EmptyLoopReplacementPass

func EmptyLoopReplacementPass(policy *ir.Policy) *ir.Policy

func GetSatUnsatForBlock

func GetSatUnsatForBlock(block *ir.Block, offset int, unsatisfied UnsatMap, satisfied SatMap) (UnsatMap, SatMap)

offset provides the index offset in the overall instruction numbering.

func GetSatUnsatForBlocks

func GetSatUnsatForBlocks(blocks []*ir.Block, offset int, unsatisfied UnsatMap, satisfied SatMap) (UnsatMap, SatMap)

Builds a graph of locals (registers) from a blocklist. offset provides the index offset in the overall instruction numbering.

func GetSatUnsatForStmts

func GetSatUnsatForStmts(stmts []ir.Stmt, offset int, unsatisfied UnsatMap, satisfied SatMap) (UnsatMap, SatMap)

offset provides the index offset in the overall instruction numbering.

func LoopInvariantCodeMotionPass

func LoopInvariantCodeMotionPass(policy *ir.Policy) *ir.Policy

The pass design allows us to wire this into the global pass structure.

func LoopPassBlock

func LoopPassBlock(block *ir.Block, f func(LoopTransformState) (LoopTransformState, bool)) (*ir.Block, bool)

func LoopPassBlocks

func LoopPassBlocks(blocks []*ir.Block, f func(LoopTransformState) (LoopTransformState, bool)) ([]*ir.Block, bool)

Recursively descends the block list, until it finds the innermost loop body, and then applies the loop transform repeatedly until no further modifications are made.

func RewriteBreakStmtsForLifting

func RewriteBreakStmtsForLifting(stmt ir.Stmt, depth uint32) (ir.Stmt, bool)

Returns (possibly rewritten) stmt, and whether it was modified or not.

func RunPasses

func RunPasses(policy *ir.Policy, schedule []*IROptPass) (*ir.Policy, error)

Types

type IROptPass

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

Borrowed from OPA's compiler stage struct:

func NewIROptLevel0Schedule

func NewIROptLevel0Schedule(cliEnableFlags, _ *OptimizationPassFlags) []*IROptPass

Generates a new optimization pass schedule for -O=0, taking into account -of and -ofno flags. Note(philip): Eventually, we'll add back the `cliEnableFlags` parameter, but for now, no passes need manual enabling at -O=0.

func NewIROptLevel1Schedule

func NewIROptLevel1Schedule(cliEnableFlags, cliDisableFlags *OptimizationPassFlags) []*IROptPass

func NewIROptLevel2Schedule

func NewIROptLevel2Schedule(cliEnableFlags, cliDisableFlags *OptimizationPassFlags) []*IROptPass

type LoopTransformState

type LoopTransformState struct {
	Before []ir.Stmt
	After  []ir.Stmt
	Loop   ir.Stmt // ScanStmt with a body appended.
}

Encodes the state of preamble, postamble, and loop body instructions for the loop.

func LoopInvariantCodeMotion

func LoopInvariantCodeMotion(state LoopTransformState) (LoopTransformState, bool)

Performs Loop Invariant Code Motion for this loop. Behavior Notes:

  • Assumes it's the innermost loop, and that LICM has already happened for any nested ScanStmt loops in its loop body.
  • Runs until it hits a fixpoint, which happens when there are no further instructions to move.

Edge-Case Notes:

  • BreakStmt :: Has an implicit control dependency on all upstream instructions in the block. -- Resolved by *always* being the last thing moved out of a loop. If it is not the only member of the loop, it cannot be moved. -- If lifted, it usually has to be rewritten, to ensure its jump target is the same. --- We don't have to recursively rewrite the levels, because the jumps are *relative*, and only direct movement of the statement requires a rewrite, because that's changing its relative placement in the block hierarchy, relative to sibling blocks.
  • AssignVarOnceStmt, ObjectInsertOnceStmt :: Implicit control dependency, similar to BreakStmt. -- We always lift these last out of a loop. No rewriting is performed. --- Note(philip): This may prove unsafe, in which case we'll just have to treat them as unmovable.
  • Nondeterministic Builtin function calls :: Generally cannot be moved out of the loop. Have ordering dependencies relative to each other. (Ex: http.send calls) -- Applies to: some CallStmt, almost all CallDynamicStmt -- HACK: Resolved by never lifting ND builtins out of the loop, and thus they'll end up being in-order at the end. -- TODO: We *can* do better down the road, but for now, it's easier to just treat them as unmovable. --- The down-the-road way of "doing better" will be to track which ND builtin calls are really unmovable, and treating them as movement barriers.

Mark-and-Lift Algorithm:

  • Because sometimes it's convenient to create a temp var in a loop, we have to check the reaching definition property of each instruction in the loop-- does any downstream instruction overwrite that instruction's write target register(s)?
  • We can continue to do a linear forward pass by marking each liftable instruction index, and then only at the end (before the next pass) lifting all the truly safe-to-lift instructions at once.

type OptimizationPassFlags

type OptimizationPassFlags struct {
	LoopInvariantCodeMotion bool `cli:"licm"`
}

NOTE(philip): We use struct tags to encode the CLI-visible names for each pass. Ref: https://stackoverflow.com/a/30889373

func (*OptimizationPassFlags) GetCLIFlagNames

func (opf *OptimizationPassFlags) GetCLIFlagNames() []string

Ref: https://stackoverflow.com/a/30889373

func (*OptimizationPassFlags) GetFieldNames

func (opf *OptimizationPassFlags) GetFieldNames() []string

Ref: https://stackoverflow.com/a/50208292

func (*OptimizationPassFlags) GetFieldPtrMapping

func (opf *OptimizationPassFlags) GetFieldPtrMapping() map[string]*bool

HACK(philip): More horrific reflection hackery, also for the CLI. Ref: https://stackoverflow.com/a/29185381

func (*OptimizationPassFlags) GetFlag

func (opf *OptimizationPassFlags) GetFlag(name string) bool

func (*OptimizationPassFlags) GetFlagToFieldsMapping

func (opf *OptimizationPassFlags) GetFlagToFieldsMapping() map[string]string

HACK(philip): Relies on pass names and CLI flags being the same length.

func (*OptimizationPassFlags) MergeDisables

func (*OptimizationPassFlags) MergeEnables

func (*OptimizationPassFlags) SetFlag

func (opf *OptimizationPassFlags) SetFlag(name string, value bool)

HACK(philip): Horrible reflection hack, thankfully only needed to make CLI enable/disable flags easier to work with. Ref: https://stackoverflow.com/a/18931036

type SatMap

type SatMap map[ir.Local]int // index of node providing a write to that register.

type UnsatMap

type UnsatMap map[ir.Local][]int // indexes of nodes needing that register.

Jump to

Keyboard shortcuts

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