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_validbit_opt.h"
17 #include "mempool.h"
18 #include "aarch64_validbit_opt.h"
19
20 namespace maplebe {
GetDefInsn(const RegOperand & useReg)21 Insn *ValidBitPattern::GetDefInsn(const RegOperand &useReg)
22 {
23 if (!useReg.IsSSAForm()) {
24 return nullptr;
25 }
26 regno_t useRegNO = useReg.GetRegisterNumber();
27 VRegVersion *useVersion = ssaInfo->FindSSAVersion(useRegNO);
28 DEBUG_ASSERT(useVersion != nullptr, "useVRegVersion must not be null based on ssa");
29 CHECK_FATAL(!useVersion->IsDeleted(), "deleted version");
30 DUInsnInfo *defInfo = useVersion->GetDefInsnInfo();
31 return defInfo == nullptr ? nullptr : defInfo->GetInsn();
32 }
33
GetAllUseInsn(const RegOperand & defReg)34 InsnSet ValidBitPattern::GetAllUseInsn(const RegOperand &defReg)
35 {
36 InsnSet allUseInsn;
37 if ((ssaInfo != nullptr) && defReg.IsSSAForm()) {
38 VRegVersion *defVersion = ssaInfo->FindSSAVersion(defReg.GetRegisterNumber());
39 CHECK_FATAL(defVersion != nullptr, "useVRegVersion must not be null based on ssa");
40 for (auto insnInfo : defVersion->GetAllUseInsns()) {
41 Insn *currInsn = insnInfo.second->GetInsn();
42 allUseInsn.emplace(currInsn);
43 }
44 }
45 return allUseInsn;
46 }
47
DumpAfterPattern(std::vector<Insn * > & prevInsns,const Insn * replacedInsn,const Insn * newInsn)48 void ValidBitPattern::DumpAfterPattern(std::vector<Insn *> &prevInsns, const Insn *replacedInsn, const Insn *newInsn)
49 {
50 LogInfo::MapleLogger() << ">>>>>>> In " << GetPatternName() << " : <<<<<<<\n";
51 if (!prevInsns.empty()) {
52 if ((replacedInsn == nullptr) && (newInsn == nullptr)) {
53 LogInfo::MapleLogger() << "======= RemoveInsns : {\n";
54 } else {
55 LogInfo::MapleLogger() << "======= PrevInsns : {\n";
56 }
57 for (auto *prevInsn : prevInsns) {
58 if (prevInsn != nullptr) {
59 LogInfo::MapleLogger() << "[primal form] ";
60 prevInsn->Dump();
61 if (ssaInfo != nullptr) {
62 LogInfo::MapleLogger() << "[ssa form] ";
63 ssaInfo->DumpInsnInSSAForm(*prevInsn);
64 }
65 }
66 }
67 LogInfo::MapleLogger() << "}\n";
68 }
69 if (replacedInsn != nullptr) {
70 LogInfo::MapleLogger() << "======= OldInsn :\n";
71 LogInfo::MapleLogger() << "[primal form] ";
72 replacedInsn->Dump();
73 if (ssaInfo != nullptr) {
74 LogInfo::MapleLogger() << "[ssa form] ";
75 ssaInfo->DumpInsnInSSAForm(*replacedInsn);
76 }
77 }
78 if (newInsn != nullptr) {
79 LogInfo::MapleLogger() << "======= NewInsn :\n";
80 LogInfo::MapleLogger() << "[primal form] ";
81 newInsn->Dump();
82 if (ssaInfo != nullptr) {
83 LogInfo::MapleLogger() << "[ssa form] ";
84 ssaInfo->DumpInsnInSSAForm(*newInsn);
85 }
86 }
87 }
88
RectifyValidBitNum()89 void ValidBitOpt::RectifyValidBitNum()
90 {
91 FOR_ALL_BB(bb, cgFunc) {
92 FOR_BB_INSNS(insn, bb) {
93 if (!insn->IsMachineInstruction()) {
94 continue;
95 }
96 SetValidBits(*insn);
97 }
98 }
99 bool iterate;
100 /* Use inverse postorder to converge with minimal iterations */
101 do {
102 iterate = false;
103 MapleVector<uint32> reversePostOrder = ssaInfo->GetReversePostOrder();
104 for (uint32 bbId : reversePostOrder) {
105 BB *bb = cgFunc->GetBBFromID(bbId);
106 FOR_BB_INSNS(insn, bb) {
107 if (!insn->IsPhi()) {
108 continue;
109 }
110 bool change = SetPhiValidBits(*insn);
111 if (change) {
112 /* if vb changes once, iterate. */
113 iterate = true;
114 }
115 }
116 }
117 } while (iterate);
118 }
119
RecoverValidBitNum()120 void ValidBitOpt::RecoverValidBitNum()
121 {
122 FOR_ALL_BB(bb, cgFunc) {
123 FOR_BB_INSNS(insn, bb) {
124 if (!insn->IsMachineInstruction() && !insn->IsPhi()) {
125 continue;
126 }
127 uint32 opndNum = insn->GetOperandSize();
128 for (uint32 i = 0; i < opndNum; ++i) {
129 if (insn->OpndIsDef(i) && insn->GetOperand(i).IsRegister()) {
130 auto &dstOpnd = static_cast<RegOperand &>(insn->GetOperand(i));
131 dstOpnd.SetValidBitsNum(dstOpnd.GetSize());
132 }
133 }
134 }
135 }
136 }
137
Run()138 void ValidBitOpt::Run()
139 {
140 /*
141 * Set validbit of regOpnd before optimization
142 */
143 RectifyValidBitNum();
144 FOR_ALL_BB(bb, cgFunc) {
145 FOR_BB_INSNS(insn, bb) {
146 if (!insn->IsMachineInstruction()) {
147 continue;
148 }
149 DoOpt(*bb, *insn);
150 }
151 }
152 /*
153 * Recover validbit of regOpnd after optimization
154 */
155 RecoverValidBitNum();
156 }
157
PhaseRun(maplebe::CGFunc & f)158 bool CgValidBitOpt::PhaseRun(maplebe::CGFunc &f)
159 {
160 CGSSAInfo *ssaInfo = GET_ANALYSIS(CgSSAConstruct, f);
161 CHECK_FATAL(ssaInfo != nullptr, "Get ssaInfo failed");
162 auto *vbOpt = f.GetCG()->CreateValidBitOpt(*GetPhaseMemPool(), f, *ssaInfo);
163 CHECK_FATAL(vbOpt != nullptr, "vbOpt instance create failed");
164 vbOpt->Run();
165 return true;
166 }
167
GetAnalysisDependence(AnalysisDep & aDep) const168 void CgValidBitOpt::GetAnalysisDependence(AnalysisDep &aDep) const
169 {
170 aDep.AddRequired<CgSSAConstruct>();
171 aDep.AddPreserved<CgSSAConstruct>();
172 }
173 MAPLE_TRANSFORM_PHASE_REGISTER_CANSKIP(CgValidBitOpt, cgvalidbitopt)
174 } /* namespace maplebe */
175