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 }