• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "cg_phi_elimination.h"
17 #include "cg.h"
18 #include "cgbb.h"
19 
20 namespace maplebe {
TranslateTSSAToCSSA()21 void PhiEliminate::TranslateTSSAToCSSA()
22 {
23     FOR_ALL_BB(bb, cgFunc) {
24         eliminatedBB.emplace(bb->GetId());
25         for (auto phiInsnIt : bb->GetPhiInsns()) {
26             /* Method I create a temp move for phi-node */
27             auto &destReg = static_cast<RegOperand &>(phiInsnIt.second->GetOperand(kInsnFirstOpnd));
28             RegOperand &tempMovDest = cgFunc->GetOrCreateVirtualRegisterOperand(CreateTempRegForCSSA(destReg));
29             auto &phiList = static_cast<PhiOperand &>(phiInsnIt.second->GetOperand(kInsnSecondOpnd));
30             for (auto phiOpndIt : phiList.GetOperands()) {
31                 uint32 fBBId = phiOpndIt.first;
32                 DEBUG_ASSERT(fBBId != 0, "GetFromBBID = 0");
33 #if DEBUG
34                 bool find = false;
35                 for (auto predBB : bb->GetPreds()) {
36                     if (predBB->GetId() == fBBId) {
37                         find = true;
38                     }
39                 }
40                 CHECK_FATAL(find, "dont exited pred for phi-node");
41 #endif
42                 PlaceMovInPredBB(fBBId, CreateMov(tempMovDest, *(phiOpndIt.second)));
43             }
44             if (!destReg.IsOfCC()) {
45                 Insn &movInsn = CreateMov(destReg, tempMovDest);
46                 bb->ReplaceInsn(*phiInsnIt.second, movInsn);
47             } else {
48                 bb->RemoveInsn(*phiInsnIt.second);
49             }
50         }
51     }
52 
53     FOR_ALL_BB(bb, cgFunc) {
54         FOR_BB_INSNS(insn, bb) {
55             CHECK_FATAL(eliminatedBB.count(bb->GetId()), "still have phi");
56             if (!insn->IsMachineInstruction()) {
57                 continue;
58             }
59             ReCreateRegOperand(*insn);
60             bb->GetPhiInsns().clear();
61         }
62     }
63     UpdateRematInfo();
64     cgFunc->SetSSAvRegCount(0);
65 }
66 
UpdateRematInfo()67 void PhiEliminate::UpdateRematInfo()
68 {
69     if (CGOptions::GetRematLevel() > 0) {
70         cgFunc->UpdateAllRegisterVregMapping(remateInfoAfterSSA);
71     }
72 }
73 
PlaceMovInPredBB(uint32 predBBId,Insn & movInsn)74 void PhiEliminate::PlaceMovInPredBB(uint32 predBBId, Insn &movInsn)
75 {
76     BB *predBB = cgFunc->GetBBFromID(predBBId);
77     DEBUG_ASSERT(movInsn.GetOperand(kInsnSecondOpnd).IsRegister(), "unexpect operand");
78     if (predBB->GetKind() == BB::kBBFallthru) {
79         predBB->AppendInsn(movInsn);
80     } else {
81         AppendMovAfterLastVregDef(*predBB, movInsn);
82     }
83 }
84 
GetAndIncreaseTempRegNO()85 regno_t PhiEliminate::GetAndIncreaseTempRegNO()
86 {
87     while (GetSSAInfo()->GetAllSSAOperands().count(tempRegNO)) {
88         tempRegNO++;
89     }
90     regno_t ori = tempRegNO;
91     tempRegNO++;
92     return ori;
93 }
94 
MakeRoomForNoDefVreg(RegOperand & conflictReg)95 RegOperand *PhiEliminate::MakeRoomForNoDefVreg(RegOperand &conflictReg)
96 {
97     regno_t conflictVregNO = conflictReg.GetRegisterNumber();
98     auto rVregIt = replaceVreg.find(conflictVregNO);
99     if (rVregIt != replaceVreg.end()) {
100         return rVregIt->second;
101     } else {
102         RegOperand *regForRecreate = &CreateTempRegForCSSA(conflictReg);
103         (void)replaceVreg.emplace(std::pair<regno_t, RegOperand *>(conflictVregNO, regForRecreate));
104         return regForRecreate;
105     }
106 }
107 
RecordRematInfo(regno_t vRegNO,PregIdx pIdx)108 void PhiEliminate::RecordRematInfo(regno_t vRegNO, PregIdx pIdx)
109 {
110     if (remateInfoAfterSSA.count(vRegNO)) {
111         if (remateInfoAfterSSA[vRegNO] != pIdx) {
112             remateInfoAfterSSA.erase(vRegNO);
113         }
114     } else {
115         (void)remateInfoAfterSSA.emplace(std::pair<regno_t, PregIdx>(vRegNO, pIdx));
116     }
117 }
118 
PhaseRun(maplebe::CGFunc & f)119 bool CgPhiElimination::PhaseRun(maplebe::CGFunc &f)
120 {
121     CGSSAInfo *ssaInfo = GET_ANALYSIS(CgSSAConstruct, f);
122     PhiEliminate *pe = f.GetCG()->CreatePhiElimintor(*GetPhaseMemPool(), f, *ssaInfo);
123     DEBUG_ASSERT(pe != nullptr, "nullptr check");
124     pe->TranslateTSSAToCSSA();
125     return false;
126 }
GetAnalysisDependence(maple::AnalysisDep & aDep) const127 void CgPhiElimination::GetAnalysisDependence(maple::AnalysisDep &aDep) const
128 {
129     aDep.AddRequired<CgSSAConstruct>();
130 }
131 MAPLE_TRANSFORM_PHASE_REGISTER(CgPhiElimination, cgphielimination)
132 }  // namespace maplebe
133