github.com/cloudwego/frugal@v0.1.15/internal/atm/ssa/compile.go (about) 1 /* 2 * Copyright 2022 ByteDance Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package ssa 18 19 import ( 20 `reflect` 21 22 `github.com/cloudwego/frugal/internal/atm/abi` 23 `github.com/cloudwego/frugal/internal/atm/hir` 24 ) 25 26 type Pass interface { 27 Apply(*CFG) 28 } 29 30 type PassDescriptor struct { 31 Pass Pass 32 Name string 33 } 34 35 var Passes = [...]PassDescriptor { 36 { Name: "Early Constant Propagation" , Pass: new(ConstProp) }, 37 { Name: "Early Reduction" , Pass: new(Reduce) }, 38 { Name: "Branch Elimination" , Pass: new(BranchElim) }, 39 { Name: "Return Spreading" , Pass: new(ReturnSpread) }, 40 { Name: "Value Reordering" , Pass: new(Reorder) }, 41 { Name: "Late Constant Propagation" , Pass: new(ConstProp) }, 42 { Name: "Late Reduction" , Pass: new(Reduce) }, 43 { Name: "Machine Dependent Lowering" , Pass: new(Lowering) }, 44 { Name: "Zero Register Substitution" , Pass: new(ZeroReg) }, 45 { Name: "Write Barrier Insertion" , Pass: new(WriteBarrier) }, 46 { Name: "ABI-Specific Lowering" , Pass: new(ABILowering) }, 47 { Name: "Instruction Fusion" , Pass: new(Fusion) }, 48 { Name: "Instruction Compaction" , Pass: new(Compaction) }, 49 { Name: "Block Merging" , Pass: new(BlockMerge) }, 50 { Name: "Critical Edge Splitting" , Pass: new(SplitCritical) }, 51 { Name: "Phi Propagation" , Pass: new(PhiProp) }, 52 { Name: "Operand Allocation" , Pass: new(OperandAlloc) }, 53 { Name: "Constant Rematerialize" , Pass: new(Rematerialize) }, 54 { Name: "Pre-allocation TDCE" , Pass: new(TDCE) }, 55 { Name: "Register Allocation" , Pass: new(RegAlloc) }, 56 { Name: "Stack Liveness Analysis" , Pass: new(StackLiveness) }, 57 { Name: "Function Layout" , Pass: new(Layout) }, 58 } 59 60 func toFuncType(fn interface{}) reflect.Type { 61 if vt := reflect.TypeOf(fn); vt.Kind() != reflect.Func { 62 panic("ssa: fn must be a function prototype") 63 } else { 64 return vt 65 } 66 } 67 68 func executeSSAPasses(cfg *CFG) { 69 for _, p := range Passes { 70 p.Pass.Apply(cfg) 71 } 72 } 73 74 func Compile(p hir.Program, fn interface{}) (cfg *CFG) { 75 cfg = newGraphBuilder().build(p) 76 cfg.Layout = abi.ABI.LayoutFunc(-1, toFuncType(fn)) 77 insertPhiNodes(cfg) 78 renameRegisters(cfg) 79 executeSSAPasses(cfg) 80 return 81 }