clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name MIParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Analysis -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ASMParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/BinaryFormat -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitstream -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /include/llvm/CodeGen -I /include/llvm/CodeGen/PBQP -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Coroutines -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData/Coverage -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/CodeView -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/DWARF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/MSF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/PDB -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Demangle -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/JITLink -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/Orc -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenACC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenMP -I /include/llvm/CodeGen/GlobalISel -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IRReader -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/LTO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Linker -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC/MCParser -I /include/llvm/CodeGen/MIRParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Object -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Option -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Passes -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Scalar -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Support -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/Symbolize -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Target -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Utils -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Vectorize -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/IPO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libLLVM/../include -I /usr/src/gnu/usr.bin/clang/libLLVM/obj -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -D PIC -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -D_RET_PROTECTOR -ret-protector -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/CodeGen/MIRParser/MIParser.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "llvm/CodeGen/MIRParser/MIParser.h" |
14 | #include "MILexer.h" |
15 | #include "llvm/ADT/APInt.h" |
16 | #include "llvm/ADT/APSInt.h" |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/ADT/DenseMap.h" |
19 | #include "llvm/ADT/None.h" |
20 | #include "llvm/ADT/Optional.h" |
21 | #include "llvm/ADT/SmallVector.h" |
22 | #include "llvm/ADT/StringMap.h" |
23 | #include "llvm/ADT/StringRef.h" |
24 | #include "llvm/ADT/StringSwitch.h" |
25 | #include "llvm/ADT/Twine.h" |
26 | #include "llvm/Analysis/MemoryLocation.h" |
27 | #include "llvm/AsmParser/Parser.h" |
28 | #include "llvm/AsmParser/SlotMapping.h" |
29 | #include "llvm/CodeGen/GlobalISel/RegisterBank.h" |
30 | #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" |
31 | #include "llvm/CodeGen/MIRFormatter.h" |
32 | #include "llvm/CodeGen/MIRPrinter.h" |
33 | #include "llvm/CodeGen/MachineBasicBlock.h" |
34 | #include "llvm/CodeGen/MachineFrameInfo.h" |
35 | #include "llvm/CodeGen/MachineFunction.h" |
36 | #include "llvm/CodeGen/MachineInstr.h" |
37 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
38 | #include "llvm/CodeGen/MachineMemOperand.h" |
39 | #include "llvm/CodeGen/MachineOperand.h" |
40 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
41 | #include "llvm/CodeGen/TargetInstrInfo.h" |
42 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
43 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
44 | #include "llvm/IR/BasicBlock.h" |
45 | #include "llvm/IR/Constants.h" |
46 | #include "llvm/IR/DataLayout.h" |
47 | #include "llvm/IR/DebugInfoMetadata.h" |
48 | #include "llvm/IR/DebugLoc.h" |
49 | #include "llvm/IR/Function.h" |
50 | #include "llvm/IR/InstrTypes.h" |
51 | #include "llvm/IR/Instructions.h" |
52 | #include "llvm/IR/Intrinsics.h" |
53 | #include "llvm/IR/Metadata.h" |
54 | #include "llvm/IR/Module.h" |
55 | #include "llvm/IR/ModuleSlotTracker.h" |
56 | #include "llvm/IR/Type.h" |
57 | #include "llvm/IR/Value.h" |
58 | #include "llvm/IR/ValueSymbolTable.h" |
59 | #include "llvm/MC/LaneBitmask.h" |
60 | #include "llvm/MC/MCContext.h" |
61 | #include "llvm/MC/MCDwarf.h" |
62 | #include "llvm/MC/MCInstrDesc.h" |
63 | #include "llvm/MC/MCRegisterInfo.h" |
64 | #include "llvm/Support/AtomicOrdering.h" |
65 | #include "llvm/Support/BranchProbability.h" |
66 | #include "llvm/Support/Casting.h" |
67 | #include "llvm/Support/ErrorHandling.h" |
68 | #include "llvm/Support/LowLevelTypeImpl.h" |
69 | #include "llvm/Support/MemoryBuffer.h" |
70 | #include "llvm/Support/SMLoc.h" |
71 | #include "llvm/Support/SourceMgr.h" |
72 | #include "llvm/Support/raw_ostream.h" |
73 | #include "llvm/Target/TargetIntrinsicInfo.h" |
74 | #include "llvm/Target/TargetMachine.h" |
75 | #include <algorithm> |
76 | #include <cassert> |
77 | #include <cctype> |
78 | #include <cstddef> |
79 | #include <cstdint> |
80 | #include <limits> |
81 | #include <string> |
82 | #include <utility> |
83 | |
84 | using namespace llvm; |
85 | |
86 | void PerTargetMIParsingState::setTarget( |
87 | const TargetSubtargetInfo &NewSubtarget) { |
88 | |
89 | |
90 | if (&Subtarget == &NewSubtarget) |
91 | return; |
92 | |
93 | Names2InstrOpCodes.clear(); |
94 | Names2Regs.clear(); |
95 | Names2RegMasks.clear(); |
96 | Names2SubRegIndices.clear(); |
97 | Names2TargetIndices.clear(); |
98 | Names2DirectTargetFlags.clear(); |
99 | Names2BitmaskTargetFlags.clear(); |
100 | Names2MMOTargetFlags.clear(); |
101 | |
102 | initNames2RegClasses(); |
103 | initNames2RegBanks(); |
104 | } |
105 | |
106 | void PerTargetMIParsingState::initNames2Regs() { |
107 | if (!Names2Regs.empty()) |
108 | return; |
109 | |
110 | |
111 | Names2Regs.insert(std::make_pair("noreg", 0)); |
112 | const auto *TRI = Subtarget.getRegisterInfo(); |
113 | assert(TRI && "Expected target register info"); |
114 | |
115 | for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) { |
116 | bool WasInserted = |
117 | Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I)) |
118 | .second; |
119 | (void)WasInserted; |
120 | assert(WasInserted && "Expected registers to be unique case-insensitively"); |
121 | } |
122 | } |
123 | |
124 | bool PerTargetMIParsingState::getRegisterByName(StringRef RegName, |
125 | Register &Reg) { |
126 | initNames2Regs(); |
127 | auto RegInfo = Names2Regs.find(RegName); |
128 | if (RegInfo == Names2Regs.end()) |
129 | return true; |
130 | Reg = RegInfo->getValue(); |
131 | return false; |
132 | } |
133 | |
134 | void PerTargetMIParsingState::initNames2InstrOpCodes() { |
135 | if (!Names2InstrOpCodes.empty()) |
136 | return; |
137 | const auto *TII = Subtarget.getInstrInfo(); |
138 | assert(TII && "Expected target instruction info"); |
139 | for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) |
140 | Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); |
141 | } |
142 | |
143 | bool PerTargetMIParsingState::parseInstrName(StringRef InstrName, |
144 | unsigned &OpCode) { |
145 | initNames2InstrOpCodes(); |
146 | auto InstrInfo = Names2InstrOpCodes.find(InstrName); |
147 | if (InstrInfo == Names2InstrOpCodes.end()) |
148 | return true; |
149 | OpCode = InstrInfo->getValue(); |
150 | return false; |
151 | } |
152 | |
153 | void PerTargetMIParsingState::initNames2RegMasks() { |
154 | if (!Names2RegMasks.empty()) |
155 | return; |
156 | const auto *TRI = Subtarget.getRegisterInfo(); |
157 | assert(TRI && "Expected target register info"); |
158 | ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks(); |
159 | ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames(); |
160 | assert(RegMasks.size() == RegMaskNames.size()); |
161 | for (size_t I = 0, E = RegMasks.size(); I < E; ++I) |
162 | Names2RegMasks.insert( |
163 | std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I])); |
164 | } |
165 | |
166 | const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) { |
167 | initNames2RegMasks(); |
168 | auto RegMaskInfo = Names2RegMasks.find(Identifier); |
169 | if (RegMaskInfo == Names2RegMasks.end()) |
170 | return nullptr; |
171 | return RegMaskInfo->getValue(); |
172 | } |
173 | |
174 | void PerTargetMIParsingState::initNames2SubRegIndices() { |
175 | if (!Names2SubRegIndices.empty()) |
176 | return; |
177 | const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); |
178 | for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) |
179 | Names2SubRegIndices.insert( |
180 | std::make_pair(TRI->getSubRegIndexName(I), I)); |
181 | } |
182 | |
183 | unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) { |
184 | initNames2SubRegIndices(); |
185 | auto SubRegInfo = Names2SubRegIndices.find(Name); |
186 | if (SubRegInfo == Names2SubRegIndices.end()) |
187 | return 0; |
188 | return SubRegInfo->getValue(); |
189 | } |
190 | |
191 | void PerTargetMIParsingState::initNames2TargetIndices() { |
192 | if (!Names2TargetIndices.empty()) |
193 | return; |
194 | const auto *TII = Subtarget.getInstrInfo(); |
195 | assert(TII && "Expected target instruction info"); |
196 | auto Indices = TII->getSerializableTargetIndices(); |
197 | for (const auto &I : Indices) |
198 | Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); |
199 | } |
200 | |
201 | bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) { |
202 | initNames2TargetIndices(); |
203 | auto IndexInfo = Names2TargetIndices.find(Name); |
204 | if (IndexInfo == Names2TargetIndices.end()) |
205 | return true; |
206 | Index = IndexInfo->second; |
207 | return false; |
208 | } |
209 | |
210 | void PerTargetMIParsingState::initNames2DirectTargetFlags() { |
211 | if (!Names2DirectTargetFlags.empty()) |
212 | return; |
213 | |
214 | const auto *TII = Subtarget.getInstrInfo(); |
215 | assert(TII && "Expected target instruction info"); |
216 | auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); |
217 | for (const auto &I : Flags) |
218 | Names2DirectTargetFlags.insert( |
219 | std::make_pair(StringRef(I.second), I.first)); |
220 | } |
221 | |
222 | bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name, |
223 | unsigned &Flag) { |
224 | initNames2DirectTargetFlags(); |
225 | auto FlagInfo = Names2DirectTargetFlags.find(Name); |
226 | if (FlagInfo == Names2DirectTargetFlags.end()) |
227 | return true; |
228 | Flag = FlagInfo->second; |
229 | return false; |
230 | } |
231 | |
232 | void PerTargetMIParsingState::initNames2BitmaskTargetFlags() { |
233 | if (!Names2BitmaskTargetFlags.empty()) |
234 | return; |
235 | |
236 | const auto *TII = Subtarget.getInstrInfo(); |
237 | assert(TII && "Expected target instruction info"); |
238 | auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags(); |
239 | for (const auto &I : Flags) |
240 | Names2BitmaskTargetFlags.insert( |
241 | std::make_pair(StringRef(I.second), I.first)); |
242 | } |
243 | |
244 | bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name, |
245 | unsigned &Flag) { |
246 | initNames2BitmaskTargetFlags(); |
247 | auto FlagInfo = Names2BitmaskTargetFlags.find(Name); |
248 | if (FlagInfo == Names2BitmaskTargetFlags.end()) |
249 | return true; |
250 | Flag = FlagInfo->second; |
251 | return false; |
252 | } |
253 | |
254 | void PerTargetMIParsingState::initNames2MMOTargetFlags() { |
255 | if (!Names2MMOTargetFlags.empty()) |
256 | return; |
257 | |
258 | const auto *TII = Subtarget.getInstrInfo(); |
259 | assert(TII && "Expected target instruction info"); |
260 | auto Flags = TII->getSerializableMachineMemOperandTargetFlags(); |
261 | for (const auto &I : Flags) |
262 | Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first)); |
263 | } |
264 | |
265 | bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name, |
266 | MachineMemOperand::Flags &Flag) { |
267 | initNames2MMOTargetFlags(); |
268 | auto FlagInfo = Names2MMOTargetFlags.find(Name); |
269 | if (FlagInfo == Names2MMOTargetFlags.end()) |
270 | return true; |
271 | Flag = FlagInfo->second; |
272 | return false; |
273 | } |
274 | |
275 | void PerTargetMIParsingState::initNames2RegClasses() { |
276 | if (!Names2RegClasses.empty()) |
277 | return; |
278 | |
279 | const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); |
280 | for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { |
281 | const auto *RC = TRI->getRegClass(I); |
282 | Names2RegClasses.insert( |
283 | std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); |
284 | } |
285 | } |
286 | |
287 | void PerTargetMIParsingState::initNames2RegBanks() { |
288 | if (!Names2RegBanks.empty()) |
289 | return; |
290 | |
291 | const RegisterBankInfo *RBI = Subtarget.getRegBankInfo(); |
292 | |
293 | |
294 | if (!RBI) |
295 | return; |
296 | |
297 | for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) { |
298 | const auto &RegBank = RBI->getRegBank(I); |
299 | Names2RegBanks.insert( |
300 | std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); |
301 | } |
302 | } |
303 | |
304 | const TargetRegisterClass * |
305 | PerTargetMIParsingState::getRegClass(StringRef Name) { |
306 | auto RegClassInfo = Names2RegClasses.find(Name); |
307 | if (RegClassInfo == Names2RegClasses.end()) |
308 | return nullptr; |
309 | return RegClassInfo->getValue(); |
310 | } |
311 | |
312 | const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) { |
313 | auto RegBankInfo = Names2RegBanks.find(Name); |
314 | if (RegBankInfo == Names2RegBanks.end()) |
315 | return nullptr; |
316 | return RegBankInfo->getValue(); |
317 | } |
318 | |
319 | PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF, |
320 | SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T) |
321 | : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) { |
322 | } |
323 | |
324 | VRegInfo &PerFunctionMIParsingState::getVRegInfo(Register Num) { |
325 | auto I = VRegInfos.insert(std::make_pair(Num, nullptr)); |
326 | if (I.second) { |
327 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
328 | VRegInfo *Info = new (Allocator) VRegInfo; |
329 | Info->VReg = MRI.createIncompleteVirtualRegister(); |
330 | I.first->second = Info; |
331 | } |
332 | return *I.first->second; |
333 | } |
334 | |
335 | VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) { |
336 | assert(RegName != "" && "Expected named reg."); |
337 | |
338 | auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr)); |
339 | if (I.second) { |
340 | VRegInfo *Info = new (Allocator) VRegInfo; |
341 | Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName); |
342 | I.first->second = Info; |
343 | } |
344 | return *I.first->second; |
345 | } |
346 | |
347 | static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST, |
348 | DenseMap<unsigned, const Value *> &Slots2Values) { |
349 | int Slot = MST.getLocalSlot(V); |
350 | if (Slot == -1) |
351 | return; |
352 | Slots2Values.insert(std::make_pair(unsigned(Slot), V)); |
353 | } |
354 | |
355 | |
356 | static void initSlots2Values(const Function &F, |
357 | DenseMap<unsigned, const Value *> &Slots2Values) { |
358 | ModuleSlotTracker MST(F.getParent(), false); |
359 | MST.incorporateFunction(F); |
360 | for (const auto &Arg : F.args()) |
361 | mapValueToSlot(&Arg, MST, Slots2Values); |
362 | for (const auto &BB : F) { |
363 | mapValueToSlot(&BB, MST, Slots2Values); |
364 | for (const auto &I : BB) |
365 | mapValueToSlot(&I, MST, Slots2Values); |
366 | } |
367 | } |
368 | |
369 | const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) { |
370 | if (Slots2Values.empty()) |
371 | initSlots2Values(MF.getFunction(), Slots2Values); |
372 | return Slots2Values.lookup(Slot); |
373 | } |
374 | |
375 | namespace { |
376 | |
377 | |
378 | |
379 | struct ParsedMachineOperand { |
380 | MachineOperand Operand; |
381 | StringRef::iterator Begin; |
382 | StringRef::iterator End; |
383 | Optional<unsigned> TiedDefIdx; |
384 | |
385 | ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin, |
386 | StringRef::iterator End, Optional<unsigned> &TiedDefIdx) |
387 | : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) { |
388 | if (TiedDefIdx) |
389 | assert(Operand.isReg() && Operand.isUse() && |
390 | "Only used register operands can be tied"); |
391 | } |
392 | }; |
393 | |
394 | class MIParser { |
395 | MachineFunction &MF; |
396 | SMDiagnostic &Error; |
397 | StringRef Source, CurrentSource; |
398 | SMRange SourceRange; |
399 | MIToken Token; |
400 | PerFunctionMIParsingState &PFS; |
401 | |
402 | DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks; |
403 | |
404 | public: |
405 | MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, |
406 | StringRef Source); |
407 | MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, |
408 | StringRef Source, SMRange SourceRange); |
409 | |
410 | |
411 | |
412 | void lex(unsigned SkipChar = 0); |
413 | |
414 | |
415 | |
416 | |
417 | bool error(const Twine &Msg); |
418 | |
419 | |
420 | |
421 | |
422 | bool error(StringRef::iterator Loc, const Twine &Msg); |
423 | |
424 | bool |
425 | parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); |
426 | bool parseBasicBlocks(); |
427 | bool parse(MachineInstr *&MI); |
428 | bool parseStandaloneMBB(MachineBasicBlock *&MBB); |
429 | bool parseStandaloneNamedRegister(Register &Reg); |
430 | bool parseStandaloneVirtualRegister(VRegInfo *&Info); |
431 | bool parseStandaloneRegister(Register &Reg); |
432 | bool parseStandaloneStackObject(int &FI); |
433 | bool parseStandaloneMDNode(MDNode *&Node); |
434 | bool parseMachineMetadata(); |
435 | bool parseMDTuple(MDNode *&MD, bool IsDistinct); |
436 | bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts); |
437 | bool parseMetadata(Metadata *&MD); |
438 | |
439 | bool |
440 | parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); |
441 | bool parseBasicBlock(MachineBasicBlock &MBB, |
442 | MachineBasicBlock *&AddFalthroughFrom); |
443 | bool parseBasicBlockLiveins(MachineBasicBlock &MBB); |
444 | bool parseBasicBlockSuccessors(MachineBasicBlock &MBB); |
445 | |
446 | bool parseNamedRegister(Register &Reg); |
447 | bool parseVirtualRegister(VRegInfo *&Info); |
448 | bool parseNamedVirtualRegister(VRegInfo *&Info); |
449 | bool parseRegister(Register &Reg, VRegInfo *&VRegInfo); |
450 | bool parseRegisterFlag(unsigned &Flags); |
451 | bool parseRegisterClassOrBank(VRegInfo &RegInfo); |
452 | bool parseSubRegisterIndex(unsigned &SubReg); |
453 | bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx); |
454 | bool parseRegisterOperand(MachineOperand &Dest, |
455 | Optional<unsigned> &TiedDefIdx, bool IsDef = false); |
456 | bool parseImmediateOperand(MachineOperand &Dest); |
457 | bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, |
458 | const Constant *&C); |
459 | bool parseIRConstant(StringRef::iterator Loc, const Constant *&C); |
460 | bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty); |
461 | bool parseTypedImmediateOperand(MachineOperand &Dest); |
462 | bool parseFPImmediateOperand(MachineOperand &Dest); |
463 | bool parseMBBReference(MachineBasicBlock *&MBB); |
464 | bool parseMBBOperand(MachineOperand &Dest); |
465 | bool parseStackFrameIndex(int &FI); |
466 | bool parseStackObjectOperand(MachineOperand &Dest); |
467 | bool parseFixedStackFrameIndex(int &FI); |
468 | bool parseFixedStackObjectOperand(MachineOperand &Dest); |
469 | bool parseGlobalValue(GlobalValue *&GV); |
470 | bool parseGlobalAddressOperand(MachineOperand &Dest); |
471 | bool parseConstantPoolIndexOperand(MachineOperand &Dest); |
472 | bool parseSubRegisterIndexOperand(MachineOperand &Dest); |
473 | bool parseJumpTableIndexOperand(MachineOperand &Dest); |
474 | bool parseExternalSymbolOperand(MachineOperand &Dest); |
475 | bool parseMCSymbolOperand(MachineOperand &Dest); |
476 | bool parseMDNode(MDNode *&Node); |
477 | bool parseDIExpression(MDNode *&Expr); |
478 | bool parseDILocation(MDNode *&Expr); |
479 | bool parseMetadataOperand(MachineOperand &Dest); |
480 | bool parseCFIOffset(int &Offset); |
481 | bool parseCFIRegister(Register &Reg); |
482 | bool parseCFIAddressSpace(unsigned &AddressSpace); |
483 | bool parseCFIEscapeValues(std::string& Values); |
484 | bool parseCFIOperand(MachineOperand &Dest); |
485 | bool parseIRBlock(BasicBlock *&BB, const Function &F); |
486 | bool parseBlockAddressOperand(MachineOperand &Dest); |
487 | bool parseIntrinsicOperand(MachineOperand &Dest); |
488 | bool parsePredicateOperand(MachineOperand &Dest); |
489 | bool parseShuffleMaskOperand(MachineOperand &Dest); |
490 | bool parseTargetIndexOperand(MachineOperand &Dest); |
491 | bool parseCustomRegisterMaskOperand(MachineOperand &Dest); |
492 | bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); |
493 | bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, |
494 | MachineOperand &Dest, |
495 | Optional<unsigned> &TiedDefIdx); |
496 | bool parseMachineOperandAndTargetFlags(const unsigned OpCode, |
497 | const unsigned OpIdx, |
498 | MachineOperand &Dest, |
499 | Optional<unsigned> &TiedDefIdx); |
500 | bool parseOffset(int64_t &Offset); |
501 | bool parseAlignment(unsigned &Alignment); |
502 | bool parseAddrspace(unsigned &Addrspace); |
503 | bool parseSectionID(Optional<MBBSectionID> &SID); |
504 | bool parseOperandsOffset(MachineOperand &Op); |
505 | bool parseIRValue(const Value *&V); |
506 | bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags); |
507 | bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV); |
508 | bool parseMachinePointerInfo(MachinePointerInfo &Dest); |
509 | bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID); |
510 | bool parseOptionalAtomicOrdering(AtomicOrdering &Order); |
511 | bool parseMachineMemoryOperand(MachineMemOperand *&Dest); |
512 | bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol); |
513 | bool parseHeapAllocMarker(MDNode *&Node); |
514 | |
515 | bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx, |
516 | MachineOperand &Dest, const MIRFormatter &MF); |
517 | |
518 | private: |
519 | |
520 | |
521 | |
522 | bool getUnsigned(unsigned &Result); |
523 | |
524 | |
525 | |
526 | |
527 | bool getUint64(uint64_t &Result); |
528 | |
529 | |
530 | |
531 | |
532 | |
533 | bool getHexUint(APInt &Result); |
534 | |
535 | |
536 | |
537 | bool expectAndConsume(MIToken::TokenKind TokenKind); |
538 | |
539 | |
540 | |
541 | bool consumeIfPresent(MIToken::TokenKind TokenKind); |
542 | |
543 | bool parseInstruction(unsigned &OpCode, unsigned &Flags); |
544 | |
545 | bool assignRegisterTies(MachineInstr &MI, |
546 | ArrayRef<ParsedMachineOperand> Operands); |
547 | |
548 | bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, |
549 | const MCInstrDesc &MCID); |
550 | |
551 | const BasicBlock *getIRBlock(unsigned Slot); |
552 | const BasicBlock *getIRBlock(unsigned Slot, const Function &F); |
553 | |
554 | |
555 | MCSymbol *getOrCreateMCSymbol(StringRef Name); |
556 | |
557 | |
558 | |
559 | bool parseStringConstant(std::string &Result); |
560 | |
561 | |
562 | |
563 | SMLoc mapSMLoc(StringRef::iterator Loc); |
564 | }; |
565 | |
566 | } |
567 | |
568 | MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, |
569 | StringRef Source) |
570 | : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS) |
571 | {} |
572 | |
573 | MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, |
574 | StringRef Source, SMRange SourceRange) |
575 | : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), |
576 | SourceRange(SourceRange), PFS(PFS) {} |
577 | |
578 | void MIParser::lex(unsigned SkipChar) { |
579 | CurrentSource = lexMIToken( |
580 | CurrentSource.slice(SkipChar, StringRef::npos), Token, |
581 | [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); }); |
582 | } |
583 | |
584 | bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); } |
585 | |
586 | bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) { |
587 | const SourceMgr &SM = *PFS.SM; |
588 | assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size())); |
589 | const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID()); |
590 | if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) { |
591 | |
592 | |
593 | Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); |
594 | return true; |
595 | } |
596 | |
597 | Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1, |
598 | Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), |
599 | Source, None, None); |
600 | return true; |
601 | } |
602 | |
603 | SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) { |
604 | assert(SourceRange.isValid() && "Invalid source range"); |
605 | assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size())); |
606 | return SMLoc::getFromPointer(SourceRange.Start.getPointer() + |
607 | (Loc - Source.data())); |
608 | } |
609 | |
610 | typedef function_ref<bool(StringRef::iterator Loc, const Twine &)> |
611 | ErrorCallbackType; |
612 | |
613 | static const char *toString(MIToken::TokenKind TokenKind) { |
614 | switch (TokenKind) { |
615 | case MIToken::comma: |
616 | return "','"; |
617 | case MIToken::equal: |
618 | return "'='"; |
619 | case MIToken::colon: |
620 | return "':'"; |
621 | case MIToken::lparen: |
622 | return "'('"; |
623 | case MIToken::rparen: |
624 | return "')'"; |
625 | default: |
626 | return "<unknown token>"; |
627 | } |
628 | } |
629 | |
630 | bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) { |
631 | if (Token.isNot(TokenKind)) |
632 | return error(Twine("expected ") + toString(TokenKind)); |
633 | lex(); |
634 | return false; |
635 | } |
636 | |
637 | bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) { |
638 | if (Token.isNot(TokenKind)) |
639 | return false; |
640 | lex(); |
641 | return true; |
642 | } |
643 | |
644 | |
645 | bool MIParser::parseSectionID(Optional<MBBSectionID> &SID) { |
646 | assert(Token.is(MIToken::kw_bbsections)); |
647 | lex(); |
648 | if (Token.is(MIToken::IntegerLiteral)) { |
649 | unsigned Value = 0; |
650 | if (getUnsigned(Value)) |
651 | return error("Unknown Section ID"); |
652 | SID = MBBSectionID{Value}; |
653 | } else { |
654 | const StringRef &S = Token.stringValue(); |
655 | if (S == "Exception") |
656 | SID = MBBSectionID::ExceptionSectionID; |
657 | else if (S == "Cold") |
658 | SID = MBBSectionID::ColdSectionID; |
659 | else |
660 | return error("Unknown Section ID"); |
661 | } |
662 | lex(); |
663 | return false; |
664 | } |
665 | |
666 | bool MIParser::parseBasicBlockDefinition( |
667 | DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { |
668 | assert(Token.is(MIToken::MachineBasicBlockLabel)); |
669 | unsigned ID = 0; |
670 | if (getUnsigned(ID)) |
671 | return true; |
672 | auto Loc = Token.location(); |
673 | auto Name = Token.stringValue(); |
674 | lex(); |
675 | bool HasAddressTaken = false; |
676 | bool IsLandingPad = false; |
677 | bool IsEHFuncletEntry = false; |
678 | Optional<MBBSectionID> SectionID; |
679 | unsigned Alignment = 0; |
680 | BasicBlock *BB = nullptr; |
681 | if (consumeIfPresent(MIToken::lparen)) { |
682 | do { |
683 | |
684 | switch (Token.kind()) { |
685 | case MIToken::kw_address_taken: |
686 | HasAddressTaken = true; |
687 | lex(); |
688 | break; |
689 | case MIToken::kw_landing_pad: |
690 | IsLandingPad = true; |
691 | lex(); |
692 | break; |
693 | case MIToken::kw_ehfunclet_entry: |
694 | IsEHFuncletEntry = true; |
695 | lex(); |
696 | break; |
697 | case MIToken::kw_align: |
698 | if (parseAlignment(Alignment)) |
699 | return true; |
700 | break; |
701 | case MIToken::IRBlock: |
702 | |
703 | if (parseIRBlock(BB, MF.getFunction())) |
704 | return true; |
705 | lex(); |
706 | break; |
707 | case MIToken::kw_bbsections: |
708 | if (parseSectionID(SectionID)) |
709 | return true; |
710 | break; |
711 | default: |
712 | break; |
713 | } |
714 | } while (consumeIfPresent(MIToken::comma)); |
715 | if (expectAndConsume(MIToken::rparen)) |
716 | return true; |
717 | } |
718 | if (expectAndConsume(MIToken::colon)) |
719 | return true; |
720 | |
721 | if (!Name.empty()) { |
722 | BB = dyn_cast_or_null<BasicBlock>( |
723 | MF.getFunction().getValueSymbolTable()->lookup(Name)); |
724 | if (!BB) |
725 | return error(Loc, Twine("basic block '") + Name + |
726 | "' is not defined in the function '" + |
727 | MF.getName() + "'"); |
728 | } |
729 | auto *MBB = MF.CreateMachineBasicBlock(BB); |
730 | MF.insert(MF.end(), MBB); |
731 | bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second; |
732 | if (!WasInserted) |
733 | return error(Loc, Twine("redefinition of machine basic block with id #") + |
734 | Twine(ID)); |
735 | if (Alignment) |
736 | MBB->setAlignment(Align(Alignment)); |
737 | if (HasAddressTaken) |
738 | MBB->setHasAddressTaken(); |
739 | MBB->setIsEHPad(IsLandingPad); |
740 | MBB->setIsEHFuncletEntry(IsEHFuncletEntry); |
741 | if (SectionID.hasValue()) { |
742 | MBB->setSectionID(SectionID.getValue()); |
743 | MF.setBBSectionsType(BasicBlockSection::List); |
744 | } |
745 | return false; |
746 | } |
747 | |
748 | bool MIParser::parseBasicBlockDefinitions( |
749 | DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { |
750 | lex(); |
751 | |
752 | while (Token.is(MIToken::Newline)) |
753 | lex(); |
754 | if (Token.isErrorOrEOF()) |
755 | return Token.isError(); |
756 | if (Token.isNot(MIToken::MachineBasicBlockLabel)) |
757 | return error("expected a basic block definition before instructions"); |
758 | unsigned BraceDepth = 0; |
759 | do { |
760 | if (parseBasicBlockDefinition(MBBSlots)) |
761 | return true; |
762 | bool IsAfterNewline = false; |
763 | |
764 | while (true) { |
765 | if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) || |
766 | Token.isErrorOrEOF()) |
767 | break; |
768 | else if (Token.is(MIToken::MachineBasicBlockLabel)) |
769 | return error("basic block definition should be located at the start of " |
770 | "the line"); |
771 | else if (consumeIfPresent(MIToken::Newline)) { |
772 | IsAfterNewline = true; |
773 | continue; |
774 | } |
775 | IsAfterNewline = false; |
776 | if (Token.is(MIToken::lbrace)) |
777 | ++BraceDepth; |
778 | if (Token.is(MIToken::rbrace)) { |
779 | if (!BraceDepth) |
780 | return error("extraneous closing brace ('}')"); |
781 | --BraceDepth; |
782 | } |
783 | lex(); |
784 | } |
785 | |
786 | if (!Token.isError() && BraceDepth) |
787 | return error("expected '}'"); |
788 | } while (!Token.isErrorOrEOF()); |
789 | return Token.isError(); |
790 | } |
791 | |
792 | bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) { |
793 | assert(Token.is(MIToken::kw_liveins)); |
794 | lex(); |
795 | if (expectAndConsume(MIToken::colon)) |
796 | return true; |
797 | if (Token.isNewlineOrEOF()) |
798 | return false; |
799 | do { |
800 | if (Token.isNot(MIToken::NamedRegister)) |
801 | return error("expected a named register"); |
802 | Register Reg; |
803 | if (parseNamedRegister(Reg)) |
804 | return true; |
805 | lex(); |
806 | LaneBitmask Mask = LaneBitmask::getAll(); |
807 | if (consumeIfPresent(MIToken::colon)) { |
808 | |
809 | if (Token.isNot(MIToken::IntegerLiteral) && |
810 | Token.isNot(MIToken::HexLiteral)) |
811 | return error("expected a lane mask"); |
812 | static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t), |
813 | "Use correct get-function for lane mask"); |
814 | LaneBitmask::Type V; |
815 | if (getUint64(V)) |
816 | return error("invalid lane mask value"); |
817 | Mask = LaneBitmask(V); |
818 | lex(); |
819 | } |
820 | MBB.addLiveIn(Reg, Mask); |
821 | } while (consumeIfPresent(MIToken::comma)); |
822 | return false; |
823 | } |
824 | |
825 | bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) { |
826 | assert(Token.is(MIToken::kw_successors)); |
827 | lex(); |
828 | if (expectAndConsume(MIToken::colon)) |
829 | return true; |
830 | if (Token.isNewlineOrEOF()) |
831 | return false; |
832 | do { |
833 | if (Token.isNot(MIToken::MachineBasicBlock)) |
834 | return error("expected a machine basic block reference"); |
835 | MachineBasicBlock *SuccMBB = nullptr; |
836 | if (parseMBBReference(SuccMBB)) |
837 | return true; |
838 | lex(); |
839 | unsigned Weight = 0; |
840 | if (consumeIfPresent(MIToken::lparen)) { |
841 | if (Token.isNot(MIToken::IntegerLiteral) && |
842 | Token.isNot(MIToken::HexLiteral)) |
843 | return error("expected an integer literal after '('"); |
844 | if (getUnsigned(Weight)) |
845 | return true; |
846 | lex(); |
847 | if (expectAndConsume(MIToken::rparen)) |
848 | return true; |
849 | } |
850 | MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight)); |
851 | } while (consumeIfPresent(MIToken::comma)); |
852 | MBB.normalizeSuccProbs(); |
853 | return false; |
854 | } |
855 | |
856 | bool MIParser::parseBasicBlock(MachineBasicBlock &MBB, |
857 | MachineBasicBlock *&AddFalthroughFrom) { |
858 | |
859 | assert(Token.is(MIToken::MachineBasicBlockLabel)); |
860 | lex(); |
861 | if (consumeIfPresent(MIToken::lparen)) { |
862 | while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF()) |
863 | lex(); |
864 | consumeIfPresent(MIToken::rparen); |
865 | } |
866 | consumeIfPresent(MIToken::colon); |
867 | |
868 | |
869 | |
870 | |
871 | |
872 | |
873 | |
874 | |
875 | |
876 | |
877 | bool ExplicitSuccessors = false; |
878 | while (true) { |
879 | if (Token.is(MIToken::kw_successors)) { |
880 | if (parseBasicBlockSuccessors(MBB)) |
881 | return true; |
882 | ExplicitSuccessors = true; |
883 | } else if (Token.is(MIToken::kw_liveins)) { |
884 | if (parseBasicBlockLiveins(MBB)) |
885 | return true; |
886 | } else if (consumeIfPresent(MIToken::Newline)) { |
887 | continue; |
888 | } else |
889 | break; |
890 | if (!Token.isNewlineOrEOF()) |
891 | return error("expected line break at the end of a list"); |
892 | lex(); |
893 | } |
894 | |
895 | |
896 | bool IsInBundle = false; |
897 | MachineInstr *PrevMI = nullptr; |
898 | while (!Token.is(MIToken::MachineBasicBlockLabel) && |
899 | !Token.is(MIToken::Eof)) { |
900 | if (consumeIfPresent(MIToken::Newline)) |
901 | continue; |
902 | if (consumeIfPresent(MIToken::rbrace)) { |
903 | |
904 | |
905 | assert(IsInBundle); |
906 | IsInBundle = false; |
907 | continue; |
908 | } |
909 | MachineInstr *MI = nullptr; |
910 | if (parse(MI)) |
911 | return true; |
912 | MBB.insert(MBB.end(), MI); |
913 | if (IsInBundle) { |
914 | PrevMI->setFlag(MachineInstr::BundledSucc); |
915 | MI->setFlag(MachineInstr::BundledPred); |
916 | } |
917 | PrevMI = MI; |
918 | if (Token.is(MIToken::lbrace)) { |
919 | if (IsInBundle) |
920 | return error("nested instruction bundles are not allowed"); |
921 | lex(); |
922 | |
923 | MI->setFlag(MachineInstr::BundledSucc); |
924 | IsInBundle = true; |
925 | if (!Token.is(MIToken::Newline)) |
926 | |
927 | continue; |
928 | } |
929 | assert(Token.isNewlineOrEOF() && "MI is not fully parsed"); |
930 | lex(); |
931 | } |
932 | |
933 | |
934 | if (!ExplicitSuccessors) { |
935 | SmallVector<MachineBasicBlock*,4> Successors; |
936 | bool IsFallthrough; |
937 | guessSuccessors(MBB, Successors, IsFallthrough); |
938 | for (MachineBasicBlock *Succ : Successors) |
939 | MBB.addSuccessor(Succ); |
940 | |
941 | if (IsFallthrough) { |
942 | AddFalthroughFrom = &MBB; |
943 | } else { |
944 | MBB.normalizeSuccProbs(); |
945 | } |
946 | } |
947 | |
948 | return false; |
949 | } |
950 | |
951 | bool MIParser::parseBasicBlocks() { |
952 | lex(); |
953 | |
954 | while (Token.is(MIToken::Newline)) |
955 | lex(); |
956 | if (Token.isErrorOrEOF()) |
957 | return Token.isError(); |
958 | |
959 | |
960 | assert(Token.is(MIToken::MachineBasicBlockLabel)); |
961 | MachineBasicBlock *AddFalthroughFrom = nullptr; |
962 | do { |
963 | MachineBasicBlock *MBB = nullptr; |
964 | if (parseMBBReference(MBB)) |
965 | return true; |
966 | if (AddFalthroughFrom) { |
967 | if (!AddFalthroughFrom->isSuccessor(MBB)) |
968 | AddFalthroughFrom->addSuccessor(MBB); |
969 | AddFalthroughFrom->normalizeSuccProbs(); |
970 | AddFalthroughFrom = nullptr; |
971 | } |
972 | if (parseBasicBlock(*MBB, AddFalthroughFrom)) |
973 | return true; |
974 | |
975 | |
976 | assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof)); |
977 | } while (Token.isNot(MIToken::Eof)); |
978 | return false; |
979 | } |
980 | |
981 | bool MIParser::parse(MachineInstr *&MI) { |
982 | |
983 | MachineOperand MO = MachineOperand::CreateImm(0); |
984 | SmallVector<ParsedMachineOperand, 8> Operands; |
985 | while (Token.isRegister() || Token.isRegisterFlag()) { |
986 | auto Loc = Token.location(); |
987 | Optional<unsigned> TiedDefIdx; |
988 | if (parseRegisterOperand(MO, TiedDefIdx, true)) |
989 | return true; |
990 | Operands.push_back( |
991 | ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); |
992 | if (Token.isNot(MIToken::comma)) |
993 | break; |
994 | lex(); |
995 | } |
996 | if (!Operands.empty() && expectAndConsume(MIToken::equal)) |
997 | return true; |
998 | |
999 | unsigned OpCode, Flags = 0; |
1000 | if (Token.isError() || parseInstruction(OpCode, Flags)) |
1001 | return true; |
1002 | |
1003 | |
1004 | while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) && |
1005 | Token.isNot(MIToken::kw_post_instr_symbol) && |
1006 | Token.isNot(MIToken::kw_heap_alloc_marker) && |
1007 | Token.isNot(MIToken::kw_debug_location) && |
1008 | Token.isNot(MIToken::kw_debug_instr_number) && |
1009 | Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) { |
1010 | auto Loc = Token.location(); |
1011 | Optional<unsigned> TiedDefIdx; |
1012 | if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx)) |
1013 | return true; |
1014 | if ((OpCode == TargetOpcode::DBG_VALUE || |
1015 | OpCode == TargetOpcode::DBG_VALUE_LIST) && |
1016 | MO.isReg()) |
1017 | MO.setIsDebug(); |
1018 | Operands.push_back( |
1019 | ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); |
1020 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || |
1021 | Token.is(MIToken::lbrace)) |
1022 | break; |
1023 | if (Token.isNot(MIToken::comma)) |
1024 | return error("expected ',' before the next machine operand"); |
1025 | lex(); |
1026 | } |
1027 | |
1028 | MCSymbol *PreInstrSymbol = nullptr; |
1029 | if (Token.is(MIToken::kw_pre_instr_symbol)) |
1030 | if (parsePreOrPostInstrSymbol(PreInstrSymbol)) |
1031 | return true; |
1032 | MCSymbol *PostInstrSymbol = nullptr; |
1033 | if (Token.is(MIToken::kw_post_instr_symbol)) |
1034 | if (parsePreOrPostInstrSymbol(PostInstrSymbol)) |
1035 | return true; |
1036 | MDNode *HeapAllocMarker = nullptr; |
1037 | if (Token.is(MIToken::kw_heap_alloc_marker)) |
1038 | if (parseHeapAllocMarker(HeapAllocMarker)) |
1039 | return true; |
1040 | |
1041 | unsigned InstrNum = 0; |
1042 | if (Token.is(MIToken::kw_debug_instr_number)) { |
1043 | lex(); |
1044 | if (Token.isNot(MIToken::IntegerLiteral)) |
1045 | return error("expected an integer literal after 'debug-instr-number'"); |
1046 | if (getUnsigned(InstrNum)) |
1047 | return true; |
1048 | lex(); |
1049 | |
1050 | if (Token.is(MIToken::comma)) |
1051 | lex(); |
1052 | } |
1053 | |
1054 | DebugLoc DebugLocation; |
1055 | if (Token.is(MIToken::kw_debug_location)) { |
1056 | lex(); |
1057 | MDNode *Node = nullptr; |
1058 | if (Token.is(MIToken::exclaim)) { |
1059 | if (parseMDNode(Node)) |
1060 | return true; |
1061 | } else if (Token.is(MIToken::md_dilocation)) { |
1062 | if (parseDILocation(Node)) |
1063 | return true; |
1064 | } else |
1065 | return error("expected a metadata node after 'debug-location'"); |
1066 | if (!isa<DILocation>(Node)) |
1067 | return error("referenced metadata is not a DILocation"); |
1068 | DebugLocation = DebugLoc(Node); |
1069 | } |
1070 | |
1071 | |
1072 | SmallVector<MachineMemOperand *, 2> MemOperands; |
1073 | if (Token.is(MIToken::coloncolon)) { |
1074 | lex(); |
1075 | while (!Token.isNewlineOrEOF()) { |
1076 | MachineMemOperand *MemOp = nullptr; |
1077 | if (parseMachineMemoryOperand(MemOp)) |
1078 | return true; |
1079 | MemOperands.push_back(MemOp); |
1080 | if (Token.isNewlineOrEOF()) |
1081 | break; |
1082 | if (Token.isNot(MIToken::comma)) |
1083 | return error("expected ',' before the next machine memory operand"); |
1084 | lex(); |
1085 | } |
1086 | } |
1087 | |
1088 | const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); |
1089 | if (!MCID.isVariadic()) { |
1090 | |
1091 | if (verifyImplicitOperands(Operands, MCID)) |
1092 | return true; |
1093 | } |
1094 | |
1095 | |
1096 | MI = MF.CreateMachineInstr(MCID, DebugLocation, true); |
1097 | MI->setFlags(Flags); |
1098 | for (const auto &Operand : Operands) |
1099 | MI->addOperand(MF, Operand.Operand); |
1100 | if (assignRegisterTies(*MI, Operands)) |
1101 | return true; |
1102 | if (PreInstrSymbol) |
1103 | MI->setPreInstrSymbol(MF, PreInstrSymbol); |
1104 | if (PostInstrSymbol) |
1105 | MI->setPostInstrSymbol(MF, PostInstrSymbol); |
1106 | if (HeapAllocMarker) |
1107 | MI->setHeapAllocMarker(MF, HeapAllocMarker); |
1108 | if (!MemOperands.empty()) |
1109 | MI->setMemRefs(MF, MemOperands); |
1110 | if (InstrNum) |
1111 | MI->setDebugInstrNum(InstrNum); |
1112 | return false; |
1113 | } |
1114 | |
1115 | bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) { |
1116 | lex(); |
1117 | if (Token.isNot(MIToken::MachineBasicBlock)) |
1118 | return error("expected a machine basic block reference"); |
1119 | if (parseMBBReference(MBB)) |
1120 | return true; |
1121 | lex(); |
1122 | if (Token.isNot(MIToken::Eof)) |
1123 | return error( |
1124 | "expected end of string after the machine basic block reference"); |
1125 | return false; |
1126 | } |
1127 | |
1128 | bool MIParser::parseStandaloneNamedRegister(Register &Reg) { |
1129 | lex(); |
1130 | if (Token.isNot(MIToken::NamedRegister)) |
1131 | return error("expected a named register"); |
1132 | if (parseNamedRegister(Reg)) |
1133 | return true; |
1134 | lex(); |
1135 | if (Token.isNot(MIToken::Eof)) |
1136 | return error("expected end of string after the register reference"); |
1137 | return false; |
1138 | } |
1139 | |
1140 | bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) { |
1141 | lex(); |
1142 | if (Token.isNot(MIToken::VirtualRegister)) |
1143 | return error("expected a virtual register"); |
1144 | if (parseVirtualRegister(Info)) |
1145 | return true; |
1146 | lex(); |
1147 | if (Token.isNot(MIToken::Eof)) |
1148 | return error("expected end of string after the register reference"); |
1149 | return false; |
1150 | } |
1151 | |
1152 | bool MIParser::parseStandaloneRegister(Register &Reg) { |
1153 | lex(); |
1154 | if (Token.isNot(MIToken::NamedRegister) && |
1155 | Token.isNot(MIToken::VirtualRegister)) |
1156 | return error("expected either a named or virtual register"); |
1157 | |
1158 | VRegInfo *Info; |
1159 | if (parseRegister(Reg, Info)) |
1160 | return true; |
1161 | |
1162 | lex(); |
1163 | if (Token.isNot(MIToken::Eof)) |
1164 | return error("expected end of string after the register reference"); |
1165 | return false; |
1166 | } |
1167 | |
1168 | bool MIParser::parseStandaloneStackObject(int &FI) { |
1169 | lex(); |
1170 | if (Token.isNot(MIToken::StackObject)) |
1171 | return error("expected a stack object"); |
1172 | if (parseStackFrameIndex(FI)) |
1173 | return true; |
1174 | if (Token.isNot(MIToken::Eof)) |
1175 | return error("expected end of string after the stack object reference"); |
1176 | return false; |
1177 | } |
1178 | |
1179 | bool MIParser::parseStandaloneMDNode(MDNode *&Node) { |
1180 | lex(); |
1181 | if (Token.is(MIToken::exclaim)) { |
1182 | if (parseMDNode(Node)) |
1183 | return true; |
1184 | } else if (Token.is(MIToken::md_diexpr)) { |
1185 | if (parseDIExpression(Node)) |
1186 | return true; |
1187 | } else if (Token.is(MIToken::md_dilocation)) { |
1188 | if (parseDILocation(Node)) |
1189 | return true; |
1190 | } else |
1191 | return error("expected a metadata node"); |
1192 | if (Token.isNot(MIToken::Eof)) |
1193 | return error("expected end of string after the metadata node"); |
1194 | return false; |
1195 | } |
1196 | |
1197 | bool MIParser::parseMachineMetadata() { |
1198 | lex(); |
1199 | if (Token.isNot(MIToken::exclaim)) |
1200 | return error("expected a metadata node"); |
1201 | |
1202 | lex(); |
1203 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) |
1204 | return error("expected metadata id after '!'"); |
1205 | unsigned ID = 0; |
1206 | if (getUnsigned(ID)) |
1207 | return true; |
1208 | lex(); |
1209 | if (expectAndConsume(MIToken::equal)) |
1210 | return true; |
1211 | bool IsDistinct = Token.is(MIToken::kw_distinct); |
1212 | if (IsDistinct) |
1213 | lex(); |
1214 | if (Token.isNot(MIToken::exclaim)) |
1215 | return error("expected a metadata node"); |
1216 | lex(); |
1217 | |
1218 | MDNode *MD; |
1219 | if (parseMDTuple(MD, IsDistinct)) |
1220 | return true; |
1221 | |
1222 | auto FI = PFS.MachineForwardRefMDNodes.find(ID); |
1223 | if (FI != PFS.MachineForwardRefMDNodes.end()) { |
1224 | FI->second.first->replaceAllUsesWith(MD); |
1225 | PFS.MachineForwardRefMDNodes.erase(FI); |
1226 | |
1227 | assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work"); |
1228 | } else { |
1229 | if (PFS.MachineMetadataNodes.count(ID)) |
1230 | return error("Metadata id is already used"); |
1231 | PFS.MachineMetadataNodes[ID].reset(MD); |
1232 | } |
1233 | |
1234 | return false; |
1235 | } |
1236 | |
1237 | bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) { |
1238 | SmallVector<Metadata *, 16> Elts; |
1239 | if (parseMDNodeVector(Elts)) |
1240 | return true; |
1241 | MD = (IsDistinct ? MDTuple::getDistinct |
1242 | : MDTuple::get)(MF.getFunction().getContext(), Elts); |
1243 | return false; |
1244 | } |
1245 | |
1246 | bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) { |
1247 | if (Token.isNot(MIToken::lbrace)) |
1248 | return error("expected '{' here"); |
1249 | lex(); |
1250 | |
1251 | if (Token.is(MIToken::rbrace)) { |
1252 | lex(); |
1253 | return false; |
1254 | } |
1255 | |
1256 | do { |
1257 | Metadata *MD; |
1258 | if (parseMetadata(MD)) |
1259 | return true; |
1260 | |
1261 | Elts.push_back(MD); |
1262 | |
1263 | if (Token.isNot(MIToken::comma)) |
1264 | break; |
1265 | lex(); |
1266 | } while (true); |
1267 | |
1268 | if (Token.isNot(MIToken::rbrace)) |
1269 | return error("expected end of metadata node"); |
1270 | lex(); |
1271 | |
1272 | return false; |
1273 | } |
1274 | |
1275 | |
1276 | |
1277 | bool MIParser::parseMetadata(Metadata *&MD) { |
1278 | if (Token.isNot(MIToken::exclaim)) |
1279 | return error("expected '!' here"); |
1280 | lex(); |
1281 | |
1282 | if (Token.is(MIToken::StringConstant)) { |
1283 | std::string Str; |
1284 | if (parseStringConstant(Str)) |
1285 | return true; |
1286 | MD = MDString::get(MF.getFunction().getContext(), Str); |
1287 | return false; |
1288 | } |
1289 | |
1290 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) |
1291 | return error("expected metadata id after '!'"); |
1292 | |
1293 | SMLoc Loc = mapSMLoc(Token.location()); |
1294 | |
1295 | unsigned ID = 0; |
1296 | if (getUnsigned(ID)) |
1297 | return true; |
1298 | lex(); |
1299 | |
1300 | auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID); |
1301 | if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) { |
1302 | MD = NodeInfo->second.get(); |
1303 | return false; |
1304 | } |
1305 | |
1306 | NodeInfo = PFS.MachineMetadataNodes.find(ID); |
1307 | if (NodeInfo != PFS.MachineMetadataNodes.end()) { |
1308 | MD = NodeInfo->second.get(); |
1309 | return false; |
1310 | } |
1311 | |
1312 | auto &FwdRef = PFS.MachineForwardRefMDNodes[ID]; |
1313 | FwdRef = std::make_pair( |
1314 | MDTuple::getTemporary(MF.getFunction().getContext(), None), Loc); |
1315 | PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get()); |
1316 | MD = FwdRef.first.get(); |
1317 | |
1318 | return false; |
1319 | } |
1320 | |
1321 | static const char *printImplicitRegisterFlag(const MachineOperand &MO) { |
1322 | assert(MO.isImplicit()); |
1323 | return MO.isDef() ? "implicit-def" : "implicit"; |
1324 | } |
1325 | |
1326 | static std::string getRegisterName(const TargetRegisterInfo *TRI, |
1327 | Register Reg) { |
1328 | assert(Register::isPhysicalRegister(Reg) && "expected phys reg"); |
1329 | return StringRef(TRI->getName(Reg)).lower(); |
1330 | } |
1331 | |
1332 | |
1333 | static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand, |
1334 | ArrayRef<ParsedMachineOperand> Operands) { |
1335 | for (const auto &I : Operands) { |
1336 | if (ImplicitOperand.isIdenticalTo(I.Operand)) |
1337 | return true; |
1338 | } |
1339 | return false; |
1340 | } |
1341 | |
1342 | bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, |
1343 | const MCInstrDesc &MCID) { |
1344 | if (MCID.isCall()) |
1345 | |
1346 | |
1347 | return false; |
1348 | |
1349 | |
1350 | SmallVector<MachineOperand, 4> ImplicitOperands; |
1351 | if (MCID.ImplicitDefs) |
1352 | for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) |
1353 | ImplicitOperands.push_back( |
1354 | MachineOperand::CreateReg(*ImpDefs, true, true)); |
1355 | if (MCID.ImplicitUses) |
1356 | for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) |
1357 | ImplicitOperands.push_back( |
1358 | MachineOperand::CreateReg(*ImpUses, false, true)); |
1359 | |
1360 | const auto *TRI = MF.getSubtarget().getRegisterInfo(); |
1361 | assert(TRI && "Expected target register info"); |
1362 | for (const auto &I : ImplicitOperands) { |
1363 | if (isImplicitOperandIn(I, Operands)) |
1364 | continue; |
1365 | return error(Operands.empty() ? Token.location() : Operands.back().End, |
1366 | Twine("missing implicit register operand '") + |
1367 | printImplicitRegisterFlag(I) + " $" + |
1368 | getRegisterName(TRI, I.getReg()) + "'"); |
1369 | } |
1370 | return false; |
1371 | } |
1372 | |
1373 | bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { |
1374 | |
1375 | while (Token.is(MIToken::kw_frame_setup) || |
1376 | Token.is(MIToken::kw_frame_destroy) || |
1377 | Token.is(MIToken::kw_nnan) || |
1378 | Token.is(MIToken::kw_ninf) || |
1379 | Token.is(MIToken::kw_nsz) || |
1380 | Token.is(MIToken::kw_arcp) || |
1381 | Token.is(MIToken::kw_contract) || |
1382 | Token.is(MIToken::kw_afn) || |
1383 | Token.is(MIToken::kw_reassoc) || |
1384 | Token.is(MIToken::kw_nuw) || |
1385 | Token.is(MIToken::kw_nsw) || |
1386 | Token.is(MIToken::kw_exact) || |
1387 | Token.is(MIToken::kw_nofpexcept)) { |
1388 | |
1389 | if (Token.is(MIToken::kw_frame_setup)) |
1390 | Flags |= MachineInstr::FrameSetup; |
1391 | if (Token.is(MIToken::kw_frame_destroy)) |
1392 | Flags |= MachineInstr::FrameDestroy; |
1393 | if (Token.is(MIToken::kw_nnan)) |
1394 | Flags |= MachineInstr::FmNoNans; |
1395 | if (Token.is(MIToken::kw_ninf)) |
1396 | Flags |= MachineInstr::FmNoInfs; |
1397 | if (Token.is(MIToken::kw_nsz)) |
1398 | Flags |= MachineInstr::FmNsz; |
1399 | if (Token.is(MIToken::kw_arcp)) |
1400 | Flags |= MachineInstr::FmArcp; |
1401 | if (Token.is(MIToken::kw_contract)) |
1402 | Flags |= MachineInstr::FmContract; |
1403 | if (Token.is(MIToken::kw_afn)) |
1404 | Flags |= MachineInstr::FmAfn; |
1405 | if (Token.is(MIToken::kw_reassoc)) |
1406 | Flags |= MachineInstr::FmReassoc; |
1407 | if (Token.is(MIToken::kw_nuw)) |
1408 | Flags |= MachineInstr::NoUWrap; |
1409 | if (Token.is(MIToken::kw_nsw)) |
1410 | Flags |= MachineInstr::NoSWrap; |
1411 | if (Token.is(MIToken::kw_exact)) |
1412 | Flags |= MachineInstr::IsExact; |
1413 | if (Token.is(MIToken::kw_nofpexcept)) |
1414 | Flags |= MachineInstr::NoFPExcept; |
1415 | |
1416 | lex(); |
1417 | } |
1418 | if (Token.isNot(MIToken::Identifier)) |
1419 | return error("expected a machine instruction"); |
1420 | StringRef InstrName = Token.stringValue(); |
1421 | if (PFS.Target.parseInstrName(InstrName, OpCode)) |
1422 | return error(Twine("unknown machine instruction name '") + InstrName + "'"); |
1423 | lex(); |
1424 | return false; |
1425 | } |
1426 | |
1427 | bool MIParser::parseNamedRegister(Register &Reg) { |
1428 | assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token"); |
1429 | StringRef Name = Token.stringValue(); |
1430 | if (PFS.Target.getRegisterByName(Name, Reg)) |
1431 | return error(Twine("unknown register name '") + Name + "'"); |
1432 | return false; |
1433 | } |
1434 | |
1435 | bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) { |
1436 | assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token"); |
1437 | StringRef Name = Token.stringValue(); |
1438 | |
1439 | |
1440 | Info = &PFS.getVRegInfoNamed(Name); |
1441 | return false; |
1442 | } |
1443 | |
1444 | bool MIParser::parseVirtualRegister(VRegInfo *&Info) { |
1445 | if (Token.is(MIToken::NamedVirtualRegister)) |
1446 | return parseNamedVirtualRegister(Info); |
1447 | assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token"); |
1448 | unsigned ID; |
1449 | if (getUnsigned(ID)) |
1450 | return true; |
1451 | Info = &PFS.getVRegInfo(ID); |
1452 | return false; |
1453 | } |
1454 | |
1455 | bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) { |
1456 | switch (Token.kind()) { |
1457 | case MIToken::underscore: |
1458 | Reg = 0; |
1459 | return false; |
1460 | case MIToken::NamedRegister: |
1461 | return parseNamedRegister(Reg); |
1462 | case MIToken::NamedVirtualRegister: |
1463 | case MIToken::VirtualRegister: |
1464 | if (parseVirtualRegister(Info)) |
1465 | return true; |
1466 | Reg = Info->VReg; |
1467 | return false; |
1468 | |
1469 | default: |
1470 | llvm_unreachable("The current token should be a register"); |
1471 | } |
1472 | } |
1473 | |
1474 | bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) { |
1475 | if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore)) |
1476 | return error("expected '_', register class, or register bank name"); |
1477 | StringRef::iterator Loc = Token.location(); |
1478 | StringRef Name = Token.stringValue(); |
1479 | |
1480 | |
1481 | const TargetRegisterClass *RC = PFS.Target.getRegClass(Name); |
1482 | if (RC) { |
1483 | lex(); |
1484 | |
1485 | switch (RegInfo.Kind) { |
1486 | case VRegInfo::UNKNOWN: |
1487 | case VRegInfo::NORMAL: |
1488 | RegInfo.Kind = VRegInfo::NORMAL; |
1489 | if (RegInfo.Explicit && RegInfo.D.RC != RC) { |
1490 | const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); |
1491 | return error(Loc, Twine("conflicting register classes, previously: ") + |
1492 | Twine(TRI.getRegClassName(RegInfo.D.RC))); |
1493 | } |
1494 | RegInfo.D.RC = RC; |
1495 | RegInfo.Explicit = true; |
1496 | return false; |
1497 | |
1498 | case VRegInfo::GENERIC: |
1499 | case VRegInfo::REGBANK: |
1500 | return error(Loc, "register class specification on generic register"); |
1501 | } |
1502 | llvm_unreachable("Unexpected register kind"); |
1503 | } |
1504 | |
1505 | |
1506 | const RegisterBank *RegBank = nullptr; |
1507 | if (Name != "_") { |
1508 | RegBank = PFS.Target.getRegBank(Name); |
1509 | if (!RegBank) |
1510 | return error(Loc, "expected '_', register class, or register bank name"); |
1511 | } |
1512 | |
1513 | lex(); |
1514 | |
1515 | switch (RegInfo.Kind) { |
1516 | case VRegInfo::UNKNOWN: |
1517 | case VRegInfo::GENERIC: |
1518 | case VRegInfo::REGBANK: |
1519 | RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC; |
1520 | if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank) |
1521 | return error(Loc, "conflicting generic register banks"); |
1522 | RegInfo.D.RegBank = RegBank; |
1523 | RegInfo.Explicit = true; |
1524 | return false; |
1525 | |
1526 | case VRegInfo::NORMAL: |
1527 | return error(Loc, "register bank specification on normal register"); |
1528 | } |
1529 | llvm_unreachable("Unexpected register kind"); |
1530 | } |
1531 | |
1532 | bool MIParser::parseRegisterFlag(unsigned &Flags) { |
1533 | const unsigned OldFlags = Flags; |
1534 | switch (Token.kind()) { |
1535 | case MIToken::kw_implicit: |
1536 | Flags |= RegState::Implicit; |
1537 | break; |
1538 | case MIToken::kw_implicit_define: |
1539 | Flags |= RegState::ImplicitDefine; |
1540 | break; |
1541 | case MIToken::kw_def: |
1542 | Flags |= RegState::Define; |
1543 | break; |
1544 | case MIToken::kw_dead: |
1545 | Flags |= RegState::Dead; |
1546 | break; |
1547 | case MIToken::kw_killed: |
1548 | Flags |= RegState::Kill; |
1549 | break; |
1550 | case MIToken::kw_undef: |
1551 | Flags |= RegState::Undef; |
1552 | break; |
1553 | case MIToken::kw_internal: |
1554 | Flags |= RegState::InternalRead; |
1555 | break; |
1556 | case MIToken::kw_early_clobber: |
1557 | Flags |= RegState::EarlyClobber; |
1558 | break; |
1559 | case MIToken::kw_debug_use: |
1560 | Flags |= RegState::Debug; |
1561 | break; |
1562 | case MIToken::kw_renamable: |
1563 | Flags |= RegState::Renamable; |
1564 | break; |
1565 | default: |
1566 | llvm_unreachable("The current token should be a register flag"); |
1567 | } |
1568 | if (OldFlags == Flags) |
1569 | |
1570 | |
1571 | return error("duplicate '" + Token.stringValue() + "' register flag"); |
1572 | lex(); |
1573 | return false; |
1574 | } |
1575 | |
1576 | bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { |
1577 | assert(Token.is(MIToken::dot)); |
1578 | lex(); |
1579 | if (Token.isNot(MIToken::Identifier)) |
1580 | return error("expected a subregister index after '.'"); |
1581 | auto Name = Token.stringValue(); |
1582 | SubReg = PFS.Target.getSubRegIndex(Name); |
1583 | if (!SubReg) |
1584 | return error(Twine("use of unknown subregister index '") + Name + "'"); |
1585 | lex(); |
1586 | return false; |
1587 | } |
1588 | |
1589 | bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { |
1590 | if (!consumeIfPresent(MIToken::kw_tied_def)) |
1591 | return true; |
1592 | if (Token.isNot(MIToken::IntegerLiteral)) |
1593 | return error("expected an integer literal after 'tied-def'"); |
1594 | if (getUnsigned(TiedDefIdx)) |
1595 | return true; |
1596 | lex(); |
1597 | if (expectAndConsume(MIToken::rparen)) |
1598 | return true; |
1599 | return false; |
1600 | } |
1601 | |
1602 | bool MIParser::assignRegisterTies(MachineInstr &MI, |
1603 | ArrayRef<ParsedMachineOperand> Operands) { |
1604 | SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs; |
1605 | for (unsigned I = 0, E = Operands.size(); I != E; ++I) { |
1606 | if (!Operands[I].TiedDefIdx) |
1607 | continue; |
1608 | |
1609 | |
1610 | unsigned DefIdx = Operands[I].TiedDefIdx.getValue(); |
1611 | if (DefIdx >= E) |
1612 | return error(Operands[I].Begin, |
1613 | Twine("use of invalid tied-def operand index '" + |
1614 | Twine(DefIdx) + "'; instruction has only ") + |
1615 | Twine(E) + " operands"); |
1616 | const auto &DefOperand = Operands[DefIdx].Operand; |
1617 | if (!DefOperand.isReg() || !DefOperand.isDef()) |
1618 | |
1619 | return error(Operands[I].Begin, |
1620 | Twine("use of invalid tied-def operand index '") + |
1621 | Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) + |
1622 | " isn't a defined register"); |
1623 | |
1624 | for (const auto &TiedPair : TiedRegisterPairs) { |
1625 | if (TiedPair.first == DefIdx) |
1626 | return error(Operands[I].Begin, |
1627 | Twine("the tied-def operand #") + Twine(DefIdx) + |
1628 | " is already tied with another register operand"); |
1629 | } |
1630 | TiedRegisterPairs.push_back(std::make_pair(DefIdx, I)); |
1631 | } |
1632 | |
1633 | |
1634 | for (const auto &TiedPair : TiedRegisterPairs) |
1635 | MI.tieOperands(TiedPair.first, TiedPair.second); |
1636 | return false; |
1637 | } |
1638 | |
1639 | bool MIParser::parseRegisterOperand(MachineOperand &Dest, |
1640 | Optional<unsigned> &TiedDefIdx, |
1641 | bool IsDef) { |
1642 | unsigned Flags = IsDef ? RegState::Define : 0; |
1643 | while (Token.isRegisterFlag()) { |
1644 | if (parseRegisterFlag(Flags)) |
1645 | return true; |
1646 | } |
1647 | if (!Token.isRegister()) |
1648 | return error("expected a register after register flags"); |
1649 | Register Reg; |
1650 | VRegInfo *RegInfo; |
1651 | if (parseRegister(Reg, RegInfo)) |
1652 | return true; |
1653 | lex(); |
1654 | unsigned SubReg = 0; |
1655 | if (Token.is(MIToken::dot)) { |
1656 | if (parseSubRegisterIndex(SubReg)) |
1657 | return true; |
1658 | if (!Register::isVirtualRegister(Reg)) |
1659 | return error("subregister index expects a virtual register"); |
1660 | } |
1661 | if (Token.is(MIToken::colon)) { |
1662 | if (!Register::isVirtualRegister(Reg)) |
1663 | return error("register class specification expects a virtual register"); |
1664 | lex(); |
1665 | if (parseRegisterClassOrBank(*RegInfo)) |
1666 | return true; |
1667 | } |
1668 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
1669 | if ((Flags & RegState::Define) == 0) { |
1670 | if (consumeIfPresent(MIToken::lparen)) { |
1671 | unsigned Idx; |
1672 | if (!parseRegisterTiedDefIndex(Idx)) |
1673 | TiedDefIdx = Idx; |
1674 | else { |
1675 | |
1676 | LLT Ty; |
1677 | if (parseLowLevelType(Token.location(), Ty)) |
1678 | return error("expected tied-def or low-level type after '('"); |
1679 | |
1680 | if (expectAndConsume(MIToken::rparen)) |
1681 | return true; |
1682 | |
1683 | if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) |
1684 | return error("inconsistent type for generic virtual register"); |
1685 | |
1686 | MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr)); |
1687 | MRI.setType(Reg, Ty); |
1688 | } |
1689 | } |
1690 | } else if (consumeIfPresent(MIToken::lparen)) { |
1691 | |
1692 | if (!Register::isVirtualRegister(Reg)) |
1693 | return error("unexpected type on physical register"); |
1694 | |
1695 | LLT Ty; |
1696 | if (parseLowLevelType(Token.location(), Ty)) |
1697 | return true; |
1698 | |
1699 | if (expectAndConsume(MIToken::rparen)) |
1700 | return true; |
1701 | |
1702 | if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) |
1703 | return error("inconsistent type for generic virtual register"); |
1704 | |
1705 | MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr)); |
1706 | MRI.setType(Reg, Ty); |
1707 | } else if (Register::isVirtualRegister(Reg)) { |
1708 | |
1709 | |
1710 | |
1711 | if (RegInfo->Kind == VRegInfo::GENERIC || |
1712 | RegInfo->Kind == VRegInfo::REGBANK) |
1713 | return error("generic virtual registers must have a type"); |
1714 | } |
1715 | Dest = MachineOperand::CreateReg( |
1716 | Reg, Flags & RegState::Define, Flags & RegState::Implicit, |
1717 | Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef, |
1718 | Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug, |
1719 | Flags & RegState::InternalRead, Flags & RegState::Renamable); |
1720 | |
1721 | return false; |
1722 | } |
1723 | |
1724 | bool MIParser::parseImmediateOperand(MachineOperand &Dest) { |
1725 | assert(Token.is(MIToken::IntegerLiteral)); |
1726 | const APSInt &Int = Token.integerValue(); |
1727 | if (Int.getMinSignedBits() > 64) |
1728 | return error("integer literal is too large to be an immediate operand"); |
1729 | Dest = MachineOperand::CreateImm(Int.getExtValue()); |
1730 | lex(); |
1731 | return false; |
1732 | } |
1733 | |
1734 | bool MIParser::parseTargetImmMnemonic(const unsigned OpCode, |
1735 | const unsigned OpIdx, |
1736 | MachineOperand &Dest, |
1737 | const MIRFormatter &MF) { |
1738 | assert(Token.is(MIToken::dot)); |
1739 | auto Loc = Token.location(); |
1740 | size_t Len = 1; |
1741 | lex(); |
1742 | |
1743 | |
1744 | if (Token.is(MIToken::IntegerLiteral)) { |
1745 | Len += Token.range().size(); |
1746 | lex(); |
1747 | } |
1748 | |
1749 | StringRef Src; |
1750 | if (Token.is(MIToken::comma)) |
1751 | Src = StringRef(Loc, Len); |
1752 | else { |
1753 | assert(Token.is(MIToken::Identifier)); |
1754 | Src = StringRef(Loc, Len + Token.stringValue().size()); |
1755 | } |
1756 | int64_t Val; |
1757 | if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val, |
1758 | [this](StringRef::iterator Loc, const Twine &Msg) |
1759 | -> bool { return error(Loc, Msg); })) |
1760 | return true; |
1761 | |
1762 | Dest = MachineOperand::CreateImm(Val); |
1763 | if (!Token.is(MIToken::comma)) |
1764 | lex(); |
1765 | return false; |
1766 | } |
1767 | |
1768 | static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, |
1769 | PerFunctionMIParsingState &PFS, const Constant *&C, |
1770 | ErrorCallbackType ErrCB) { |
1771 | auto Source = StringValue.str(); |
1772 | SMDiagnostic Err; |
1773 | C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(), |
1774 | &PFS.IRSlots); |
1775 | if (!C) |
1776 | return ErrCB(Loc + Err.getColumnNo(), Err.getMessage()); |
1777 | return false; |
1778 | } |
1779 | |
1780 | bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue, |
1781 | const Constant *&C) { |
1782 | return ::parseIRConstant( |
1783 | Loc, StringValue, PFS, C, |
1784 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { |
1785 | return error(Loc, Msg); |
1786 | }); |
1787 | } |
1788 | |
1789 | bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) { |
1790 | if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C)) |
1791 | return true; |
1792 | lex(); |
1793 | return false; |
1794 | } |
1795 | |
1796 | |
1797 | static bool verifyScalarSize(uint64_t Size) { |
1798 | return Size != 0 && isUInt<16>(Size); |
1799 | } |
1800 | |
1801 | static bool verifyVectorElementCount(uint64_t NumElts) { |
1802 | return NumElts != 0 && isUInt<16>(NumElts); |
1803 | } |
1804 | |
1805 | static bool verifyAddrSpace(uint64_t AddrSpace) { |
1806 | return isUInt<24>(AddrSpace); |
1807 | } |
1808 | |
1809 | bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { |
1810 | if (Token.range().front() == 's' || Token.range().front() == 'p') { |
1811 | StringRef SizeStr = Token.range().drop_front(); |
1812 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) |
1813 | return error("expected integers after 's'/'p' type character"); |
1814 | } |
1815 | |
1816 | if (Token.range().front() == 's') { |
1817 | auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); |
1818 | if (!verifyScalarSize(ScalarSize)) |
1819 | return error("invalid size for scalar type"); |
1820 | |
1821 | Ty = LLT::scalar(ScalarSize); |
1822 | lex(); |
1823 | return false; |
1824 | } else if (Token.range().front() == 'p') { |
1825 | const DataLayout &DL = MF.getDataLayout(); |
1826 | uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); |
1827 | if (!verifyAddrSpace(AS)) |
1828 | return error("invalid address space number"); |
1829 | |
1830 | Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); |
1831 | lex(); |
1832 | return false; |
1833 | } |
1834 | |
1835 | |
1836 | if (Token.isNot(MIToken::less)) |
1837 | return error(Loc, |
1838 | "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type"); |
1839 | lex(); |
1840 | |
1841 | if (Token.isNot(MIToken::IntegerLiteral)) |
1842 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); |
1843 | uint64_t NumElements = Token.integerValue().getZExtValue(); |
1844 | if (!verifyVectorElementCount(NumElements)) |
1845 | return error("invalid number of vector elements"); |
1846 | |
1847 | lex(); |
1848 | |
1849 | if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x") |
1850 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); |
1851 | lex(); |
1852 | |
1853 | if (Token.range().front() != 's' && Token.range().front() != 'p') |
1854 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); |
1855 | StringRef SizeStr = Token.range().drop_front(); |
1856 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) |
1857 | return error("expected integers after 's'/'p' type character"); |
1858 | |
1859 | if (Token.range().front() == 's') { |
1860 | auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); |
1861 | if (!verifyScalarSize(ScalarSize)) |
1862 | return error("invalid size for scalar type"); |
1863 | Ty = LLT::scalar(ScalarSize); |
1864 | } else if (Token.range().front() == 'p') { |
1865 | const DataLayout &DL = MF.getDataLayout(); |
1866 | uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); |
1867 | if (!verifyAddrSpace(AS)) |
1868 | return error("invalid address space number"); |
1869 | |
1870 | Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); |
1871 | } else |
1872 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); |
1873 | lex(); |
1874 | |
1875 | if (Token.isNot(MIToken::greater)) |
1876 | return error(Loc, "expected <M x sN> or <M x pA> for vector type"); |
1877 | lex(); |
1878 | |
1879 | Ty = LLT::fixed_vector(NumElements, Ty); |
1880 | return false; |
1881 | } |
1882 | |
1883 | bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) { |
1884 | assert(Token.is(MIToken::Identifier)); |
1885 | StringRef TypeStr = Token.range(); |
1886 | if (TypeStr.front() != 'i' && TypeStr.front() != 's' && |
1887 | TypeStr.front() != 'p') |
1888 | return error( |
1889 | "a typed immediate operand should start with one of 'i', 's', or 'p'"); |
1890 | StringRef SizeStr = Token.range().drop_front(); |
1891 | if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) |
1892 | return error("expected integers after 'i'/'s'/'p' type character"); |
1893 | |
1894 | auto Loc = Token.location(); |
1895 | lex(); |
1896 | if (Token.isNot(MIToken::IntegerLiteral)) { |
1897 | if (Token.isNot(MIToken::Identifier) || |
1898 | !(Token.range() == "true" || Token.range() == "false")) |
1899 | return error("expected an integer literal"); |
1900 | } |
1901 | const Constant *C = nullptr; |
1902 | if (parseIRConstant(Loc, C)) |
1903 | return true; |
1904 | Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C)); |
1905 | return false; |
1906 | } |
1907 | |
1908 | bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { |
1909 | auto Loc = Token.location(); |
1910 | lex(); |
1911 | if (Token.isNot(MIToken::FloatingPointLiteral) && |
1912 | Token.isNot(MIToken::HexLiteral)) |
1913 | return error("expected a floating point literal"); |
1914 | const Constant *C = nullptr; |
1915 | if (parseIRConstant(Loc, C)) |
1916 | return true; |
1917 | Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C)); |
1918 | return false; |
1919 | } |
1920 | |
1921 | static bool getHexUint(const MIToken &Token, APInt &Result) { |
1922 | assert(Token.is(MIToken::HexLiteral)); |
1923 | StringRef S = Token.range(); |
1924 | assert(S[0] == '0' && tolower(S[1]) == 'x'); |
1925 | |
1926 | if (!isxdigit(S[2])) |
1927 | return true; |
1928 | StringRef V = S.substr(2); |
1929 | APInt A(V.size()*4, V, 16); |
1930 | |
1931 | |
1932 | |
1933 | unsigned NumBits = (A == 0) ? 32 : A.getActiveBits(); |
1934 | Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords())); |
1935 | return false; |
1936 | } |
1937 | |
1938 | static bool getUnsigned(const MIToken &Token, unsigned &Result, |
1939 | ErrorCallbackType ErrCB) { |
1940 | if (Token.hasIntegerValue()) { |
| 10 | | Calling 'MIToken::hasIntegerValue' | |
|
| 12 | | Returning from 'MIToken::hasIntegerValue' | |
|
| |
1941 | const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1; |
1942 | uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); |
1943 | if (Val64 == Limit) |
| |
1944 | return ErrCB(Token.location(), "expected 32-bit integer (too large)"); |
| 15 | | Returning without writing to 'Result' | |
|
| 16 | | Returning value, which participates in a condition later | |
|
1945 | Result = Val64; |
1946 | return false; |
1947 | } |
1948 | if (Token.is(MIToken::HexLiteral)) { |
1949 | APInt A; |
1950 | if (getHexUint(Token, A)) |
1951 | return true; |
1952 | if (A.getBitWidth() > 32) |
1953 | return ErrCB(Token.location(), "expected 32-bit integer (too large)"); |
1954 | Result = A.getZExtValue(); |
1955 | return false; |
1956 | } |
1957 | return true; |
1958 | } |
1959 | |
1960 | bool MIParser::getUnsigned(unsigned &Result) { |
1961 | return ::getUnsigned( |
1962 | Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool { |
1963 | return error(Loc, Msg); |
1964 | }); |
1965 | } |
1966 | |
1967 | bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { |
1968 | assert(Token.is(MIToken::MachineBasicBlock) || |
1969 | Token.is(MIToken::MachineBasicBlockLabel)); |
1970 | unsigned Number; |
1971 | if (getUnsigned(Number)) |
1972 | return true; |
1973 | auto MBBInfo = PFS.MBBSlots.find(Number); |
1974 | if (MBBInfo == PFS.MBBSlots.end()) |
1975 | return error(Twine("use of undefined machine basic block #") + |
1976 | Twine(Number)); |
1977 | MBB = MBBInfo->second; |
1978 | |
1979 | |
1980 | if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName()) |
1981 | return error(Twine("the name of machine basic block #") + Twine(Number) + |
1982 | " isn't '" + Token.stringValue() + "'"); |
1983 | return false; |
1984 | } |
1985 | |
1986 | bool MIParser::parseMBBOperand(MachineOperand &Dest) { |
1987 | MachineBasicBlock *MBB; |
1988 | if (parseMBBReference(MBB)) |
1989 | return true; |
1990 | Dest = MachineOperand::CreateMBB(MBB); |
1991 | lex(); |
1992 | return false; |
1993 | } |
1994 | |
1995 | bool MIParser::parseStackFrameIndex(int &FI) { |
1996 | assert(Token.is(MIToken::StackObject)); |
1997 | unsigned ID; |
1998 | if (getUnsigned(ID)) |
1999 | return true; |
2000 | auto ObjectInfo = PFS.StackObjectSlots.find(ID); |
2001 | if (ObjectInfo == PFS.StackObjectSlots.end()) |
2002 | return error(Twine("use of undefined stack object '%stack.") + Twine(ID) + |
2003 | "'"); |
2004 | StringRef Name; |
2005 | if (const auto *Alloca = |
2006 | MF.getFrameInfo().getObjectAllocation(ObjectInfo->second)) |
2007 | Name = Alloca->getName(); |
2008 | if (!Token.stringValue().empty() && Token.stringValue() != Name) |
2009 | return error(Twine("the name of the stack object '%stack.") + Twine(ID) + |
2010 | "' isn't '" + Token.stringValue() + "'"); |
2011 | lex(); |
2012 | FI = ObjectInfo->second; |
2013 | return false; |
2014 | } |
2015 | |
2016 | bool MIParser::parseStackObjectOperand(MachineOperand &Dest) { |
2017 | int FI; |
2018 | if (parseStackFrameIndex(FI)) |
2019 | return true; |
2020 | Dest = MachineOperand::CreateFI(FI); |
2021 | return false; |
2022 | } |
2023 | |
2024 | bool MIParser::parseFixedStackFrameIndex(int &FI) { |
2025 | assert(Token.is(MIToken::FixedStackObject)); |
2026 | unsigned ID; |
2027 | if (getUnsigned(ID)) |
2028 | return true; |
2029 | auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID); |
2030 | if (ObjectInfo == PFS.FixedStackObjectSlots.end()) |
2031 | return error(Twine("use of undefined fixed stack object '%fixed-stack.") + |
2032 | Twine(ID) + "'"); |
2033 | lex(); |
2034 | FI = ObjectInfo->second; |
2035 | return false; |
2036 | } |
2037 | |
2038 | bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) { |
2039 | int FI; |
2040 | if (parseFixedStackFrameIndex(FI)) |
2041 | return true; |
2042 | Dest = MachineOperand::CreateFI(FI); |
2043 | return false; |
2044 | } |
2045 | |
2046 | static bool parseGlobalValue(const MIToken &Token, |
2047 | PerFunctionMIParsingState &PFS, GlobalValue *&GV, |
2048 | ErrorCallbackType ErrCB) { |
2049 | switch (Token.kind()) { |
| |
| 6 | | Returning from 'MIToken::kind' | |
|
| 7 | | Control jumps to 'case GlobalValue:' at line 2058 | |
|
2050 | case MIToken::NamedGlobalValue: { |
2051 | const Module *M = PFS.MF.getFunction().getParent(); |
2052 | GV = M->getNamedValue(Token.stringValue()); |
2053 | if (!GV) |
2054 | return ErrCB(Token.location(), Twine("use of undefined global value '") + |
2055 | Token.range() + "'"); |
2056 | break; |
2057 | } |
2058 | case MIToken::GlobalValue: { |
2059 | unsigned GVIdx; |
| 8 | | 'GVIdx' declared without an initial value | |
|
2060 | if (getUnsigned(Token, GVIdx, ErrCB)) |
| |
| 17 | | Returning from 'getUnsigned' | |
|
| 18 | | Assuming the condition is false | |
|
| |
2061 | return true; |
2062 | if (GVIdx >= PFS.IRSlots.GlobalValues.size()) |
| 20 | | The left operand of '>=' is a garbage value |
|
2063 | return ErrCB(Token.location(), Twine("use of undefined global value '@") + |
2064 | Twine(GVIdx) + "'"); |
2065 | GV = PFS.IRSlots.GlobalValues[GVIdx]; |
2066 | break; |
2067 | } |
2068 | default: |
2069 | llvm_unreachable("The current token should be a global value"); |
2070 | } |
2071 | return false; |
2072 | } |
2073 | |
2074 | bool MIParser::parseGlobalValue(GlobalValue *&GV) { |
2075 | return ::parseGlobalValue( |
2076 | Token, PFS, GV, |
2077 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { |
2078 | return error(Loc, Msg); |
2079 | }); |
2080 | } |
2081 | |
2082 | bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) { |
2083 | GlobalValue *GV = nullptr; |
2084 | if (parseGlobalValue(GV)) |
2085 | return true; |
2086 | lex(); |
2087 | Dest = MachineOperand::CreateGA(GV, 0); |
2088 | if (parseOperandsOffset(Dest)) |
2089 | return true; |
2090 | return false; |
2091 | } |
2092 | |
2093 | bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) { |
2094 | assert(Token.is(MIToken::ConstantPoolItem)); |
2095 | unsigned ID; |
2096 | if (getUnsigned(ID)) |
2097 | return true; |
2098 | auto ConstantInfo = PFS.ConstantPoolSlots.find(ID); |
2099 | if (ConstantInfo == PFS.ConstantPoolSlots.end()) |
2100 | return error("use of undefined constant '%const." + Twine(ID) + "'"); |
2101 | lex(); |
2102 | Dest = MachineOperand::CreateCPI(ID, 0); |
2103 | if (parseOperandsOffset(Dest)) |
2104 | return true; |
2105 | return false; |
2106 | } |
2107 | |
2108 | bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) { |
2109 | assert(Token.is(MIToken::JumpTableIndex)); |
2110 | unsigned ID; |
2111 | if (getUnsigned(ID)) |
2112 | return true; |
2113 | auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID); |
2114 | if (JumpTableEntryInfo == PFS.JumpTableSlots.end()) |
2115 | return error("use of undefined jump table '%jump-table." + Twine(ID) + "'"); |
2116 | lex(); |
2117 | Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second); |
2118 | return false; |
2119 | } |
2120 | |
2121 | bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { |
2122 | assert(Token.is(MIToken::ExternalSymbol)); |
2123 | const char *Symbol = MF.createExternalSymbolName(Token.stringValue()); |
2124 | lex(); |
2125 | Dest = MachineOperand::CreateES(Symbol); |
2126 | if (parseOperandsOffset(Dest)) |
2127 | return true; |
2128 | return false; |
2129 | } |
2130 | |
2131 | bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) { |
2132 | assert(Token.is(MIToken::MCSymbol)); |
2133 | MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue()); |
2134 | lex(); |
2135 | Dest = MachineOperand::CreateMCSymbol(Symbol); |
2136 | if (parseOperandsOffset(Dest)) |
2137 | return true; |
2138 | return false; |
2139 | } |
2140 | |
2141 | bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { |
2142 | assert(Token.is(MIToken::SubRegisterIndex)); |
2143 | StringRef Name = Token.stringValue(); |
2144 | unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue()); |
2145 | if (SubRegIndex == 0) |
2146 | return error(Twine("unknown subregister index '") + Name + "'"); |
2147 | lex(); |
2148 | Dest = MachineOperand::CreateImm(SubRegIndex); |
2149 | return false; |
2150 | } |
2151 | |
2152 | bool MIParser::parseMDNode(MDNode *&Node) { |
2153 | assert(Token.is(MIToken::exclaim)); |
2154 | |
2155 | auto Loc = Token.location(); |
2156 | lex(); |
2157 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) |
2158 | return error("expected metadata id after '!'"); |
2159 | unsigned ID; |
2160 | if (getUnsigned(ID)) |
2161 | return true; |
2162 | auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID); |
2163 | if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) { |
2164 | NodeInfo = PFS.MachineMetadataNodes.find(ID); |
2165 | if (NodeInfo == PFS.MachineMetadataNodes.end()) |
2166 | return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'"); |
2167 | } |
2168 | lex(); |
2169 | Node = NodeInfo->second.get(); |
2170 | return false; |
2171 | } |
2172 | |
2173 | bool MIParser::parseDIExpression(MDNode *&Expr) { |
2174 | assert(Token.is(MIToken::md_diexpr)); |
2175 | lex(); |
2176 | |
2177 | |
2178 | SmallVector<uint64_t, 8> Elements; |
2179 | |
2180 | if (expectAndConsume(MIToken::lparen)) |
2181 | return true; |
2182 | |
2183 | if (Token.isNot(MIToken::rparen)) { |
2184 | do { |
2185 | if (Token.is(MIToken::Identifier)) { |
2186 | if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) { |
2187 | lex(); |
2188 | Elements.push_back(Op); |
2189 | continue; |
2190 | } |
2191 | if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) { |
2192 | lex(); |
2193 | Elements.push_back(Enc); |
2194 | continue; |
2195 | } |
2196 | return error(Twine("invalid DWARF op '") + Token.stringValue() + "'"); |
2197 | } |
2198 | |
2199 | if (Token.isNot(MIToken::IntegerLiteral) || |
2200 | Token.integerValue().isSigned()) |
2201 | return error("expected unsigned integer"); |
2202 | |
2203 | auto &U = Token.integerValue(); |
2204 | if (U.ugt(UINT64_MAX)) |
2205 | return error("element too large, limit is " + Twine(UINT64_MAX)); |
2206 | Elements.push_back(U.getZExtValue()); |
2207 | lex(); |
2208 | |
2209 | } while (consumeIfPresent(MIToken::comma)); |
2210 | } |
2211 | |
2212 | if (expectAndConsume(MIToken::rparen)) |
2213 | return true; |
2214 | |
2215 | Expr = DIExpression::get(MF.getFunction().getContext(), Elements); |
2216 | return false; |
2217 | } |
2218 | |
2219 | bool MIParser::parseDILocation(MDNode *&Loc) { |
2220 | assert(Token.is(MIToken::md_dilocation)); |
2221 | lex(); |
2222 | |
2223 | bool HaveLine = false; |
2224 | unsigned Line = 0; |
2225 | unsigned Column = 0; |
2226 | MDNode *Scope = nullptr; |
2227 | MDNode *InlinedAt = nullptr; |
2228 | bool ImplicitCode = false; |
2229 | |
2230 | if (expectAndConsume(MIToken::lparen)) |
2231 | return true; |
2232 | |
2233 | if (Token.isNot(MIToken::rparen)) { |
2234 | do { |
2235 | if (Token.is(MIToken::Identifier)) { |
2236 | if (Token.stringValue() == "line") { |
2237 | lex(); |
2238 | if (expectAndConsume(MIToken::colon)) |
2239 | return true; |
2240 | if (Token.isNot(MIToken::IntegerLiteral) || |
2241 | Token.integerValue().isSigned()) |
2242 | return error("expected unsigned integer"); |
2243 | Line = Token.integerValue().getZExtValue(); |
2244 | HaveLine = true; |
2245 | lex(); |
2246 | continue; |
2247 | } |
2248 | if (Token.stringValue() == "column") { |
2249 | lex(); |
2250 | if (expectAndConsume(MIToken::colon)) |
2251 | return true; |
2252 | if (Token.isNot(MIToken::IntegerLiteral) || |
2253 | Token.integerValue().isSigned()) |
2254 | return error("expected unsigned integer"); |
2255 | Column = Token.integerValue().getZExtValue(); |
2256 | lex(); |
2257 | continue; |
2258 | } |
2259 | if (Token.stringValue() == "scope") { |
2260 | lex(); |
2261 | if (expectAndConsume(MIToken::colon)) |
2262 | return true; |
2263 | if (parseMDNode(Scope)) |
2264 | return error("expected metadata node"); |
2265 | if (!isa<DIScope>(Scope)) |
2266 | return error("expected DIScope node"); |
2267 | continue; |
2268 | } |
2269 | if (Token.stringValue() == "inlinedAt") { |
2270 | lex(); |
2271 | if (expectAndConsume(MIToken::colon)) |
2272 | return true; |
2273 | if (Token.is(MIToken::exclaim)) { |
2274 | if (parseMDNode(InlinedAt)) |
2275 | return true; |
2276 | } else if (Token.is(MIToken::md_dilocation)) { |
2277 | if (parseDILocation(InlinedAt)) |
2278 | return true; |
2279 | } else |
2280 | return error("expected metadata node"); |
2281 | if (!isa<DILocation>(InlinedAt)) |
2282 | return error("expected DILocation node"); |
2283 | continue; |
2284 | } |
2285 | if (Token.stringValue() == "isImplicitCode") { |
2286 | lex(); |
2287 | if (expectAndConsume(MIToken::colon)) |
2288 | return true; |
2289 | if (!Token.is(MIToken::Identifier)) |
2290 | return error("expected true/false"); |
2291 | |
2292 | |
2293 | |
2294 | if (Token.stringValue() == "true") |
2295 | ImplicitCode = true; |
2296 | else if (Token.stringValue() == "false") |
2297 | ImplicitCode = false; |
2298 | else |
2299 | return error("expected true/false"); |
2300 | lex(); |
2301 | continue; |
2302 | } |
2303 | } |
2304 | return error(Twine("invalid DILocation argument '") + |
2305 | Token.stringValue() + "'"); |
2306 | } while (consumeIfPresent(MIToken::comma)); |
2307 | } |
2308 | |
2309 | if (expectAndConsume(MIToken::rparen)) |
2310 | return true; |
2311 | |
2312 | if (!HaveLine) |
2313 | return error("DILocation requires line number"); |
2314 | if (!Scope) |
2315 | return error("DILocation requires a scope"); |
2316 | |
2317 | Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope, |
2318 | InlinedAt, ImplicitCode); |
2319 | return false; |
2320 | } |
2321 | |
2322 | bool MIParser::parseMetadataOperand(MachineOperand &Dest) { |
2323 | MDNode *Node = nullptr; |
2324 | if (Token.is(MIToken::exclaim)) { |
2325 | if (parseMDNode(Node)) |
2326 | return true; |
2327 | } else if (Token.is(MIToken::md_diexpr)) { |
2328 | if (parseDIExpression(Node)) |
2329 | return true; |
2330 | } |
2331 | Dest = MachineOperand::CreateMetadata(Node); |
2332 | return false; |
2333 | } |
2334 | |
2335 | bool MIParser::parseCFIOffset(int &Offset) { |
2336 | if (Token.isNot(MIToken::IntegerLiteral)) |
2337 | return error("expected a cfi offset"); |
2338 | if (Token.integerValue().getMinSignedBits() > 32) |
2339 | return error("expected a 32 bit integer (the cfi offset is too large)"); |
2340 | Offset = (int)Token.integerValue().getExtValue(); |
2341 | lex(); |
2342 | return false; |
2343 | } |
2344 | |
2345 | bool MIParser::parseCFIRegister(Register &Reg) { |
2346 | if (Token.isNot(MIToken::NamedRegister)) |
2347 | return error("expected a cfi register"); |
2348 | Register LLVMReg; |
2349 | if (parseNamedRegister(LLVMReg)) |
2350 | return true; |
2351 | const auto *TRI = MF.getSubtarget().getRegisterInfo(); |
2352 | assert(TRI && "Expected target register info"); |
2353 | int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true); |
2354 | if (DwarfReg < 0) |
2355 | return error("invalid DWARF register"); |
2356 | Reg = (unsigned)DwarfReg; |
2357 | lex(); |
2358 | return false; |
2359 | } |
2360 | |
2361 | bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) { |
2362 | if (Token.isNot(MIToken::IntegerLiteral)) |
2363 | return error("expected a cfi address space literal"); |
2364 | if (Token.integerValue().isSigned()) |
2365 | return error("expected an unsigned integer (cfi address space)"); |
2366 | AddressSpace = Token.integerValue().getZExtValue(); |
2367 | lex(); |
2368 | return false; |
2369 | } |
2370 | |
2371 | bool MIParser::parseCFIEscapeValues(std::string &Values) { |
2372 | do { |
2373 | if (Token.isNot(MIToken::HexLiteral)) |
2374 | return error("expected a hexadecimal literal"); |
2375 | unsigned Value; |
2376 | if (getUnsigned(Value)) |
2377 | return true; |
2378 | if (Value > UINT8_MAX) |
2379 | return error("expected a 8-bit integer (too large)"); |
2380 | Values.push_back(static_cast<uint8_t>(Value)); |
2381 | lex(); |
2382 | } while (consumeIfPresent(MIToken::comma)); |
2383 | return false; |
2384 | } |
2385 | |
2386 | bool MIParser::parseCFIOperand(MachineOperand &Dest) { |
2387 | auto Kind = Token.kind(); |
2388 | lex(); |
2389 | int Offset; |
2390 | Register Reg; |
2391 | unsigned AddressSpace; |
2392 | unsigned CFIIndex; |
2393 | switch (Kind) { |
2394 | case MIToken::kw_cfi_same_value: |
2395 | if (parseCFIRegister(Reg)) |
2396 | return true; |
2397 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg)); |
2398 | break; |
2399 | case MIToken::kw_cfi_offset: |
2400 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || |
2401 | parseCFIOffset(Offset)) |
2402 | return true; |
2403 | CFIIndex = |
2404 | MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); |
2405 | break; |
2406 | case MIToken::kw_cfi_rel_offset: |
2407 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || |
2408 | parseCFIOffset(Offset)) |
2409 | return true; |
2410 | CFIIndex = MF.addFrameInst( |
2411 | MCCFIInstruction::createRelOffset(nullptr, Reg, Offset)); |
2412 | break; |
2413 | case MIToken::kw_cfi_def_cfa_register: |
2414 | if (parseCFIRegister(Reg)) |
2415 | return true; |
2416 | CFIIndex = |
2417 | MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); |
2418 | break; |
2419 | case MIToken::kw_cfi_def_cfa_offset: |
2420 | if (parseCFIOffset(Offset)) |
2421 | return true; |
2422 | CFIIndex = |
2423 | MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset)); |
2424 | break; |
2425 | case MIToken::kw_cfi_adjust_cfa_offset: |
2426 | if (parseCFIOffset(Offset)) |
2427 | return true; |
2428 | CFIIndex = MF.addFrameInst( |
2429 | MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset)); |
2430 | break; |
2431 | case MIToken::kw_cfi_def_cfa: |
2432 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || |
2433 | parseCFIOffset(Offset)) |
2434 | return true; |
2435 | CFIIndex = |
2436 | MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset)); |
2437 | break; |
2438 | case MIToken::kw_cfi_llvm_def_aspace_cfa: |
2439 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || |
2440 | parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) || |
2441 | parseCFIAddressSpace(AddressSpace)) |
2442 | return true; |
2443 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa( |
2444 | nullptr, Reg, Offset, AddressSpace)); |
2445 | break; |
2446 | case MIToken::kw_cfi_remember_state: |
2447 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); |
2448 | break; |
2449 | case MIToken::kw_cfi_restore: |
2450 | if (parseCFIRegister(Reg)) |
2451 | return true; |
2452 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); |
2453 | break; |
2454 | case MIToken::kw_cfi_restore_state: |
2455 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); |
2456 | break; |
2457 | case MIToken::kw_cfi_undefined: |
2458 | if (parseCFIRegister(Reg)) |
2459 | return true; |
2460 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg)); |
2461 | break; |
2462 | case MIToken::kw_cfi_register: { |
2463 | Register Reg2; |
2464 | if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || |
2465 | parseCFIRegister(Reg2)) |
2466 | return true; |
2467 | |
2468 | CFIIndex = |
2469 | MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2)); |
2470 | break; |
2471 | } |
2472 | case MIToken::kw_cfi_window_save: |
2473 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); |
2474 | break; |
2475 | case MIToken::kw_cfi_aarch64_negate_ra_sign_state: |
2476 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); |
2477 | break; |
2478 | case MIToken::kw_cfi_escape: { |
2479 | std::string Values; |
2480 | if (parseCFIEscapeValues(Values)) |
2481 | return true; |
2482 | CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values)); |
2483 | break; |
2484 | } |
2485 | default: |
2486 | |
2487 | llvm_unreachable("The current token should be a cfi operand"); |
2488 | } |
2489 | Dest = MachineOperand::CreateCFIIndex(CFIIndex); |
2490 | return false; |
2491 | } |
2492 | |
2493 | bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) { |
2494 | switch (Token.kind()) { |
2495 | case MIToken::NamedIRBlock: { |
2496 | BB = dyn_cast_or_null<BasicBlock>( |
2497 | F.getValueSymbolTable()->lookup(Token.stringValue())); |
2498 | if (!BB) |
2499 | return error(Twine("use of undefined IR block '") + Token.range() + "'"); |
2500 | break; |
2501 | } |
2502 | case MIToken::IRBlock: { |
2503 | unsigned SlotNumber = 0; |
2504 | if (getUnsigned(SlotNumber)) |
2505 | return true; |
2506 | BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F)); |
2507 | if (!BB) |
2508 | return error(Twine("use of undefined IR block '%ir-block.") + |
2509 | Twine(SlotNumber) + "'"); |
2510 | break; |
2511 | } |
2512 | default: |
2513 | llvm_unreachable("The current token should be an IR block reference"); |
2514 | } |
2515 | return false; |
2516 | } |
2517 | |
2518 | bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { |
2519 | assert(Token.is(MIToken::kw_blockaddress)); |
2520 | lex(); |
2521 | if (expectAndConsume(MIToken::lparen)) |
2522 | return true; |
2523 | if (Token.isNot(MIToken::GlobalValue) && |
2524 | Token.isNot(MIToken::NamedGlobalValue)) |
2525 | return error("expected a global value"); |
2526 | GlobalValue *GV = nullptr; |
2527 | if (parseGlobalValue(GV)) |
2528 | return true; |
2529 | auto *F = dyn_cast<Function>(GV); |
2530 | if (!F) |
2531 | return error("expected an IR function reference"); |
2532 | lex(); |
2533 | if (expectAndConsume(MIToken::comma)) |
2534 | return true; |
2535 | BasicBlock *BB = nullptr; |
2536 | if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock)) |
2537 | return error("expected an IR block reference"); |
2538 | if (parseIRBlock(BB, *F)) |
2539 | return true; |
2540 | lex(); |
2541 | if (expectAndConsume(MIToken::rparen)) |
2542 | return true; |
2543 | Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), 0); |
2544 | if (parseOperandsOffset(Dest)) |
2545 | return true; |
2546 | return false; |
2547 | } |
2548 | |
2549 | bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) { |
2550 | assert(Token.is(MIToken::kw_intrinsic)); |
2551 | lex(); |
2552 | if (expectAndConsume(MIToken::lparen)) |
2553 | return error("expected syntax intrinsic(@llvm.whatever)"); |
2554 | |
2555 | if (Token.isNot(MIToken::NamedGlobalValue)) |
2556 | return error("expected syntax intrinsic(@llvm.whatever)"); |
2557 | |
2558 | std::string Name = std::string(Token.stringValue()); |
2559 | lex(); |
2560 | |
2561 | if (expectAndConsume(MIToken::rparen)) |
2562 | return error("expected ')' to terminate intrinsic name"); |
2563 | |
2564 | |
2565 | |
2566 | const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); |
2567 | Intrinsic::ID ID = Function::lookupIntrinsicID(Name); |
2568 | if (ID == Intrinsic::not_intrinsic && TII) |
2569 | ID = static_cast<Intrinsic::ID>(TII->lookupName(Name)); |
2570 | |
2571 | if (ID == Intrinsic::not_intrinsic) |
2572 | return error("unknown intrinsic name"); |
2573 | Dest = MachineOperand::CreateIntrinsicID(ID); |
2574 | |
2575 | return false; |
2576 | } |
2577 | |
2578 | bool MIParser::parsePredicateOperand(MachineOperand &Dest) { |
2579 | assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred)); |
2580 | bool IsFloat = Token.is(MIToken::kw_floatpred); |
2581 | lex(); |
2582 | |
2583 | if (expectAndConsume(MIToken::lparen)) |
2584 | return error("expected syntax intpred(whatever) or floatpred(whatever"); |
2585 | |
2586 | if (Token.isNot(MIToken::Identifier)) |
2587 | return error("whatever"); |
2588 | |
2589 | CmpInst::Predicate Pred; |
2590 | if (IsFloat) { |
2591 | Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) |
2592 | .Case("false", CmpInst::FCMP_FALSE) |
2593 | .Case("oeq", CmpInst::FCMP_OEQ) |
2594 | .Case("ogt", CmpInst::FCMP_OGT) |
2595 | .Case("oge", CmpInst::FCMP_OGE) |
2596 | .Case("olt", CmpInst::FCMP_OLT) |
2597 | .Case("ole", CmpInst::FCMP_OLE) |
2598 | .Case("one", CmpInst::FCMP_ONE) |
2599 | .Case("ord", CmpInst::FCMP_ORD) |
2600 | .Case("uno", CmpInst::FCMP_UNO) |
2601 | .Case("ueq", CmpInst::FCMP_UEQ) |
2602 | .Case("ugt", CmpInst::FCMP_UGT) |
2603 | .Case("uge", CmpInst::FCMP_UGE) |
2604 | .Case("ult", CmpInst::FCMP_ULT) |
2605 | .Case("ule", CmpInst::FCMP_ULE) |
2606 | .Case("une", CmpInst::FCMP_UNE) |
2607 | .Case("true", CmpInst::FCMP_TRUE) |
2608 | .Default(CmpInst::BAD_FCMP_PREDICATE); |
2609 | if (!CmpInst::isFPPredicate(Pred)) |
2610 | return error("invalid floating-point predicate"); |
2611 | } else { |
2612 | Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) |
2613 | .Case("eq", CmpInst::ICMP_EQ) |
2614 | .Case("ne", CmpInst::ICMP_NE) |
2615 | .Case("sgt", CmpInst::ICMP_SGT) |
2616 | .Case("sge", CmpInst::ICMP_SGE) |
2617 | .Case("slt", CmpInst::ICMP_SLT) |
2618 | .Case("sle", CmpInst::ICMP_SLE) |
2619 | .Case("ugt", CmpInst::ICMP_UGT) |
2620 | .Case("uge", CmpInst::ICMP_UGE) |
2621 | .Case("ult", CmpInst::ICMP_ULT) |
2622 | .Case("ule", CmpInst::ICMP_ULE) |
2623 | .Default(CmpInst::BAD_ICMP_PREDICATE); |
2624 | if (!CmpInst::isIntPredicate(Pred)) |
2625 | return error("invalid integer predicate"); |
2626 | } |
2627 | |
2628 | lex(); |
2629 | Dest = MachineOperand::CreatePredicate(Pred); |
2630 | if (expectAndConsume(MIToken::rparen)) |
2631 | return error("predicate should be terminated by ')'."); |
2632 | |
2633 | return false; |
2634 | } |
2635 | |
2636 | bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) { |
2637 | assert(Token.is(MIToken::kw_shufflemask)); |
2638 | |
2639 | lex(); |
2640 | if (expectAndConsume(MIToken::lparen)) |
2641 | return error("expected syntax shufflemask(<integer or undef>, ...)"); |
2642 | |
2643 | SmallVector<int, 32> ShufMask; |
2644 | do { |
2645 | if (Token.is(MIToken::kw_undef)) { |
2646 | ShufMask.push_back(-1); |
2647 | } else if (Token.is(MIToken::IntegerLiteral)) { |
2648 | const APSInt &Int = Token.integerValue(); |
2649 | ShufMask.push_back(Int.getExtValue()); |
2650 | } else |
2651 | return error("expected integer constant"); |
2652 | |
2653 | lex(); |
2654 | } while (consumeIfPresent(MIToken::comma)); |
2655 | |
2656 | if (expectAndConsume(MIToken::rparen)) |
2657 | return error("shufflemask should be terminated by ')'."); |
2658 | |
2659 | ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask); |
2660 | Dest = MachineOperand::CreateShuffleMask(MaskAlloc); |
2661 | return false; |
2662 | } |
2663 | |
2664 | bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { |
2665 | assert(Token.is(MIToken::kw_target_index)); |
2666 | lex(); |
2667 | if (expectAndConsume(MIToken::lparen)) |
2668 | return true; |
2669 | if (Token.isNot(MIToken::Identifier)) |
2670 | return error("expected the name of the target index"); |
2671 | int Index = 0; |
2672 | if (PFS.Target.getTargetIndex(Token.stringValue(), Index)) |
2673 | return error("use of undefined target index '" + Token.stringValue() + "'"); |
2674 | lex(); |
2675 | if (expectAndConsume(MIToken::rparen)) |
2676 | return true; |
2677 | Dest = MachineOperand::CreateTargetIndex(unsigned(Index), 0); |
2678 | if (parseOperandsOffset(Dest)) |
2679 | return true; |
2680 | return false; |
2681 | } |
2682 | |
2683 | bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { |
2684 | assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask"); |
2685 | lex(); |
2686 | if (expectAndConsume(MIToken::lparen)) |
2687 | return true; |
2688 | |
2689 | uint32_t *Mask = MF.allocateRegMask(); |
2690 | while (true) { |
2691 | if (Token.isNot(MIToken::NamedRegister)) |
2692 | return error("expected a named register"); |
2693 | Register Reg; |
2694 | if (parseNamedRegister(Reg)) |
2695 | return true; |
2696 | lex(); |
2697 | Mask[Reg / 32] |= 1U << (Reg % 32); |
2698 | |
2699 | if (Token.isNot(MIToken::comma)) |
2700 | break; |
2701 | lex(); |
2702 | } |
2703 | |
2704 | if (expectAndConsume(MIToken::rparen)) |
2705 | return true; |
2706 | Dest = MachineOperand::CreateRegMask(Mask); |
2707 | return false; |
2708 | } |
2709 | |
2710 | bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { |
2711 | assert(Token.is(MIToken::kw_liveout)); |
2712 | uint32_t *Mask = MF.allocateRegMask(); |
2713 | lex(); |
2714 | if (expectAndConsume(MIToken::lparen)) |
2715 | return true; |
2716 | while (true) { |
2717 | if (Token.isNot(MIToken::NamedRegister)) |
2718 | return error("expected a named register"); |
2719 | Register Reg; |
2720 | if (parseNamedRegister(Reg)) |
2721 | return true; |
2722 | lex(); |
2723 | Mask[Reg / 32] |= 1U << (Reg % 32); |
2724 | |
2725 | if (Token.isNot(MIToken::comma)) |
2726 | break; |
2727 | lex(); |
2728 | } |
2729 | if (expectAndConsume(MIToken::rparen)) |
2730 | return true; |
2731 | Dest = MachineOperand::CreateRegLiveOut(Mask); |
2732 | return false; |
2733 | } |
2734 | |
2735 | bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx, |
2736 | MachineOperand &Dest, |
2737 | Optional<unsigned> &TiedDefIdx) { |
2738 | switch (Token.kind()) { |
2739 | case MIToken::kw_implicit: |
2740 | case MIToken::kw_implicit_define: |
2741 | case MIToken::kw_def: |
2742 | case MIToken::kw_dead: |
2743 | case MIToken::kw_killed: |
2744 | case MIToken::kw_undef: |
2745 | case MIToken::kw_internal: |
2746 | case MIToken::kw_early_clobber: |
2747 | case MIToken::kw_debug_use: |
2748 | case MIToken::kw_renamable: |
2749 | case MIToken::underscore: |
2750 | case MIToken::NamedRegister: |
2751 | case MIToken::VirtualRegister: |
2752 | case MIToken::NamedVirtualRegister: |
2753 | return parseRegisterOperand(Dest, TiedDefIdx); |
2754 | case MIToken::IntegerLiteral: |
2755 | return parseImmediateOperand(Dest); |
2756 | case MIToken::kw_half: |
2757 | case MIToken::kw_float: |
2758 | case MIToken::kw_double: |
2759 | case MIToken::kw_x86_fp80: |
2760 | case MIToken::kw_fp128: |
2761 | case MIToken::kw_ppc_fp128: |
2762 | return parseFPImmediateOperand(Dest); |
2763 | case MIToken::MachineBasicBlock: |
2764 | return parseMBBOperand(Dest); |
2765 | case MIToken::StackObject: |
2766 | return parseStackObjectOperand(Dest); |
2767 | case MIToken::FixedStackObject: |
2768 | return parseFixedStackObjectOperand(Dest); |
2769 | case MIToken::GlobalValue: |
2770 | case MIToken::NamedGlobalValue: |
2771 | return parseGlobalAddressOperand(Dest); |
2772 | case MIToken::ConstantPoolItem: |
2773 | return parseConstantPoolIndexOperand(Dest); |
2774 | case MIToken::JumpTableIndex: |
2775 | return parseJumpTableIndexOperand(Dest); |
2776 | case MIToken::ExternalSymbol: |
2777 | return parseExternalSymbolOperand(Dest); |
2778 | case MIToken::MCSymbol: |
2779 | return parseMCSymbolOperand(Dest); |
2780 | case MIToken::SubRegisterIndex: |
2781 | return parseSubRegisterIndexOperand(Dest); |
2782 | case MIToken::md_diexpr: |
2783 | case MIToken::exclaim: |
2784 | return parseMetadataOperand(Dest); |
2785 | case MIToken::kw_cfi_same_value: |
2786 | case MIToken::kw_cfi_offset: |
2787 | case MIToken::kw_cfi_rel_offset: |
2788 | case MIToken::kw_cfi_def_cfa_register: |
2789 | case MIToken::kw_cfi_def_cfa_offset: |
2790 | case MIToken::kw_cfi_adjust_cfa_offset: |
2791 | case MIToken::kw_cfi_escape: |
2792 | case MIToken::kw_cfi_def_cfa: |
2793 | case MIToken::kw_cfi_llvm_def_aspace_cfa: |
2794 | case MIToken::kw_cfi_register: |
2795 | case MIToken::kw_cfi_remember_state: |
2796 | case MIToken::kw_cfi_restore: |
2797 | case MIToken::kw_cfi_restore_state: |
2798 | case MIToken::kw_cfi_undefined: |
2799 | case MIToken::kw_cfi_window_save: |
2800 | case MIToken::kw_cfi_aarch64_negate_ra_sign_state: |
2801 | return parseCFIOperand(Dest); |
2802 | case MIToken::kw_blockaddress: |
2803 | return parseBlockAddressOperand(Dest); |
2804 | case MIToken::kw_intrinsic: |
2805 | return parseIntrinsicOperand(Dest); |
2806 | case MIToken::kw_target_index: |
2807 | return parseTargetIndexOperand(Dest); |
2808 | case MIToken::kw_liveout: |
2809 | return parseLiveoutRegisterMaskOperand(Dest); |
2810 | case MIToken::kw_floatpred: |
2811 | case MIToken::kw_intpred: |
2812 | return parsePredicateOperand(Dest); |
2813 | case MIToken::kw_shufflemask: |
2814 | return parseShuffleMaskOperand(Dest); |
2815 | case MIToken::Error: |
2816 | return true; |
2817 | case MIToken::Identifier: |
2818 | if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) { |
2819 | Dest = MachineOperand::CreateRegMask(RegMask); |
2820 | lex(); |
2821 | break; |
2822 | } else if (Token.stringValue() == "CustomRegMask") { |
2823 | return parseCustomRegisterMaskOperand(Dest); |
2824 | } else |
2825 | return parseTypedImmediateOperand(Dest); |
2826 | case MIToken::dot: { |
2827 | const auto *TII = MF.getSubtarget().getInstrInfo(); |
2828 | if (const auto *Formatter = TII->getMIRFormatter()) { |
2829 | return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter); |
2830 | } |
2831 | LLVM_FALLTHROUGH; |
2832 | } |
2833 | default: |
2834 | |
2835 | return error("expected a machine operand"); |
2836 | } |
2837 | return false; |
2838 | } |
2839 | |
2840 | bool MIParser::parseMachineOperandAndTargetFlags( |
2841 | const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest, |
2842 | Optional<unsigned> &TiedDefIdx) { |
2843 | unsigned TF = 0; |
2844 | bool HasTargetFlags = false; |
2845 | if (Token.is(MIToken::kw_target_flags)) { |
2846 | HasTargetFlags = true; |
2847 | lex(); |
2848 | if (expectAndConsume(MIToken::lparen)) |
2849 | return true; |
2850 | if (Token.isNot(MIToken::Identifier)) |
2851 | return error("expected the name of the target flag"); |
2852 | if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) { |
2853 | if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF)) |
2854 | return error("use of undefined target flag '" + Token.stringValue() + |
2855 | "'"); |
2856 | } |
2857 | lex(); |
2858 | while (Token.is(MIToken::comma)) { |
2859 | lex(); |
2860 | if (Token.isNot(MIToken::Identifier)) |
2861 | return error("expected the name of the target flag"); |
2862 | unsigned BitFlag = 0; |
2863 | if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag)) |
2864 | return error("use of undefined target flag '" + Token.stringValue() + |
2865 | "'"); |
2866 | |
2867 | TF |= BitFlag; |
2868 | lex(); |
2869 | } |
2870 | if (expectAndConsume(MIToken::rparen)) |
2871 | return true; |
2872 | } |
2873 | auto Loc = Token.location(); |
2874 | if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx)) |
2875 | return true; |
2876 | if (!HasTargetFlags) |
2877 | return false; |
2878 | if (Dest.isReg()) |
2879 | return error(Loc, "register operands can't have target flags"); |
2880 | Dest.setTargetFlags(TF); |
2881 | return false; |
2882 | } |
2883 | |
2884 | bool MIParser::parseOffset(int64_t &Offset) { |
2885 | if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus)) |
2886 | return false; |
2887 | StringRef Sign = Token.range(); |
2888 | bool IsNegative = Token.is(MIToken::minus); |
2889 | lex(); |
2890 | if (Token.isNot(MIToken::IntegerLiteral)) |
2891 | return error("expected an integer literal after '" + Sign + "'"); |
2892 | if (Token.integerValue().getMinSignedBits() > 64) |
2893 | return error("expected 64-bit integer (too large)"); |
2894 | Offset = Token.integerValue().getExtValue(); |
2895 | if (IsNegative) |
2896 | Offset = -Offset; |
2897 | lex(); |
2898 | return false; |
2899 | } |
2900 | |
2901 | bool MIParser::parseAlignment(unsigned &Alignment) { |
2902 | assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign)); |
2903 | lex(); |
2904 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) |
2905 | return error("expected an integer literal after 'align'"); |
2906 | if (getUnsigned(Alignment)) |
2907 | return true; |
2908 | lex(); |
2909 | |
2910 | if (!isPowerOf2_32(Alignment)) |
2911 | return error("expected a power-of-2 literal after 'align'"); |
2912 | |
2913 | return false; |
2914 | } |
2915 | |
2916 | bool MIParser::parseAddrspace(unsigned &Addrspace) { |
2917 | assert(Token.is(MIToken::kw_addrspace)); |
2918 | lex(); |
2919 | if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) |
2920 | return error("expected an integer literal after 'addrspace'"); |
2921 | if (getUnsigned(Addrspace)) |
2922 | return true; |
2923 | lex(); |
2924 | return false; |
2925 | } |
2926 | |
2927 | bool MIParser::parseOperandsOffset(MachineOperand &Op) { |
2928 | int64_t Offset = 0; |
2929 | if (parseOffset(Offset)) |
2930 | return true; |
2931 | Op.setOffset(Offset); |
2932 | return false; |
2933 | } |
2934 | |
2935 | static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS, |
2936 | const Value *&V, ErrorCallbackType ErrCB) { |
2937 | switch (Token.kind()) { |
| 2 | | Control jumps to 'case GlobalValue:' at line 2950 | |
|
2938 | case MIToken::NamedIRValue: { |
2939 | V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue()); |
2940 | break; |
2941 | } |
2942 | case MIToken::IRValue: { |
2943 | unsigned SlotNumber = 0; |
2944 | if (getUnsigned(Token, SlotNumber, ErrCB)) |
2945 | return true; |
2946 | V = PFS.getIRValue(SlotNumber); |
2947 | break; |
2948 | } |
2949 | case MIToken::NamedGlobalValue: |
2950 | case MIToken::GlobalValue: { |
2951 | GlobalValue *GV = nullptr; |
2952 | if (parseGlobalValue(Token, PFS, GV, ErrCB)) |
| 3 | | Calling 'parseGlobalValue' | |
|
2953 | return true; |
2954 | V = GV; |
2955 | break; |
2956 | } |
2957 | case MIToken::QuotedIRValue: { |
2958 | const Constant *C = nullptr; |
2959 | if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB)) |
2960 | return true; |
2961 | V = C; |
2962 | break; |
2963 | } |
2964 | case MIToken::kw_unknown_address: |
2965 | V = nullptr; |
2966 | return false; |
2967 | default: |
2968 | llvm_unreachable("The current token should be an IR block reference"); |
2969 | } |
2970 | if (!V) |
2971 | return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'"); |
2972 | return false; |
2973 | } |
2974 | |
2975 | bool MIParser::parseIRValue(const Value *&V) { |
2976 | return ::parseIRValue( |
2977 | Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool { |
2978 | return error(Loc, Msg); |
2979 | }); |
2980 | } |
2981 | |
2982 | bool MIParser::getUint64(uint64_t &Result) { |
2983 | if (Token.hasIntegerValue()) { |
2984 | if (Token.integerValue().getActiveBits() > 64) |
2985 | return error("expected 64-bit integer (too large)"); |
2986 | Result = Token.integerValue().getZExtValue(); |
2987 | return false; |
2988 | } |
2989 | if (Token.is(MIToken::HexLiteral)) { |
2990 | APInt A; |
2991 | if (getHexUint(A)) |
2992 | return true; |
2993 | if (A.getBitWidth() > 64) |
2994 | return error("expected 64-bit integer (too large)"); |
2995 | Result = A.getZExtValue(); |
2996 | return false; |
2997 | } |
2998 | return true; |
2999 | } |
3000 | |
3001 | bool MIParser::getHexUint(APInt &Result) { |
3002 | return ::getHexUint(Token, Result); |
3003 | } |
3004 | |
3005 | bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) { |
3006 | const auto OldFlags = Flags; |
3007 | switch (Token.kind()) { |
3008 | case MIToken::kw_volatile: |
3009 | Flags |= MachineMemOperand::MOVolatile; |
3010 | break; |
3011 | case MIToken::kw_non_temporal: |
3012 | Flags |= MachineMemOperand::MONonTemporal; |
3013 | break; |
3014 | case MIToken::kw_dereferenceable: |
3015 | Flags |= MachineMemOperand::MODereferenceable; |
3016 | break; |
3017 | case MIToken::kw_invariant: |
3018 | Flags |= MachineMemOperand::MOInvariant; |
3019 | break; |
3020 | case MIToken::StringConstant: { |
3021 | MachineMemOperand::Flags TF; |
3022 | if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF)) |
3023 | return error("use of undefined target MMO flag '" + Token.stringValue() + |
3024 | "'"); |
3025 | Flags |= TF; |
3026 | break; |
3027 | } |
3028 | default: |
3029 | llvm_unreachable("The current token should be a memory operand flag"); |
3030 | } |
3031 | if (OldFlags == Flags) |
3032 | |
3033 | |
3034 | return error("duplicate '" + Token.stringValue() + "' memory operand flag"); |
3035 | lex(); |
3036 | return false; |
3037 | } |
3038 | |
3039 | bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) { |
3040 | switch (Token.kind()) { |
3041 | case MIToken::kw_stack: |
3042 | PSV = MF.getPSVManager().getStack(); |
3043 | break; |
3044 | case MIToken::kw_got: |
3045 | PSV = MF.getPSVManager().getGOT(); |
3046 | break; |
3047 | case MIToken::kw_jump_table: |
3048 | PSV = MF.getPSVManager().getJumpTable(); |
3049 | break; |
3050 | case MIToken::kw_constant_pool: |
3051 | PSV = MF.getPSVManager().getConstantPool(); |
3052 | break; |
3053 | case MIToken::FixedStackObject: { |
3054 | int FI; |
3055 | if (parseFixedStackFrameIndex(FI)) |
3056 | return true; |
3057 | PSV = MF.getPSVManager().getFixedStack(FI); |
3058 | |
3059 | return false; |
3060 | } |
3061 | case MIToken::StackObject: { |
3062 | int FI; |
3063 | if (parseStackFrameIndex(FI)) |
3064 | return true; |
3065 | PSV = MF.getPSVManager().getFixedStack(FI); |
3066 | |
3067 | return false; |
3068 | } |
3069 | case MIToken::kw_call_entry: |
3070 | lex(); |
3071 | switch (Token.kind()) { |
3072 | case MIToken::GlobalValue: |
3073 | case MIToken::NamedGlobalValue: { |
3074 | GlobalValue *GV = nullptr; |
3075 | if (parseGlobalValue(GV)) |
3076 | return true; |
3077 | PSV = MF.getPSVManager().getGlobalValueCallEntry(GV); |
3078 | break; |
3079 | } |
3080 | case MIToken::ExternalSymbol: |
3081 | PSV = MF.getPSVManager().getExternalSymbolCallEntry( |
3082 | MF.createExternalSymbolName(Token.stringValue())); |
3083 | break; |
3084 | default: |
3085 | return error( |
3086 | "expected a global value or an external symbol after 'call-entry'"); |
3087 | } |
3088 | break; |
3089 | case MIToken::kw_custom: { |
3090 | lex(); |
3091 | const auto *TII = MF.getSubtarget().getInstrInfo(); |
3092 | if (const auto *Formatter = TII->getMIRFormatter()) { |
3093 | if (Formatter->parseCustomPseudoSourceValue( |
3094 | Token.stringValue(), MF, PFS, PSV, |
3095 | [this](StringRef::iterator Loc, const Twine &Msg) -> bool { |
3096 | return error(Loc, Msg); |
3097 | })) |
3098 | return true; |
3099 | } else |
3100 | return error("unable to parse target custom pseudo source value"); |
3101 | break; |
3102 | } |
3103 | default: |
3104 | llvm_unreachable("The current token should be pseudo source value"); |
3105 | } |
3106 | lex(); |
3107 | return false; |
3108 | } |
3109 | |
3110 | bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) { |
3111 | if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) || |
3112 | Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) || |
3113 | Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) || |
3114 | Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) { |
3115 | const PseudoSourceValue *PSV = nullptr; |
3116 | if (parseMemoryPseudoSourceValue(PSV)) |
3117 | return true; |
3118 | int64_t Offset = 0; |
3119 | if (parseOffset(Offset)) |
3120 | return true; |
3121 | Dest = MachinePointerInfo(PSV, Offset); |
3122 | return false; |
3123 | } |
3124 | if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) && |
3125 | Token.isNot(MIToken::GlobalValue) && |
3126 | Token.isNot(MIToken::NamedGlobalValue) && |
3127 | Token.isNot(MIToken::QuotedIRValue) && |
3128 | Token.isNot(MIToken::kw_unknown_address)) |
3129 | return error("expected an IR value reference"); |
3130 | const Value *V = nullptr; |
3131 | if (parseIRValue(V)) |
3132 | return true; |
3133 | if (V && !V->getType()->isPointerTy()) |
3134 | return error("expected a pointer IR value"); |
3135 | lex(); |
3136 | int64_t Offset = 0; |
3137 | if (parseOffset(Offset)) |
3138 | return true; |
3139 | Dest = MachinePointerInfo(V, Offset); |
3140 | return false; |
3141 | } |
3142 | |
3143 | bool MIParser::parseOptionalScope(LLVMContext &Context, |
3144 | SyncScope::ID &SSID) { |
3145 | SSID = SyncScope::System; |
3146 | if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") { |
3147 | lex(); |
3148 | if (expectAndConsume(MIToken::lparen)) |
3149 | return error("expected '(' in syncscope"); |
3150 | |
3151 | std::string SSN; |
3152 | if (parseStringConstant(SSN)) |
3153 | return true; |
3154 | |
3155 | SSID = Context.getOrInsertSyncScopeID(SSN); |
3156 | if (expectAndConsume(MIToken::rparen)) |
3157 | return error("expected ')' in syncscope"); |
3158 | } |
3159 | |
3160 | return false; |
3161 | } |
3162 | |
3163 | bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) { |
3164 | Order = AtomicOrdering::NotAtomic; |
3165 | if (Token.isNot(MIToken::Identifier)) |
3166 | return false; |
3167 | |
3168 | Order = StringSwitch<AtomicOrdering>(Token.stringValue()) |
3169 | .Case("unordered", AtomicOrdering::Unordered) |
3170 | .Case("monotonic", AtomicOrdering::Monotonic) |
3171 | .Case("acquire", AtomicOrdering::Acquire) |
3172 | .Case("release", AtomicOrdering::Release) |
3173 | .Case("acq_rel", AtomicOrdering::AcquireRelease) |
3174 | .Case("seq_cst", AtomicOrdering::SequentiallyConsistent) |
3175 | .Default(AtomicOrdering::NotAtomic); |
3176 | |
3177 | if (Order != AtomicOrdering::NotAtomic) { |
3178 | lex(); |
3179 | return false; |
3180 | } |
3181 | |
3182 | return error("expected an atomic scope, ordering or a size specification"); |
3183 | } |
3184 | |
3185 | bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { |
3186 | if (expectAndConsume(MIToken::lparen)) |
3187 | return true; |
3188 | MachineMemOperand::Flags Flags = MachineMemOperand::MONone; |
3189 | while (Token.isMemoryOperandFlag()) { |
3190 | if (parseMemoryOperandFlag(Flags)) |
3191 | return true; |
3192 | } |
3193 | if (Token.isNot(MIToken::Identifier) || |
3194 | (Token.stringValue() != "load" && Token.stringValue() != "store")) |
3195 | return error("expected 'load' or 'store' memory operation"); |
3196 | if (Token.stringValue() == "load") |
3197 | Flags |= MachineMemOperand::MOLoad; |
3198 | else |
3199 | Flags |= MachineMemOperand::MOStore; |
3200 | lex(); |
3201 | |
3202 | |
3203 | if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") { |
3204 | Flags |= MachineMemOperand::MOStore; |
3205 | lex(); |
3206 | } |
3207 | |
3208 | |
3209 | SyncScope::ID SSID; |
3210 | if (parseOptionalScope(MF.getFunction().getContext(), SSID)) |
3211 | return true; |
3212 | |
3213 | |
3214 | AtomicOrdering Order, FailureOrder; |
3215 | if (parseOptionalAtomicOrdering(Order)) |
3216 | return true; |
3217 | |
3218 | if (parseOptionalAtomicOrdering(FailureOrder)) |
3219 | return true; |
3220 | |
3221 | LLT MemoryType; |
3222 | if (Token.isNot(MIToken::IntegerLiteral) && |
3223 | Token.isNot(MIToken::kw_unknown_size) && |
3224 | Token.isNot(MIToken::lparen)) |
3225 | return error("expected memory LLT, the size integer literal or 'unknown-size' after " |
3226 | "memory operation"); |
3227 | |
3228 | uint64_t Size = MemoryLocation::UnknownSize; |
3229 | if (Token.is(MIToken::IntegerLiteral)) { |
3230 | if (getUint64(Size)) |
3231 | return true; |
3232 | |
3233 | |
3234 | MemoryType = LLT::scalar(8 * Size); |
3235 | lex(); |
3236 | } else if (Token.is(MIToken::kw_unknown_size)) { |
3237 | Size = MemoryLocation::UnknownSize; |
3238 | lex(); |
3239 | } else { |
3240 | if (expectAndConsume(MIToken::lparen)) |
3241 | return true; |
3242 | if (parseLowLevelType(Token.location(), MemoryType)) |
3243 | return true; |
3244 | if (expectAndConsume(MIToken::rparen)) |
3245 | return true; |
3246 | |
3247 | Size = MemoryType.getSizeInBytes(); |
3248 | } |
3249 | |
3250 | MachinePointerInfo Ptr = MachinePointerInfo(); |
3251 | if (Token.is(MIToken::Identifier)) { |
3252 | const char *Word = |
3253 | ((Flags & MachineMemOperand::MOLoad) && |
3254 | (Flags & MachineMemOperand::MOStore)) |
3255 | ? "on" |
3256 | : Flags & MachineMemOperand::MOLoad ? "from" : "into"; |
3257 | if (Token.stringValue() != Word) |
3258 | return error(Twine("expected '") + Word + "'"); |
3259 | lex(); |
3260 | |
3261 | if (parseMachinePointerInfo(Ptr)) |
3262 | return true; |
3263 | } |
3264 | unsigned BaseAlignment = |
3265 | (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1); |
3266 | AAMDNodes AAInfo; |
3267 | MDNode *Range = nullptr; |
3268 | while (consumeIfPresent(MIToken::comma)) { |
3269 | switch (Token.kind()) { |
3270 | case MIToken::kw_align: |
3271 | |
3272 | if (parseAlignment(BaseAlignment)) |
3273 | return true; |
3274 | break; |
3275 | case MIToken::kw_basealign: |
3276 | |
3277 | if (parseAlignment(BaseAlignment)) |
3278 | return true; |
3279 | break; |
3280 | case MIToken::kw_addrspace: |
3281 | if (parseAddrspace(Ptr.AddrSpace)) |
3282 | return true; |
3283 | break; |
3284 | case MIToken::md_tbaa: |
3285 | lex(); |
3286 | if (parseMDNode(AAInfo.TBAA)) |
3287 | return true; |
3288 | break; |
3289 | case MIToken::md_alias_scope: |
3290 | lex(); |
3291 | if (parseMDNode(AAInfo.Scope)) |
3292 | return true; |
3293 | break; |
3294 | case MIToken::md_noalias: |
3295 | lex(); |
3296 | if (parseMDNode(AAInfo.NoAlias)) |
3297 | return true; |
3298 | break; |
3299 | case MIToken::md_range: |
3300 | lex(); |
3301 | if (parseMDNode(Range)) |
3302 | return true; |
3303 | break; |
3304 | |
3305 | default: |
3306 | return error("expected 'align' or '!tbaa' or '!alias.scope' or " |
3307 | "'!noalias' or '!range'"); |
3308 | } |
3309 | } |
3310 | if (expectAndConsume(MIToken::rparen)) |
3311 | return true; |
3312 | Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment), |
3313 | AAInfo, Range, SSID, Order, FailureOrder); |
3314 | return false; |
3315 | } |
3316 | |
3317 | bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) { |
3318 | assert((Token.is(MIToken::kw_pre_instr_symbol) || |
3319 | Token.is(MIToken::kw_post_instr_symbol)) && |
3320 | "Invalid token for a pre- post-instruction symbol!"); |
3321 | lex(); |
3322 | if (Token.isNot(MIToken::MCSymbol)) |
3323 | return error("expected a symbol after 'pre-instr-symbol'"); |
3324 | Symbol = getOrCreateMCSymbol(Token.stringValue()); |
3325 | lex(); |
3326 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || |
3327 | Token.is(MIToken::lbrace)) |
3328 | return false; |
3329 | if (Token.isNot(MIToken::comma)) |
3330 | return error("expected ',' before the next machine operand"); |
3331 | lex(); |
3332 | return false; |
3333 | } |
3334 | |
3335 | bool MIParser::parseHeapAllocMarker(MDNode *&Node) { |
3336 | assert(Token.is(MIToken::kw_heap_alloc_marker) && |
3337 | "Invalid token for a heap alloc marker!"); |
3338 | lex(); |
3339 | parseMDNode(Node); |
3340 | if (!Node) |
3341 | return error("expected a MDNode after 'heap-alloc-marker'"); |
3342 | if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || |
3343 | Token.is(MIToken::lbrace)) |
3344 | return false; |
3345 | if (Token.isNot(MIToken::comma)) |
3346 | return error("expected ',' before the next machine operand"); |
3347 | lex(); |
3348 | return false; |
3349 | } |
3350 | |
3351 | static void initSlots2BasicBlocks( |
3352 | const Function &F, |
3353 | DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { |
3354 | ModuleSlotTracker MST(F.getParent(), false); |
3355 | MST.incorporateFunction(F); |
3356 | for (auto &BB : F) { |
3357 | if (BB.hasName()) |
3358 | continue; |
3359 | int Slot = MST.getLocalSlot(&BB); |
3360 | if (Slot == -1) |
3361 | continue; |
3362 | Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB)); |
3363 | } |
3364 | } |
3365 | |
3366 | static const BasicBlock *getIRBlockFromSlot( |
3367 | unsigned Slot, |
3368 | const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { |
3369 | return Slots2BasicBlocks.lookup(Slot); |
3370 | } |
3371 | |
3372 | const BasicBlock *MIParser::getIRBlock(unsigned Slot) { |
3373 | if (Slots2BasicBlocks.empty()) |
3374 | initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks); |
3375 | return getIRBlockFromSlot(Slot, Slots2BasicBlocks); |
3376 | } |
3377 | |
3378 | const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) { |
3379 | if (&F == &MF.getFunction()) |
3380 | return getIRBlock(Slot); |
3381 | DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks; |
3382 | initSlots2BasicBlocks(F, CustomSlots2BasicBlocks); |
3383 | return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks); |
3384 | } |
3385 | |
3386 | MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) { |
3387 | |
3388 | |
3389 | |
3390 | |
3391 | |
3392 | return MF.getContext().getOrCreateSymbol(Name); |
3393 | } |
3394 | |
3395 | bool MIParser::parseStringConstant(std::string &Result) { |
3396 | if (Token.isNot(MIToken::StringConstant)) |
3397 | return error("expected string constant"); |
3398 | Result = std::string(Token.stringValue()); |
3399 | lex(); |
3400 | return false; |
3401 | } |
3402 | |
3403 | bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, |
3404 | StringRef Src, |
3405 | SMDiagnostic &Error) { |
3406 | return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots); |
3407 | } |
3408 | |
3409 | bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS, |
3410 | StringRef Src, SMDiagnostic &Error) { |
3411 | return MIParser(PFS, Error, Src).parseBasicBlocks(); |
3412 | } |
3413 | |
3414 | bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS, |
3415 | MachineBasicBlock *&MBB, StringRef Src, |
3416 | SMDiagnostic &Error) { |
3417 | return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB); |
3418 | } |
3419 | |
3420 | bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS, |
3421 | Register &Reg, StringRef Src, |
3422 | SMDiagnostic &Error) { |
3423 | return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg); |
3424 | } |
3425 | |
3426 | bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS, |
3427 | Register &Reg, StringRef Src, |
3428 | SMDiagnostic &Error) { |
3429 | return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg); |
3430 | } |
3431 | |
3432 | bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, |
3433 | VRegInfo *&Info, StringRef Src, |
3434 | SMDiagnostic &Error) { |
3435 | return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info); |
3436 | } |
3437 | |
3438 | bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS, |
3439 | int &FI, StringRef Src, |
3440 | SMDiagnostic &Error) { |
3441 | return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI); |
3442 | } |
3443 | |
3444 | bool llvm::parseMDNode(PerFunctionMIParsingState &PFS, |
3445 | MDNode *&Node, StringRef Src, SMDiagnostic &Error) { |
3446 | return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node); |
3447 | } |
3448 | |
3449 | bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src, |
3450 | SMRange SrcRange, SMDiagnostic &Error) { |
3451 | return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata(); |
3452 | } |
3453 | |
3454 | bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF, |
3455 | PerFunctionMIParsingState &PFS, const Value *&V, |
3456 | ErrorCallbackType ErrorCallback) { |
3457 | MIToken Token; |
3458 | Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) { |
3459 | ErrorCallback(Loc, Msg); |
3460 | }); |
3461 | V = nullptr; |
3462 | |
3463 | return ::parseIRValue(Token, PFS, V, ErrorCallback); |
| |
3464 | } |