File: | llvm/lib/AsmParser/LLParser.h |
Warning: | line 177, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- Parser.cpp - Main dispatch module for the Parser library -----------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This library implements the functionality defined in llvm/AsmParser/Parser.h | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #include "llvm/AsmParser/Parser.h" | |||
14 | #include "LLParser.h" | |||
15 | #include "llvm/ADT/STLExtras.h" | |||
16 | #include "llvm/IR/Module.h" | |||
17 | #include "llvm/IR/ModuleSummaryIndex.h" | |||
18 | #include "llvm/Support/MemoryBuffer.h" | |||
19 | #include "llvm/Support/SourceMgr.h" | |||
20 | #include "llvm/Support/raw_ostream.h" | |||
21 | #include <cstring> | |||
22 | #include <system_error> | |||
23 | using namespace llvm; | |||
24 | ||||
25 | bool llvm::parseAssemblyInto(MemoryBufferRef F, Module *M, | |||
26 | ModuleSummaryIndex *Index, SMDiagnostic &Err, | |||
27 | SlotMapping *Slots, bool UpgradeDebugInfo, | |||
28 | StringRef DataLayoutString) { | |||
29 | SourceMgr SM; | |||
30 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); | |||
31 | SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |||
32 | ||||
33 | LLVMContext Context; | |||
34 | return LLParser(F.getBuffer(), SM, Err, M, Index, | |||
35 | M ? M->getContext() : Context, Slots, UpgradeDebugInfo, | |||
36 | DataLayoutString) | |||
37 | .Run(); | |||
38 | } | |||
39 | ||||
40 | std::unique_ptr<Module> | |||
41 | llvm::parseAssembly(MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, | |||
42 | SlotMapping *Slots, bool UpgradeDebugInfo, | |||
43 | StringRef DataLayoutString) { | |||
44 | std::unique_ptr<Module> M = | |||
45 | std::make_unique<Module>(F.getBufferIdentifier(), Context); | |||
46 | ||||
47 | if (parseAssemblyInto(F, M.get(), nullptr, Err, Slots, UpgradeDebugInfo, | |||
48 | DataLayoutString)) | |||
49 | return nullptr; | |||
50 | ||||
51 | return M; | |||
52 | } | |||
53 | ||||
54 | std::unique_ptr<Module> | |||
55 | llvm::parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, | |||
56 | LLVMContext &Context, SlotMapping *Slots, | |||
57 | bool UpgradeDebugInfo, StringRef DataLayoutString) { | |||
58 | ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |||
59 | MemoryBuffer::getFileOrSTDIN(Filename); | |||
60 | if (std::error_code EC = FileOrErr.getError()) { | |||
61 | Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |||
62 | "Could not open input file: " + EC.message()); | |||
63 | return nullptr; | |||
64 | } | |||
65 | ||||
66 | return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context, Slots, | |||
67 | UpgradeDebugInfo, DataLayoutString); | |||
68 | } | |||
69 | ||||
70 | ParsedModuleAndIndex llvm::parseAssemblyWithIndex( | |||
71 | MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context, | |||
72 | SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { | |||
73 | std::unique_ptr<Module> M = | |||
74 | std::make_unique<Module>(F.getBufferIdentifier(), Context); | |||
75 | std::unique_ptr<ModuleSummaryIndex> Index = | |||
76 | std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/true); | |||
77 | ||||
78 | if (parseAssemblyInto(F, M.get(), Index.get(), Err, Slots, UpgradeDebugInfo, | |||
79 | DataLayoutString)) | |||
80 | return {nullptr, nullptr}; | |||
81 | ||||
82 | return {std::move(M), std::move(Index)}; | |||
83 | } | |||
84 | ||||
85 | ParsedModuleAndIndex llvm::parseAssemblyFileWithIndex( | |||
86 | StringRef Filename, SMDiagnostic &Err, LLVMContext &Context, | |||
87 | SlotMapping *Slots, bool UpgradeDebugInfo, StringRef DataLayoutString) { | |||
88 | ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |||
89 | MemoryBuffer::getFileOrSTDIN(Filename); | |||
90 | if (std::error_code EC = FileOrErr.getError()) { | |||
91 | Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |||
92 | "Could not open input file: " + EC.message()); | |||
93 | return {nullptr, nullptr}; | |||
94 | } | |||
95 | ||||
96 | return parseAssemblyWithIndex(FileOrErr.get()->getMemBufferRef(), Err, | |||
97 | Context, Slots, UpgradeDebugInfo, | |||
98 | DataLayoutString); | |||
99 | } | |||
100 | ||||
101 | std::unique_ptr<Module> | |||
102 | llvm::parseAssemblyString(StringRef AsmString, SMDiagnostic &Err, | |||
103 | LLVMContext &Context, SlotMapping *Slots, | |||
104 | bool UpgradeDebugInfo, StringRef DataLayoutString) { | |||
105 | MemoryBufferRef F(AsmString, "<string>"); | |||
106 | return parseAssembly(F, Err, Context, Slots, UpgradeDebugInfo, | |||
107 | DataLayoutString); | |||
108 | } | |||
109 | ||||
110 | static bool parseSummaryIndexAssemblyInto(MemoryBufferRef F, | |||
111 | ModuleSummaryIndex &Index, | |||
112 | SMDiagnostic &Err) { | |||
113 | SourceMgr SM; | |||
114 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F); | |||
115 | SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |||
116 | ||||
117 | // The parser holds a reference to a context that is unused when parsing the | |||
118 | // index, but we need to initialize it. | |||
119 | LLVMContext unusedContext; | |||
120 | return LLParser(F.getBuffer(), SM, Err, nullptr, &Index, unusedContext).Run(); | |||
121 | } | |||
122 | ||||
123 | std::unique_ptr<ModuleSummaryIndex> | |||
124 | llvm::parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err) { | |||
125 | std::unique_ptr<ModuleSummaryIndex> Index = | |||
126 | std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); | |||
127 | ||||
128 | if (parseSummaryIndexAssemblyInto(F, *Index, Err)) | |||
129 | return nullptr; | |||
130 | ||||
131 | return Index; | |||
132 | } | |||
133 | ||||
134 | std::unique_ptr<ModuleSummaryIndex> | |||
135 | llvm::parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err) { | |||
136 | ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = | |||
137 | MemoryBuffer::getFileOrSTDIN(Filename); | |||
138 | if (std::error_code EC = FileOrErr.getError()) { | |||
| ||||
139 | Err = SMDiagnostic(Filename, SourceMgr::DK_Error, | |||
140 | "Could not open input file: " + EC.message()); | |||
141 | return nullptr; | |||
142 | } | |||
143 | ||||
144 | return parseSummaryIndexAssembly(FileOrErr.get()->getMemBufferRef(), Err); | |||
145 | } | |||
146 | ||||
147 | Constant *llvm::parseConstantValue(StringRef Asm, SMDiagnostic &Err, | |||
148 | const Module &M, const SlotMapping *Slots) { | |||
149 | SourceMgr SM; | |||
150 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |||
151 | SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |||
152 | Constant *C; | |||
153 | if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) | |||
154 | .parseStandaloneConstantValue(C, Slots)) | |||
155 | return nullptr; | |||
156 | return C; | |||
157 | } | |||
158 | ||||
159 | Type *llvm::parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, | |||
160 | const SlotMapping *Slots) { | |||
161 | unsigned Read; | |||
162 | Type *Ty = parseTypeAtBeginning(Asm, Read, Err, M, Slots); | |||
163 | if (!Ty) | |||
164 | return nullptr; | |||
165 | if (Read != Asm.size()) { | |||
166 | SourceMgr SM; | |||
167 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |||
168 | SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |||
169 | Err = SM.GetMessage(SMLoc::getFromPointer(Asm.begin() + Read), | |||
170 | SourceMgr::DK_Error, "expected end of string"); | |||
171 | return nullptr; | |||
172 | } | |||
173 | return Ty; | |||
174 | } | |||
175 | Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read, | |||
176 | SMDiagnostic &Err, const Module &M, | |||
177 | const SlotMapping *Slots) { | |||
178 | SourceMgr SM; | |||
179 | std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm); | |||
180 | SM.AddNewSourceBuffer(std::move(Buf), SMLoc()); | |||
181 | Type *Ty; | |||
182 | if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext()) | |||
183 | .parseTypeAtBeginning(Ty, Read, Slots)) | |||
184 | return nullptr; | |||
185 | return Ty; | |||
186 | } |
1 | //===-- LLParser.h - Parser Class -------------------------------*- C++ -*-===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This file defines the parser class for .ll files. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #ifndef LLVM_LIB_ASMPARSER_LLPARSER_H | |||
14 | #define LLVM_LIB_ASMPARSER_LLPARSER_H | |||
15 | ||||
16 | #include "LLLexer.h" | |||
17 | #include "llvm/ADT/Optional.h" | |||
18 | #include "llvm/ADT/StringMap.h" | |||
19 | #include "llvm/IR/Attributes.h" | |||
20 | #include "llvm/IR/Instructions.h" | |||
21 | #include "llvm/IR/Module.h" | |||
22 | #include "llvm/IR/ModuleSummaryIndex.h" | |||
23 | #include "llvm/IR/Operator.h" | |||
24 | #include "llvm/IR/Type.h" | |||
25 | #include "llvm/IR/ValueHandle.h" | |||
26 | #include <map> | |||
27 | ||||
28 | namespace llvm { | |||
29 | class Module; | |||
30 | class OpaqueType; | |||
31 | class Function; | |||
32 | class Value; | |||
33 | class BasicBlock; | |||
34 | class Instruction; | |||
35 | class Constant; | |||
36 | class GlobalValue; | |||
37 | class Comdat; | |||
38 | class MDString; | |||
39 | class MDNode; | |||
40 | struct SlotMapping; | |||
41 | class StructType; | |||
42 | ||||
43 | /// ValID - Represents a reference of a definition of some sort with no type. | |||
44 | /// There are several cases where we have to parse the value but where the | |||
45 | /// type can depend on later context. This may either be a numeric reference | |||
46 | /// or a symbolic (%var) reference. This is just a discriminated union. | |||
47 | struct ValID { | |||
48 | enum { | |||
49 | t_LocalID, t_GlobalID, // ID in UIntVal. | |||
50 | t_LocalName, t_GlobalName, // Name in StrVal. | |||
51 | t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal. | |||
52 | t_Null, t_Undef, t_Zero, t_None, // No value. | |||
53 | t_EmptyArray, // No value: [] | |||
54 | t_Constant, // Value in ConstantVal. | |||
55 | t_InlineAsm, // Value in FTy/StrVal/StrVal2/UIntVal. | |||
56 | t_ConstantStruct, // Value in ConstantStructElts. | |||
57 | t_PackedConstantStruct // Value in ConstantStructElts. | |||
58 | } Kind = t_LocalID; | |||
59 | ||||
60 | LLLexer::LocTy Loc; | |||
61 | unsigned UIntVal; | |||
62 | FunctionType *FTy = nullptr; | |||
63 | std::string StrVal, StrVal2; | |||
64 | APSInt APSIntVal; | |||
65 | APFloat APFloatVal{0.0}; | |||
66 | Constant *ConstantVal; | |||
67 | std::unique_ptr<Constant *[]> ConstantStructElts; | |||
68 | ||||
69 | ValID() = default; | |||
70 | ValID(const ValID &RHS) | |||
71 | : Kind(RHS.Kind), Loc(RHS.Loc), UIntVal(RHS.UIntVal), FTy(RHS.FTy), | |||
72 | StrVal(RHS.StrVal), StrVal2(RHS.StrVal2), APSIntVal(RHS.APSIntVal), | |||
73 | APFloatVal(RHS.APFloatVal), ConstantVal(RHS.ConstantVal) { | |||
74 | assert(!RHS.ConstantStructElts)((!RHS.ConstantStructElts) ? static_cast<void> (0) : __assert_fail ("!RHS.ConstantStructElts", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/AsmParser/LLParser.h" , 74, __PRETTY_FUNCTION__)); | |||
75 | } | |||
76 | ||||
77 | bool operator<(const ValID &RHS) const { | |||
78 | if (Kind == t_LocalID || Kind == t_GlobalID) | |||
79 | return UIntVal < RHS.UIntVal; | |||
80 | assert((Kind == t_LocalName || Kind == t_GlobalName ||(((Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && "Ordering not defined for this ValID kind yet" ) ? static_cast<void> (0) : __assert_fail ("(Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && \"Ordering not defined for this ValID kind yet\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/AsmParser/LLParser.h" , 82, __PRETTY_FUNCTION__)) | |||
81 | Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) &&(((Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && "Ordering not defined for this ValID kind yet" ) ? static_cast<void> (0) : __assert_fail ("(Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && \"Ordering not defined for this ValID kind yet\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/AsmParser/LLParser.h" , 82, __PRETTY_FUNCTION__)) | |||
82 | "Ordering not defined for this ValID kind yet")(((Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && "Ordering not defined for this ValID kind yet" ) ? static_cast<void> (0) : __assert_fail ("(Kind == t_LocalName || Kind == t_GlobalName || Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && \"Ordering not defined for this ValID kind yet\"" , "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/AsmParser/LLParser.h" , 82, __PRETTY_FUNCTION__)); | |||
83 | return StrVal < RHS.StrVal; | |||
84 | } | |||
85 | }; | |||
86 | ||||
87 | class LLParser { | |||
88 | public: | |||
89 | typedef LLLexer::LocTy LocTy; | |||
90 | private: | |||
91 | LLVMContext &Context; | |||
92 | LLLexer Lex; | |||
93 | // Module being parsed, null if we are only parsing summary index. | |||
94 | Module *M; | |||
95 | // Summary index being parsed, null if we are only parsing Module. | |||
96 | ModuleSummaryIndex *Index; | |||
97 | SlotMapping *Slots; | |||
98 | ||||
99 | // Instruction metadata resolution. Each instruction can have a list of | |||
100 | // MDRef info associated with them. | |||
101 | // | |||
102 | // The simpler approach of just creating temporary MDNodes and then calling | |||
103 | // RAUW on them when the definition is processed doesn't work because some | |||
104 | // instruction metadata kinds, such as dbg, get stored in the IR in an | |||
105 | // "optimized" format which doesn't participate in the normal value use | |||
106 | // lists. This means that RAUW doesn't work, even on temporary MDNodes | |||
107 | // which otherwise support RAUW. Instead, we defer resolving MDNode | |||
108 | // references until the definitions have been processed. | |||
109 | struct MDRef { | |||
110 | SMLoc Loc; | |||
111 | unsigned MDKind, MDSlot; | |||
112 | }; | |||
113 | ||||
114 | SmallVector<Instruction*, 64> InstsWithTBAATag; | |||
115 | ||||
116 | // Type resolution handling data structures. The location is set when we | |||
117 | // have processed a use of the type but not a definition yet. | |||
118 | StringMap<std::pair<Type*, LocTy> > NamedTypes; | |||
119 | std::map<unsigned, std::pair<Type*, LocTy> > NumberedTypes; | |||
120 | ||||
121 | std::map<unsigned, TrackingMDNodeRef> NumberedMetadata; | |||
122 | std::map<unsigned, std::pair<TempMDTuple, LocTy>> ForwardRefMDNodes; | |||
123 | ||||
124 | // Global Value reference information. | |||
125 | std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals; | |||
126 | std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs; | |||
127 | std::vector<GlobalValue*> NumberedVals; | |||
128 | ||||
129 | // Comdat forward reference information. | |||
130 | std::map<std::string, LocTy> ForwardRefComdats; | |||
131 | ||||
132 | // References to blockaddress. The key is the function ValID, the value is | |||
133 | // a list of references to blocks in that function. | |||
134 | std::map<ValID, std::map<ValID, GlobalValue *>> ForwardRefBlockAddresses; | |||
135 | class PerFunctionState; | |||
136 | /// Reference to per-function state to allow basic blocks to be | |||
137 | /// forward-referenced by blockaddress instructions within the same | |||
138 | /// function. | |||
139 | PerFunctionState *BlockAddressPFS; | |||
140 | ||||
141 | // Attribute builder reference information. | |||
142 | std::map<Value*, std::vector<unsigned> > ForwardRefAttrGroups; | |||
143 | std::map<unsigned, AttrBuilder> NumberedAttrBuilders; | |||
144 | ||||
145 | // Summary global value reference information. | |||
146 | std::map<unsigned, std::vector<std::pair<ValueInfo *, LocTy>>> | |||
147 | ForwardRefValueInfos; | |||
148 | std::map<unsigned, std::vector<std::pair<AliasSummary *, LocTy>>> | |||
149 | ForwardRefAliasees; | |||
150 | std::vector<ValueInfo> NumberedValueInfos; | |||
151 | ||||
152 | // Summary type id reference information. | |||
153 | std::map<unsigned, std::vector<std::pair<GlobalValue::GUID *, LocTy>>> | |||
154 | ForwardRefTypeIds; | |||
155 | ||||
156 | // Map of module ID to path. | |||
157 | std::map<unsigned, StringRef> ModuleIdMap; | |||
158 | ||||
159 | /// Only the llvm-as tool may set this to false to bypass | |||
160 | /// UpgradeDebuginfo so it can generate broken bitcode. | |||
161 | bool UpgradeDebugInfo; | |||
162 | ||||
163 | /// DataLayout string to override that in LLVM assembly. | |||
164 | StringRef DataLayoutStr; | |||
165 | ||||
166 | std::string SourceFileName; | |||
167 | ||||
168 | public: | |||
169 | LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *M, | |||
170 | ModuleSummaryIndex *Index, LLVMContext &Context, | |||
171 | SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true, | |||
172 | StringRef DataLayoutString = "") | |||
173 | : Context(Context), Lex(F, SM, Err, Context), M(M), Index(Index), | |||
174 | Slots(Slots), BlockAddressPFS(nullptr), | |||
175 | UpgradeDebugInfo(UpgradeDebugInfo), DataLayoutStr(DataLayoutString) { | |||
176 | if (!DataLayoutStr.empty()) | |||
177 | M->setDataLayout(DataLayoutStr); | |||
| ||||
178 | } | |||
179 | bool Run(); | |||
180 | ||||
181 | bool parseStandaloneConstantValue(Constant *&C, const SlotMapping *Slots); | |||
182 | ||||
183 | bool parseTypeAtBeginning(Type *&Ty, unsigned &Read, | |||
184 | const SlotMapping *Slots); | |||
185 | ||||
186 | LLVMContext &getContext() { return Context; } | |||
187 | ||||
188 | private: | |||
189 | ||||
190 | bool Error(LocTy L, const Twine &Msg) const { | |||
191 | return Lex.Error(L, Msg); | |||
192 | } | |||
193 | bool TokError(const Twine &Msg) const { | |||
194 | return Error(Lex.getLoc(), Msg); | |||
195 | } | |||
196 | ||||
197 | /// Restore the internal name and slot mappings using the mappings that | |||
198 | /// were created at an earlier parsing stage. | |||
199 | void restoreParsingState(const SlotMapping *Slots); | |||
200 | ||||
201 | /// GetGlobalVal - Get a value with the specified name or ID, creating a | |||
202 | /// forward reference record if needed. This can return null if the value | |||
203 | /// exists but does not have the right type. | |||
204 | GlobalValue *GetGlobalVal(const std::string &N, Type *Ty, LocTy Loc, | |||
205 | bool IsCall); | |||
206 | GlobalValue *GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall); | |||
207 | ||||
208 | /// Get a Comdat with the specified name, creating a forward reference | |||
209 | /// record if needed. | |||
210 | Comdat *getComdat(const std::string &Name, LocTy Loc); | |||
211 | ||||
212 | // Helper Routines. | |||
213 | bool ParseToken(lltok::Kind T, const char *ErrMsg); | |||
214 | bool EatIfPresent(lltok::Kind T) { | |||
215 | if (Lex.getKind() != T) return false; | |||
216 | Lex.Lex(); | |||
217 | return true; | |||
218 | } | |||
219 | ||||
220 | FastMathFlags EatFastMathFlagsIfPresent() { | |||
221 | FastMathFlags FMF; | |||
222 | while (true) | |||
223 | switch (Lex.getKind()) { | |||
224 | case lltok::kw_fast: FMF.setFast(); Lex.Lex(); continue; | |||
225 | case lltok::kw_nnan: FMF.setNoNaNs(); Lex.Lex(); continue; | |||
226 | case lltok::kw_ninf: FMF.setNoInfs(); Lex.Lex(); continue; | |||
227 | case lltok::kw_nsz: FMF.setNoSignedZeros(); Lex.Lex(); continue; | |||
228 | case lltok::kw_arcp: FMF.setAllowReciprocal(); Lex.Lex(); continue; | |||
229 | case lltok::kw_contract: | |||
230 | FMF.setAllowContract(true); | |||
231 | Lex.Lex(); | |||
232 | continue; | |||
233 | case lltok::kw_reassoc: FMF.setAllowReassoc(); Lex.Lex(); continue; | |||
234 | case lltok::kw_afn: FMF.setApproxFunc(); Lex.Lex(); continue; | |||
235 | default: return FMF; | |||
236 | } | |||
237 | return FMF; | |||
238 | } | |||
239 | ||||
240 | bool ParseOptionalToken(lltok::Kind T, bool &Present, | |||
241 | LocTy *Loc = nullptr) { | |||
242 | if (Lex.getKind() != T) { | |||
243 | Present = false; | |||
244 | } else { | |||
245 | if (Loc) | |||
246 | *Loc = Lex.getLoc(); | |||
247 | Lex.Lex(); | |||
248 | Present = true; | |||
249 | } | |||
250 | return false; | |||
251 | } | |||
252 | bool ParseStringConstant(std::string &Result); | |||
253 | bool ParseUInt32(unsigned &Val); | |||
254 | bool ParseUInt32(unsigned &Val, LocTy &Loc) { | |||
255 | Loc = Lex.getLoc(); | |||
256 | return ParseUInt32(Val); | |||
257 | } | |||
258 | bool ParseUInt64(uint64_t &Val); | |||
259 | bool ParseUInt64(uint64_t &Val, LocTy &Loc) { | |||
260 | Loc = Lex.getLoc(); | |||
261 | return ParseUInt64(Val); | |||
262 | } | |||
263 | bool ParseFlag(unsigned &Val); | |||
264 | ||||
265 | bool ParseStringAttribute(AttrBuilder &B); | |||
266 | ||||
267 | bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); | |||
268 | bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); | |||
269 | bool ParseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr); | |||
270 | bool ParseOptionalAddrSpace(unsigned &AddrSpace, unsigned DefaultAS = 0); | |||
271 | bool ParseOptionalProgramAddrSpace(unsigned &AddrSpace) { | |||
272 | return ParseOptionalAddrSpace( | |||
273 | AddrSpace, M->getDataLayout().getProgramAddressSpace()); | |||
274 | }; | |||
275 | bool ParseOptionalParamAttrs(AttrBuilder &B); | |||
276 | bool ParseOptionalReturnAttrs(AttrBuilder &B); | |||
277 | bool ParseOptionalLinkage(unsigned &Res, bool &HasLinkage, | |||
278 | unsigned &Visibility, unsigned &DLLStorageClass, | |||
279 | bool &DSOLocal); | |||
280 | void ParseOptionalDSOLocal(bool &DSOLocal); | |||
281 | void ParseOptionalVisibility(unsigned &Res); | |||
282 | void ParseOptionalDLLStorageClass(unsigned &Res); | |||
283 | bool ParseOptionalCallingConv(unsigned &CC); | |||
284 | bool ParseOptionalAlignment(MaybeAlign &Alignment); | |||
285 | bool ParseOptionalDerefAttrBytes(lltok::Kind AttrKind, uint64_t &Bytes); | |||
286 | bool ParseScopeAndOrdering(bool isAtomic, SyncScope::ID &SSID, | |||
287 | AtomicOrdering &Ordering); | |||
288 | bool ParseScope(SyncScope::ID &SSID); | |||
289 | bool ParseOrdering(AtomicOrdering &Ordering); | |||
290 | bool ParseOptionalStackAlignment(unsigned &Alignment); | |||
291 | bool ParseOptionalCommaAlign(MaybeAlign &Alignment, bool &AteExtraComma); | |||
292 | bool ParseOptionalCommaAddrSpace(unsigned &AddrSpace, LocTy &Loc, | |||
293 | bool &AteExtraComma); | |||
294 | bool ParseOptionalCommaInAlloca(bool &IsInAlloca); | |||
295 | bool parseAllocSizeArguments(unsigned &BaseSizeArg, | |||
296 | Optional<unsigned> &HowManyArg); | |||
297 | bool ParseIndexList(SmallVectorImpl<unsigned> &Indices, | |||
298 | bool &AteExtraComma); | |||
299 | bool ParseIndexList(SmallVectorImpl<unsigned> &Indices) { | |||
300 | bool AteExtraComma; | |||
301 | if (ParseIndexList(Indices, AteExtraComma)) return true; | |||
302 | if (AteExtraComma) | |||
303 | return TokError("expected index"); | |||
304 | return false; | |||
305 | } | |||
306 | ||||
307 | // Top-Level Entities | |||
308 | bool ParseTopLevelEntities(); | |||
309 | bool ValidateEndOfModule(); | |||
310 | bool ValidateEndOfIndex(); | |||
311 | bool ParseTargetDefinition(); | |||
312 | bool ParseModuleAsm(); | |||
313 | bool ParseSourceFileName(); | |||
314 | bool ParseDepLibs(); // FIXME: Remove in 4.0. | |||
315 | bool ParseUnnamedType(); | |||
316 | bool ParseNamedType(); | |||
317 | bool ParseDeclare(); | |||
318 | bool ParseDefine(); | |||
319 | ||||
320 | bool ParseGlobalType(bool &IsConstant); | |||
321 | bool ParseUnnamedGlobal(); | |||
322 | bool ParseNamedGlobal(); | |||
323 | bool ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, | |||
324 | bool HasLinkage, unsigned Visibility, | |||
325 | unsigned DLLStorageClass, bool DSOLocal, | |||
326 | GlobalVariable::ThreadLocalMode TLM, | |||
327 | GlobalVariable::UnnamedAddr UnnamedAddr); | |||
328 | bool parseIndirectSymbol(const std::string &Name, LocTy NameLoc, | |||
329 | unsigned L, unsigned Visibility, | |||
330 | unsigned DLLStorageClass, bool DSOLocal, | |||
331 | GlobalVariable::ThreadLocalMode TLM, | |||
332 | GlobalVariable::UnnamedAddr UnnamedAddr); | |||
333 | bool parseComdat(); | |||
334 | bool ParseStandaloneMetadata(); | |||
335 | bool ParseNamedMetadata(); | |||
336 | bool ParseMDString(MDString *&Result); | |||
337 | bool ParseMDNodeID(MDNode *&Result); | |||
338 | bool ParseUnnamedAttrGrp(); | |||
339 | bool ParseFnAttributeValuePairs(AttrBuilder &B, | |||
340 | std::vector<unsigned> &FwdRefAttrGrps, | |||
341 | bool inAttrGrp, LocTy &BuiltinLoc); | |||
342 | bool ParseByValWithOptionalType(Type *&Result); | |||
343 | ||||
344 | // Module Summary Index Parsing. | |||
345 | bool SkipModuleSummaryEntry(); | |||
346 | bool ParseSummaryEntry(); | |||
347 | bool ParseModuleEntry(unsigned ID); | |||
348 | bool ParseModuleReference(StringRef &ModulePath); | |||
349 | bool ParseGVReference(ValueInfo &VI, unsigned &GVId); | |||
350 | bool ParseSummaryIndexFlags(); | |||
351 | bool ParseGVEntry(unsigned ID); | |||
352 | bool ParseFunctionSummary(std::string Name, GlobalValue::GUID, unsigned ID); | |||
353 | bool ParseVariableSummary(std::string Name, GlobalValue::GUID, unsigned ID); | |||
354 | bool ParseAliasSummary(std::string Name, GlobalValue::GUID, unsigned ID); | |||
355 | bool ParseGVFlags(GlobalValueSummary::GVFlags &GVFlags); | |||
356 | bool ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags); | |||
357 | bool ParseOptionalFFlags(FunctionSummary::FFlags &FFlags); | |||
358 | bool ParseOptionalCalls(std::vector<FunctionSummary::EdgeTy> &Calls); | |||
359 | bool ParseHotness(CalleeInfo::HotnessType &Hotness); | |||
360 | bool ParseOptionalTypeIdInfo(FunctionSummary::TypeIdInfo &TypeIdInfo); | |||
361 | bool ParseTypeTests(std::vector<GlobalValue::GUID> &TypeTests); | |||
362 | bool ParseVFuncIdList(lltok::Kind Kind, | |||
363 | std::vector<FunctionSummary::VFuncId> &VFuncIdList); | |||
364 | bool ParseConstVCallList( | |||
365 | lltok::Kind Kind, | |||
366 | std::vector<FunctionSummary::ConstVCall> &ConstVCallList); | |||
367 | using IdToIndexMapType = | |||
368 | std::map<unsigned, std::vector<std::pair<unsigned, LocTy>>>; | |||
369 | bool ParseConstVCall(FunctionSummary::ConstVCall &ConstVCall, | |||
370 | IdToIndexMapType &IdToIndexMap, unsigned Index); | |||
371 | bool ParseVFuncId(FunctionSummary::VFuncId &VFuncId, | |||
372 | IdToIndexMapType &IdToIndexMap, unsigned Index); | |||
373 | bool ParseOptionalVTableFuncs(VTableFuncList &VTableFuncs); | |||
374 | bool ParseOptionalRefs(std::vector<ValueInfo> &Refs); | |||
375 | bool ParseTypeIdEntry(unsigned ID); | |||
376 | bool ParseTypeIdSummary(TypeIdSummary &TIS); | |||
377 | bool ParseTypeIdCompatibleVtableEntry(unsigned ID); | |||
378 | bool ParseTypeTestResolution(TypeTestResolution &TTRes); | |||
379 | bool ParseOptionalWpdResolutions( | |||
380 | std::map<uint64_t, WholeProgramDevirtResolution> &WPDResMap); | |||
381 | bool ParseWpdRes(WholeProgramDevirtResolution &WPDRes); | |||
382 | bool ParseOptionalResByArg( | |||
383 | std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> | |||
384 | &ResByArg); | |||
385 | bool ParseArgs(std::vector<uint64_t> &Args); | |||
386 | void AddGlobalValueToIndex(std::string Name, GlobalValue::GUID, | |||
387 | GlobalValue::LinkageTypes Linkage, unsigned ID, | |||
388 | std::unique_ptr<GlobalValueSummary> Summary); | |||
389 | ||||
390 | // Type Parsing. | |||
391 | bool ParseType(Type *&Result, const Twine &Msg, bool AllowVoid = false); | |||
392 | bool ParseType(Type *&Result, bool AllowVoid = false) { | |||
393 | return ParseType(Result, "expected type", AllowVoid); | |||
394 | } | |||
395 | bool ParseType(Type *&Result, const Twine &Msg, LocTy &Loc, | |||
396 | bool AllowVoid = false) { | |||
397 | Loc = Lex.getLoc(); | |||
398 | return ParseType(Result, Msg, AllowVoid); | |||
399 | } | |||
400 | bool ParseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) { | |||
401 | Loc = Lex.getLoc(); | |||
402 | return ParseType(Result, AllowVoid); | |||
403 | } | |||
404 | bool ParseAnonStructType(Type *&Result, bool Packed); | |||
405 | bool ParseStructBody(SmallVectorImpl<Type*> &Body); | |||
406 | bool ParseStructDefinition(SMLoc TypeLoc, StringRef Name, | |||
407 | std::pair<Type*, LocTy> &Entry, | |||
408 | Type *&ResultTy); | |||
409 | ||||
410 | bool ParseArrayVectorType(Type *&Result, bool isVector); | |||
411 | bool ParseFunctionType(Type *&Result); | |||
412 | ||||
413 | // Function Semantic Analysis. | |||
414 | class PerFunctionState { | |||
415 | LLParser &P; | |||
416 | Function &F; | |||
417 | std::map<std::string, std::pair<Value*, LocTy> > ForwardRefVals; | |||
418 | std::map<unsigned, std::pair<Value*, LocTy> > ForwardRefValIDs; | |||
419 | std::vector<Value*> NumberedVals; | |||
420 | ||||
421 | /// FunctionNumber - If this is an unnamed function, this is the slot | |||
422 | /// number of it, otherwise it is -1. | |||
423 | int FunctionNumber; | |||
424 | public: | |||
425 | PerFunctionState(LLParser &p, Function &f, int functionNumber); | |||
426 | ~PerFunctionState(); | |||
427 | ||||
428 | Function &getFunction() const { return F; } | |||
429 | ||||
430 | bool FinishFunction(); | |||
431 | ||||
432 | /// GetVal - Get a value with the specified name or ID, creating a | |||
433 | /// forward reference record if needed. This can return null if the value | |||
434 | /// exists but does not have the right type. | |||
435 | Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc, bool IsCall); | |||
436 | Value *GetVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall); | |||
437 | ||||
438 | /// SetInstName - After an instruction is parsed and inserted into its | |||
439 | /// basic block, this installs its name. | |||
440 | bool SetInstName(int NameID, const std::string &NameStr, LocTy NameLoc, | |||
441 | Instruction *Inst); | |||
442 | ||||
443 | /// GetBB - Get a basic block with the specified name or ID, creating a | |||
444 | /// forward reference record if needed. This can return null if the value | |||
445 | /// is not a BasicBlock. | |||
446 | BasicBlock *GetBB(const std::string &Name, LocTy Loc); | |||
447 | BasicBlock *GetBB(unsigned ID, LocTy Loc); | |||
448 | ||||
449 | /// DefineBB - Define the specified basic block, which is either named or | |||
450 | /// unnamed. If there is an error, this returns null otherwise it returns | |||
451 | /// the block being defined. | |||
452 | BasicBlock *DefineBB(const std::string &Name, int NameID, LocTy Loc); | |||
453 | ||||
454 | bool resolveForwardRefBlockAddresses(); | |||
455 | }; | |||
456 | ||||
457 | bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, | |||
458 | PerFunctionState *PFS, bool IsCall); | |||
459 | ||||
460 | Value *checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty, | |||
461 | Value *Val, bool IsCall); | |||
462 | ||||
463 | bool parseConstantValue(Type *Ty, Constant *&C); | |||
464 | bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS); | |||
465 | bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) { | |||
466 | return ParseValue(Ty, V, &PFS); | |||
467 | } | |||
468 | ||||
469 | bool ParseValue(Type *Ty, Value *&V, LocTy &Loc, | |||
470 | PerFunctionState &PFS) { | |||
471 | Loc = Lex.getLoc(); | |||
472 | return ParseValue(Ty, V, &PFS); | |||
473 | } | |||
474 | ||||
475 | bool ParseTypeAndValue(Value *&V, PerFunctionState *PFS); | |||
476 | bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS) { | |||
477 | return ParseTypeAndValue(V, &PFS); | |||
478 | } | |||
479 | bool ParseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) { | |||
480 | Loc = Lex.getLoc(); | |||
481 | return ParseTypeAndValue(V, PFS); | |||
482 | } | |||
483 | bool ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc, | |||
484 | PerFunctionState &PFS); | |||
485 | bool ParseTypeAndBasicBlock(BasicBlock *&BB, PerFunctionState &PFS) { | |||
486 | LocTy Loc; | |||
487 | return ParseTypeAndBasicBlock(BB, Loc, PFS); | |||
488 | } | |||
489 | ||||
490 | ||||
491 | struct ParamInfo { | |||
492 | LocTy Loc; | |||
493 | Value *V; | |||
494 | AttributeSet Attrs; | |||
495 | ParamInfo(LocTy loc, Value *v, AttributeSet attrs) | |||
496 | : Loc(loc), V(v), Attrs(attrs) {} | |||
497 | }; | |||
498 | bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, | |||
499 | PerFunctionState &PFS, | |||
500 | bool IsMustTailCall = false, | |||
501 | bool InVarArgsFunc = false); | |||
502 | ||||
503 | bool | |||
504 | ParseOptionalOperandBundles(SmallVectorImpl<OperandBundleDef> &BundleList, | |||
505 | PerFunctionState &PFS); | |||
506 | ||||
507 | bool ParseExceptionArgs(SmallVectorImpl<Value *> &Args, | |||
508 | PerFunctionState &PFS); | |||
509 | ||||
510 | // Constant Parsing. | |||
511 | bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr); | |||
512 | bool ParseGlobalValue(Type *Ty, Constant *&C); | |||
513 | bool ParseGlobalTypeAndValue(Constant *&V); | |||
514 | bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, | |||
515 | Optional<unsigned> *InRangeOp = nullptr); | |||
516 | bool parseOptionalComdat(StringRef GlobalName, Comdat *&C); | |||
517 | bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS); | |||
518 | bool ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, | |||
519 | PerFunctionState *PFS); | |||
520 | bool ParseMetadata(Metadata *&MD, PerFunctionState *PFS); | |||
521 | bool ParseMDTuple(MDNode *&MD, bool IsDistinct = false); | |||
522 | bool ParseMDNode(MDNode *&N); | |||
523 | bool ParseMDNodeTail(MDNode *&N); | |||
524 | bool ParseMDNodeVector(SmallVectorImpl<Metadata *> &Elts); | |||
525 | bool ParseMetadataAttachment(unsigned &Kind, MDNode *&MD); | |||
526 | bool ParseInstructionMetadata(Instruction &Inst); | |||
527 | bool ParseGlobalObjectMetadataAttachment(GlobalObject &GO); | |||
528 | bool ParseOptionalFunctionMetadata(Function &F); | |||
529 | ||||
530 | template <class FieldTy> | |||
531 | bool ParseMDField(LocTy Loc, StringRef Name, FieldTy &Result); | |||
532 | template <class FieldTy> bool ParseMDField(StringRef Name, FieldTy &Result); | |||
533 | template <class ParserTy> | |||
534 | bool ParseMDFieldsImplBody(ParserTy parseField); | |||
535 | template <class ParserTy> | |||
536 | bool ParseMDFieldsImpl(ParserTy parseField, LocTy &ClosingLoc); | |||
537 | bool ParseSpecializedMDNode(MDNode *&N, bool IsDistinct = false); | |||
538 | ||||
539 | #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) \ | |||
540 | bool Parse##CLASS(MDNode *&Result, bool IsDistinct); | |||
541 | #include "llvm/IR/Metadata.def" | |||
542 | ||||
543 | // Function Parsing. | |||
544 | struct ArgInfo { | |||
545 | LocTy Loc; | |||
546 | Type *Ty; | |||
547 | AttributeSet Attrs; | |||
548 | std::string Name; | |||
549 | ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N) | |||
550 | : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} | |||
551 | }; | |||
552 | bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg); | |||
553 | bool ParseFunctionHeader(Function *&Fn, bool isDefine); | |||
554 | bool ParseFunctionBody(Function &Fn); | |||
555 | bool ParseBasicBlock(PerFunctionState &PFS); | |||
556 | ||||
557 | enum TailCallType { TCT_None, TCT_Tail, TCT_MustTail }; | |||
558 | ||||
559 | // Instruction Parsing. Each instruction parsing routine can return with a | |||
560 | // normal result, an error result, or return having eaten an extra comma. | |||
561 | enum InstResult { InstNormal = 0, InstError = 1, InstExtraComma = 2 }; | |||
562 | int ParseInstruction(Instruction *&Inst, BasicBlock *BB, | |||
563 | PerFunctionState &PFS); | |||
564 | bool ParseCmpPredicate(unsigned &P, unsigned Opc); | |||
565 | ||||
566 | bool ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS); | |||
567 | bool ParseBr(Instruction *&Inst, PerFunctionState &PFS); | |||
568 | bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); | |||
569 | bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); | |||
570 | bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); | |||
571 | bool ParseResume(Instruction *&Inst, PerFunctionState &PFS); | |||
572 | bool ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS); | |||
573 | bool ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS); | |||
574 | bool ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS); | |||
575 | bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS); | |||
576 | bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS); | |||
577 | bool ParseCallBr(Instruction *&Inst, PerFunctionState &PFS); | |||
578 | ||||
579 | bool ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc, | |||
580 | bool IsFP); | |||
581 | bool ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc, | |||
582 | bool IsFP); | |||
583 | bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc); | |||
584 | bool ParseCompare(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc); | |||
585 | bool ParseCast(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc); | |||
586 | bool ParseSelect(Instruction *&Inst, PerFunctionState &PFS); | |||
587 | bool ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS); | |||
588 | bool ParseExtractElement(Instruction *&Inst, PerFunctionState &PFS); | |||
589 | bool ParseInsertElement(Instruction *&Inst, PerFunctionState &PFS); | |||
590 | bool ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS); | |||
591 | int ParsePHI(Instruction *&Inst, PerFunctionState &PFS); | |||
592 | bool ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS); | |||
593 | bool ParseCall(Instruction *&Inst, PerFunctionState &PFS, | |||
594 | CallInst::TailCallKind TCK); | |||
595 | int ParseAlloc(Instruction *&Inst, PerFunctionState &PFS); | |||
596 | int ParseLoad(Instruction *&Inst, PerFunctionState &PFS); | |||
597 | int ParseStore(Instruction *&Inst, PerFunctionState &PFS); | |||
598 | int ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS); | |||
599 | int ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS); | |||
600 | int ParseFence(Instruction *&Inst, PerFunctionState &PFS); | |||
601 | int ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS); | |||
602 | int ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS); | |||
603 | int ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS); | |||
604 | bool ParseFreeze(Instruction *&I, PerFunctionState &PFS); | |||
605 | ||||
606 | // Use-list order directives. | |||
607 | bool ParseUseListOrder(PerFunctionState *PFS = nullptr); | |||
608 | bool ParseUseListOrderBB(); | |||
609 | bool ParseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes); | |||
610 | bool sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, SMLoc Loc); | |||
611 | }; | |||
612 | } // End llvm namespace | |||
613 | ||||
614 | #endif |