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