Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package core
import ( "git.urbach.dev/cli/q/src/errors" "git.urbach.dev/cli/q/src/linter" "git.urbach.dev/cli/q/src/optimizer" "git.urbach.dev/cli/q/src/ssa")
// optimize applies various algorithms after the compilation.func (f *Function) optimize() error { // Sometimes unreachable blocks are created at the end of // an infinite loop. These should be removed to avoid // unnecessary return statements in the later phases. optimizer.RemoveDeadBlocks(&f.IR)
// After the removal of dead blocks, if the last block is // not part of a loop and did not end with a return // statement, an implicit return is inserted. if f.needsImplicitReturn() { if len(f.Output) > 0 { return errors.New(&ReturnCountMismatch{Count: 0, ExpectedCount: len(f.Output)}, f.File, f.Output[0].Source) }
f.deleteResources(nil) f.Block().Append(&ssa.Return{}) }
// Lint binary operations that can often be reduced to // simpler expressions. if f.Env.Build.LintBinaryOps { err := linter.LintBinaryOps(f.IR, f.File)
if err != nil { return err } }
// Binary operations with constant operands are evaluated // at compile time. For example, 1 + 2 becomes 3, and the // result is propagated to subsequent operations. var folded map[ssa.Value]struct{}
if f.Env.Build.Fold { folded = optimizer.Fold(f.IR) }
// Replace copies with their actual values. if f.Env.Build.RemoveCopies { optimizer.RemoveCopies(&f.IR) }
// After cleaning up some of the instructions we can proceed // to calculate the list of users. f.ComputeUsers()
// Now that we have the list of users for each instruction, // we can filter out dead values. err := f.removeDeadCode(folded)
if err != nil { return err }
// Move values closer to their first use to reduce the number // of values that are alive at the same time. if f.Env.Build.Reorder { optimizer.Reorder(f.IR) optimizer.ReorderBlocks(&f.IR) }
// Resource types that are still defined at the end of a // scope must be freed. return f.verifyDeallocation()}