1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MAPLEBE_INCLUDE_CG_CG_CFG_H 17 #define MAPLEBE_INCLUDE_CG_CG_CFG_H 18 #include "eh_func.h" 19 #include "cgbb.h" 20 21 namespace maplebe { 22 class InsnVisitor { 23 public: InsnVisitor(CGFunc & func)24 explicit InsnVisitor(CGFunc &func) : cgFunc(&func) {} 25 26 virtual ~InsnVisitor() = default; GetCGFunc()27 CGFunc *GetCGFunc() const 28 { 29 return cgFunc; 30 } 31 32 /* 33 * Precondition: 34 * The last instruction in bb is either conditional or unconditional jump. 35 * 36 * The jump target of bb is modified to the location specified by targetLabel. 37 */ 38 virtual void ModifyJumpTarget(LabelIdx targetLabel, BB &bb) = 0; 39 40 /* 41 * Precondition: 42 * The last instruction in bb is either conditional or unconditional jump. 43 * 44 * The jump target of bb is modified to the location specified by targetOperand. 45 */ 46 virtual void ModifyJumpTarget(Operand &targetOperand, BB &bb) = 0; 47 48 /* 49 * Precondition: 50 * The last instruction in bb is either a conditional or an unconditional jump. 51 * The last instruction in newTarget is an unconditional jump. 52 * 53 * The jump target of bb is modified to newTarget's jump target. 54 */ 55 virtual void ModifyJumpTarget(BB &newTarget, BB &bb) = 0; 56 /* Check if it requires to add extra gotos when relocate bb */ 57 virtual Insn *CloneInsn(Insn &originalInsn) = 0; 58 /* Create a new virtual register operand which has the same type and size as the given one. */ 59 virtual RegOperand *CreateVregFromReg(const RegOperand ®) = 0; 60 virtual LabelIdx GetJumpLabel(const Insn &insn) const = 0; 61 virtual bool IsCompareInsn(const Insn &insn) const = 0; 62 virtual bool IsCompareAndBranchInsn(const Insn &insn) const = 0; 63 virtual bool IsAddOrSubInsn(const Insn &insn) const = 0; 64 65 private: 66 CGFunc *cgFunc; 67 }; /* class InsnVisitor; */ 68 69 class CGCFG { 70 public: CGCFG(CGFunc & cgFunc)71 explicit CGCFG(CGFunc &cgFunc) : cgFunc(&cgFunc) {} 72 73 ~CGCFG() = default; 74 75 void BuildCFG(); 76 void CheckCFG(); 77 void CheckCFGFreq(); 78 79 void InitInsnVisitor(CGFunc &func); GetInsnModifier()80 InsnVisitor *GetInsnModifier() const 81 { 82 return insnVisitor; 83 } 84 85 static bool AreCommentAllPreds(const BB &bb); 86 bool CanMerge(const BB &merger, const BB &mergee) const; 87 bool BBJudge(const BB &first, const BB &second) const; 88 /* 89 * Merge all instructions in mergee into merger, each BB's successors and 90 * predecessors should be modified accordingly. 91 */ 92 static void MergeBB(BB &merger, BB &mergee, CGFunc &func); 93 94 /* 95 * Remove a BB from its position in the CFG. 96 * Prev, next, preds and sucs are all modified accordingly. 97 */ 98 void RemoveBB(BB &curBB, bool isGotoIf = false); 99 /* Skip the successor of bb, directly jump to bb's successor'ssuccessor */ 100 void RetargetJump(BB &srcBB, BB &targetBB); 101 102 /* Loop up if the given label is in the exception tables in LSDA */ 103 static bool InLSDA(LabelIdx label, const EHFunc &ehFunc); 104 static bool InSwitchTable(LabelIdx label, const CGFunc &func); 105 106 RegOperand *CreateVregFromReg(const RegOperand &pReg); 107 Insn *CloneInsn(Insn &originalInsn); 108 static BB *GetTargetSuc(BB &curBB, bool branchOnly = false, bool isGotoIf = false); 109 bool IsCompareAndBranchInsn(const Insn &insn) const; 110 bool IsAddOrSubInsn(const Insn &insn) const; 111 112 Insn *FindLastCondBrInsn(BB &bb) const; 113 static void FindAndMarkUnreachable(CGFunc &func); 114 void FlushUnReachableStatusAndRemoveRelations(BB &bb, const CGFunc &func) const; 115 void MarkLabelTakenBB(); 116 void UnreachCodeAnalysis(); 117 void FindWillExitBBs(BB *bb, std::set<BB *, BBIdCmp> *visitedBBs); 118 void WontExitAnalysis(); 119 BB *FindLastRetBB(); 120 121 void UpdatePredsSuccsAfterSplit(BB &pred, BB &succ, BB &newBB); 122 void BreakCriticalEdge(BB &pred, BB &succ); 123 /* cgcfgvisitor */ 124 private: 125 CGFunc *cgFunc = nullptr; 126 static InsnVisitor *insnVisitor; 127 static void MergeBB(BB &merger, BB &mergee); 128 }; /* class CGCFG */ 129 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgHandleCFG, maplebe::CGFunc) 130 MAPLE_FUNC_PHASE_DECLARE_END 131 } /* namespace maplebe */ 132 133 #endif /* MAPLEBE_INCLUDE_CG_CG_CFG_H */ 134