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 IsTestAndSetCCInsn(const Insn &insn) const = 0; 64 virtual bool IsTestAndBranchInsn(const Insn &insn) const = 0; 65 virtual bool IsAddOrSubInsn(const Insn &insn) const = 0; 66 virtual bool IsSimpleJumpInsn(const Insn &insn) const = 0; 67 68 virtual void ReTargetSuccBB(BB &bb, LabelIdx newTarget) const = 0; 69 virtual void FlipIfBB(BB &bb, LabelIdx ftLabel) const = 0; 70 virtual BB *CreateGotoBBAfterCondBB(BB &bb, BB &fallthru, bool isTargetFallthru) const = 0; 71 72 // Change ftBB to gotoBB, Append new jumpInsn in curBB. 73 virtual void ModifyFathruBBToGotoBB(BB &bb, LabelIdx labelIdx) const = 0; 74 75 private: 76 CGFunc *cgFunc; 77 }; /* class InsnVisitor; */ 78 79 class CGCFG { 80 public: CGCFG(CGFunc & cgFunc)81 explicit CGCFG(CGFunc &cgFunc) : cgFunc(&cgFunc) {} 82 83 ~CGCFG() = default; 84 85 void BuildCFG(); 86 void CheckCFG(); 87 void CheckCFGFreq(); 88 89 void InitInsnVisitor(CGFunc &func) const; GetInsnModifier()90 InsnVisitor *GetInsnModifier() const 91 { 92 return insnVisitor; 93 } 94 95 static bool AreCommentAllPreds(const BB &bb); 96 bool CanMerge(const BB &merger, const BB &mergee) const; 97 bool BBJudge(const BB &first, const BB &second) const; 98 /* 99 * Merge all instructions in mergee into merger, each BB's successors and 100 * predecessors should be modified accordingly. 101 */ 102 static void MergeBB(BB &merger, BB &mergee, CGFunc &func); 103 104 /* 105 * Remove a BB from its position in the CFG. 106 * Prev, next, preds and sucs are all modified accordingly. 107 */ 108 void RemoveBB(BB &curBB, bool isGotoIf = false) const; 109 /* Skip the successor of bb, directly jump to bb's successor'ssuccessor */ 110 void RetargetJump(BB &srcBB, BB &targetBB) const; 111 112 /* 113 * Update the preds of CommonExitBB after changing cfg, 114 * We'd better do it once after cfgo opt 115 */ 116 void UpdateCommonExitBBInfo(); 117 118 /* Loop up if the given label is in the exception tables in LSDA */ 119 static bool InLSDA(LabelIdx label, const EHFunc *ehFunc); 120 static bool InSwitchTable(LabelIdx label, const CGFunc &func); 121 122 RegOperand *CreateVregFromReg(const RegOperand &pReg) const; 123 Insn *CloneInsn(Insn &originalInsn) const; 124 static BB *GetTargetSuc(BB &curBB, bool branchOnly = false, bool isGotoIf = false); 125 bool IsCompareAndBranchInsn(const Insn &insn) const; 126 bool IsTestAndBranchInsn(const Insn &insn) const; 127 bool IsAddOrSubInsn(const Insn &insn) const; 128 129 Insn *FindLastCondBrInsn(BB &bb) const; 130 static void FindAndMarkUnreachable(CGFunc &func); 131 void FlushUnReachableStatusAndRemoveRelations(BB &bb, const CGFunc &func) const; 132 void MarkLabelTakenBB() const; 133 void UnreachCodeAnalysis() const; 134 void FindWillExitBBs(BB *bb, std::set<BB *, BBIdCmp> *visitedBBs); 135 void WontExitAnalysis(); 136 BB *FindLastRetBB(); 137 138 void UpdatePredsSuccsAfterSplit(BB &pred, BB &succ, BB &newBB) const; 139 void BreakCriticalEdge(BB &pred, BB &succ) const; 140 /* cgcfgvisitor */ 141 private: 142 CGFunc *cgFunc = nullptr; 143 static InsnVisitor *insnVisitor; 144 static void MergeBB(BB &merger, BB &mergee); 145 }; /* class CGCFG */ 146 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgHandleCFG, maplebe::CGFunc) 147 OVERRIDE_DEPENDENCE 148 MAPLE_FUNC_PHASE_DECLARE_END 149 } /* namespace maplebe */ 150 151 #endif /* MAPLEBE_INCLUDE_CG_CG_CFG_H */ 152