• 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 "x64_reaching.h"
17 #include "x64_cg.h"
18 #include "insn.h"
19 #include "isa.h"
20 namespace maplebe {
21 /* find insn using register between startInsn and endInsn
22  * startInsn and endInsn must be in the same BB.
23  */
FindRegUseBetweenInsn(uint32 regNO,Insn * startInsn,Insn * endInsn,InsnSet & regUseInsnSet) const24 bool X64ReachingDefinition::FindRegUseBetweenInsn(uint32 regNO, Insn *startInsn, Insn *endInsn,
25                                                   InsnSet &regUseInsnSet) const
26 {
27     DEBUG_ASSERT(startInsn->GetBB() == endInsn->GetBB(), "two insns must be in a same BB");
28     bool findFinish = false;
29     if (startInsn == nullptr || endInsn == nullptr) {
30         return findFinish;
31     }
32     for (Insn *insn = startInsn; insn != nullptr && insn != endInsn->GetNext(); insn = insn->GetNext()) {
33         if (!insn->IsMachineInstruction()) {
34             continue;
35         }
36         /* if insn is call and regNO is caller-saved register, then regNO will not be used later */
37         if (insn->IsCall() && IsRegKilledByCallInsn(*insn, regNO)) {
38             findFinish = true;
39         }
40 
41         if (IsDiv(*insn) && regNO == x64::RAX) {
42             /* div insn use rax implicitly */
43             findFinish = true;
44         }
45 
46         const InsnDesc *md = insn->GetDesc();
47         uint32 opndNum = insn->GetOperandSize();
48         for (uint32 i = 0; i < opndNum; ++i) {
49             Operand &opnd = insn->GetOperand(i);
50             /* handle def or def use */
51             auto *regProp = md->opndMD[i];
52             if (regProp->IsDef() && opnd.IsRegister() &&
53                 (static_cast<RegOperand &>(opnd).GetRegisterNumber() == regNO)) {
54                 findFinish = true;
55             }
56 
57             if (opnd.IsList()) {
58                 auto &listOpnd = static_cast<ListOperand &>(opnd);
59                 for (auto listElem : listOpnd.GetOperands()) {
60                     RegOperand *regOpnd = static_cast<RegOperand *>(listElem);
61                     DEBUG_ASSERT(regOpnd != nullptr, "parameter operand must be RegOperand");
62                     if (regNO == regOpnd->GetRegisterNumber()) {
63                         (void)regUseInsnSet.insert(insn);
64                     }
65                 }
66                 continue;
67             }
68             if (!regProp->IsUse() && !opnd.IsMemoryAccessOperand()) {
69                 continue;
70             }
71 
72             /* handle use */
73             if (opnd.IsMemoryAccessOperand()) {
74                 auto &memOpnd = static_cast<MemOperand &>(opnd);
75                 RegOperand *base = memOpnd.GetBaseRegister();
76                 RegOperand *index = memOpnd.GetIndexRegister();
77                 if ((base != nullptr && base->GetRegisterNumber() == regNO) ||
78                     (index != nullptr && index->GetRegisterNumber() == regNO)) {
79                     (void)regUseInsnSet.insert(insn);
80                 }
81             } else if (opnd.IsConditionCode()) {
82                 Operand &rflagOpnd = cgFunc->GetOrCreateRflag();
83                 RegOperand &rflagReg = static_cast<RegOperand &>(rflagOpnd);
84                 if (rflagReg.GetRegisterNumber() == regNO) {
85                     (void)regUseInsnSet.insert(insn);
86                 }
87             } else if (opnd.IsRegister() && (static_cast<RegOperand &>(opnd).GetRegisterNumber() == regNO)) {
88                 (void)regUseInsnSet.insert(insn);
89             }
90         }
91         if (findFinish) {
92             break;
93         }
94     }
95     return findFinish;
96 }
97 
FindRegDefBetweenInsnGlobal(uint32 regNO,Insn * startInsn,Insn * endInsn) const98 std::vector<Insn *> X64ReachingDefinition::FindRegDefBetweenInsnGlobal(uint32 regNO, Insn *startInsn,
99                                                                        Insn *endInsn) const
100 {
101     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
102     return {};
103 }
104 
FindMemDefBetweenInsn(uint32 offset,const Insn * startInsn,Insn * endInsn) const105 std::vector<Insn *> X64ReachingDefinition::FindMemDefBetweenInsn(uint32 offset, const Insn *startInsn,
106                                                                  Insn *endInsn) const
107 {
108     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
109     return {};
110 }
111 
FindRegUseBetweenInsnGlobal(uint32 regNO,Insn * startInsn,Insn * endInsn,BB * movBB) const112 bool X64ReachingDefinition::FindRegUseBetweenInsnGlobal(uint32 regNO, Insn *startInsn, Insn *endInsn, BB *movBB) const
113 {
114     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
115     return false;
116 }
117 
FindMemUseBetweenInsn(uint32 offset,Insn * startInsn,const Insn * endInsn,InsnSet & useInsnSet) const118 bool X64ReachingDefinition::FindMemUseBetweenInsn(uint32 offset, Insn *startInsn, const Insn *endInsn,
119                                                   InsnSet &useInsnSet) const
120 {
121     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
122     return false;
123 }
124 
HasRegDefBetweenInsnGlobal(uint32 regNO,Insn & startInsn,Insn & endInsn)125 bool X64ReachingDefinition::HasRegDefBetweenInsnGlobal(uint32 regNO, Insn &startInsn, Insn &endInsn)
126 {
127     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
128     return false;
129 }
130 
DFSFindRegDefBetweenBB(const BB & startBB,const BB & endBB,uint32 regNO,std::vector<VisitStatus> & visitedBB) const131 bool X64ReachingDefinition::DFSFindRegDefBetweenBB(const BB &startBB, const BB &endBB, uint32 regNO,
132                                                    std::vector<VisitStatus> &visitedBB) const
133 {
134     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
135     return false;
136 }
137 
FindDefForRegOpnd(Insn & insn,uint32 indexOrRegNO,bool isRegNO) const138 InsnSet X64ReachingDefinition::FindDefForRegOpnd(Insn &insn, uint32 indexOrRegNO, bool isRegNO) const
139 {
140     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
141     return {};
142 }
143 
FindDefForMemOpnd(Insn & insn,uint32 indexOrOffset,bool isOffset) const144 InsnSet X64ReachingDefinition::FindDefForMemOpnd(Insn &insn, uint32 indexOrOffset, bool isOffset) const
145 {
146     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
147     return {};
148 }
149 
FindUseForMemOpnd(Insn & insn,uint8 index,bool secondMem) const150 InsnSet X64ReachingDefinition::FindUseForMemOpnd(Insn &insn, uint8 index, bool secondMem) const
151 {
152     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
153     return {};
154 }
155 
FindRegUsingBetweenInsn(uint32 regNO,Insn * startInsn,const Insn * endInsn) const156 bool X64ReachingDefinition::FindRegUsingBetweenInsn(uint32 regNO, Insn *startInsn, const Insn *endInsn) const
157 {
158     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
159     return false;
160 }
161 
InitStartGen()162 void X64ReachingDefinition::InitStartGen()
163 {
164     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
165     return;
166 }
167 
InitGenUse(BB & bb,bool firstTime)168 void X64ReachingDefinition::InitGenUse(BB &bb, bool firstTime)
169 {
170     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
171     return;
172 }
173 
GenAllAsmDefRegs(BB & bb,Insn & insn,uint32 index)174 void X64ReachingDefinition::GenAllAsmDefRegs(BB &bb, Insn &insn, uint32 index)
175 {
176     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
177     return;
178 }
179 
GenAllAsmUseRegs(BB & bb,Insn & insn,uint32 index)180 void X64ReachingDefinition::GenAllAsmUseRegs(BB &bb, Insn &insn, uint32 index)
181 {
182     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
183     return;
184 }
185 
GenAllCallerSavedRegs(BB & bb,Insn & insn)186 void X64ReachingDefinition::GenAllCallerSavedRegs(BB &bb, Insn &insn)
187 {
188     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
189     return;
190 }
191 
KilledByCallBetweenInsnInSameBB(const Insn & startInsn,const Insn & endInsn,regno_t regNO) const192 bool X64ReachingDefinition::KilledByCallBetweenInsnInSameBB(const Insn &startInsn, const Insn &endInsn,
193                                                             regno_t regNO) const
194 {
195     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
196     return false;
197 }
198 
AddRetPseudoInsn(BB & bb)199 void X64ReachingDefinition::AddRetPseudoInsn(BB &bb)
200 {
201     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
202     return;
203 }
204 
IsCallerSavedReg(uint32 regNO) const205 bool X64ReachingDefinition::IsCallerSavedReg(uint32 regNO) const
206 {
207     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
208     return false;
209 }
210 
FindRegDefInBB(uint32 regNO,BB & bb,InsnSet & defInsnSet) const211 void X64ReachingDefinition::FindRegDefInBB(uint32 regNO, BB &bb, InsnSet &defInsnSet) const
212 {
213     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
214     return;
215 }
216 
FindMemDefInBB(uint32 offset,BB & bb,InsnSet & defInsnSet) const217 void X64ReachingDefinition::FindMemDefInBB(uint32 offset, BB &bb, InsnSet &defInsnSet) const
218 {
219     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
220     return;
221 }
222 
DFSFindDefForRegOpnd(const BB & startBB,uint32 regNO,std::vector<VisitStatus> & visitedBB,InsnSet & defInsnSet) const223 void X64ReachingDefinition::DFSFindDefForRegOpnd(const BB &startBB, uint32 regNO, std::vector<VisitStatus> &visitedBB,
224                                                  InsnSet &defInsnSet) const
225 {
226     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
227     return;
228 }
229 
DFSFindDefForMemOpnd(const BB & startBB,uint32 offset,std::vector<VisitStatus> & visitedBB,InsnSet & defInsnSet) const230 void X64ReachingDefinition::DFSFindDefForMemOpnd(const BB &startBB, uint32 offset, std::vector<VisitStatus> &visitedBB,
231                                                  InsnSet &defInsnSet) const
232 {
233     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
234     return;
235 }
236 
GetStackSize() const237 int32 X64ReachingDefinition::GetStackSize() const
238 {
239     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
240     return 0;
241 };
242 
AddRetPseudoInsns()243 void X64ReachingDefinition::AddRetPseudoInsns()
244 {
245     CHECK_FATAL(false, "x64_reaching analysis not implemented yet!");
246     return;
247 };
248 
249 /* reg killed killed by call insn */
IsRegKilledByCallInsn(const Insn & insn,regno_t regNO) const250 bool X64ReachingDefinition::IsRegKilledByCallInsn(const Insn &insn, regno_t regNO) const
251 {
252     return !x64::IsCalleeSavedReg(static_cast<X64reg>(regNO));
253 }
254 
IsDiv(const Insn & insn) const255 bool X64ReachingDefinition::IsDiv(const Insn &insn) const
256 {
257     MOperator mOp = insn.GetMachineOpcode();
258     return (MOP_idivw_r <= mOp && mOp <= MOP_divq_m);
259 }
260 
261 } /* namespace maplebe */
262