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  }