github.com/cloudwego/frugal@v0.1.15/internal/atm/ssa/cfg.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      `sync/atomic`
    21  
    22      `github.com/cloudwego/frugal/internal/atm/abi`
    23  )
    24  
    25  type _CFGPrivate struct {
    26      reg   uint64
    27      block uint64
    28  }
    29  
    30  func (self *_CFGPrivate) allocreg() int {
    31      return int(atomic.AddUint64(&self.reg, 1)) - 1
    32  }
    33  
    34  func (self *_CFGPrivate) allocblock() int {
    35      return int(atomic.AddUint64(&self.block, 1)) - 1
    36  }
    37  
    38  type CFG struct {
    39      _CFGPrivate
    40      Func              FuncData
    41      Root              *BasicBlock
    42      Depth             map[int]int
    43      Layout            *abi.FunctionLayout
    44      DominatedBy       map[int]*BasicBlock
    45      DominatorOf       map[int][]*BasicBlock
    46      DominanceFrontier map[int][]*BasicBlock
    47  }
    48  
    49  func (self *CFG) Rebuild() {
    50      updateDominatorTree(self)
    51      updateDominatorDepth(self)
    52      updateDominatorFrontier(self)
    53  }
    54  
    55  func (self *CFG) MaxBlock() int {
    56      return int(self.block)
    57  }
    58  
    59  func (self *CFG) PostOrder() *BasicBlockIter {
    60      return newBasicBlockIter(self)
    61  }
    62  
    63  func (self *CFG) CreateBlock() (r *BasicBlock) {
    64      r = new(BasicBlock)
    65      r.Id = self.allocblock()
    66      return
    67  }
    68  
    69  func (self *CFG) CreateRegister(ptr bool) Reg {
    70      if i := self.allocreg(); ptr {
    71          return mkreg(1, K_norm, 0).Derive(i)
    72      } else {
    73          return mkreg(0, K_norm, 0).Derive(i)
    74      }
    75  }
    76  
    77  func (self *CFG) CreateUnreachable(bb *BasicBlock) (ret *BasicBlock) {
    78      ret      = self.CreateBlock()
    79      ret.Ins  = []IrNode { new(IrBreakpoint) }
    80      ret.Term = &IrSwitch { Ln: IrLikely(ret) }
    81      ret.Pred = []*BasicBlock { bb, ret }
    82      return
    83  }