LLVM 24.0.0git
IR2Vec.cpp
Go to the documentation of this file.
1//===- IR2Vec.cpp - Implementation of IR2Vec -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM
4// Exceptions. See the LICENSE file for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements the IR2Vec algorithm.
11///
12//===----------------------------------------------------------------------===//
13
15#include "AnalysisOptions.h"
16
18#include "llvm/ADT/Sequence.h"
19#include "llvm/ADT/Statistic.h"
20#include "llvm/IR/CFG.h"
22#include "llvm/IR/Module.h"
23#include "llvm/IR/PassManager.h"
24#include "llvm/Support/Debug.h"
25#include "llvm/Support/Errc.h"
26#include "llvm/Support/Error.h"
28#include "llvm/Support/Format.h"
30
31using namespace llvm;
32using namespace ir2vec;
33
34#define DEBUG_TYPE "ir2vec"
35
36STATISTIC(VocabMissCounter,
37 "Number of lookups to entities not present in the vocabulary");
38
40 return getAnalysisOptions(C).ir2vec_vocab_path;
41}
45
47
48// ==----------------------------------------------------------------------===//
49// Local helper functions
50//===----------------------------------------------------------------------===//
51namespace llvm::json {
52inline bool fromJSON(const llvm::json::Value &E, Embedding &Out,
54 std::vector<double> TempOut;
55 if (!llvm::json::fromJSON(E, TempOut, P))
56 return false;
57 Out = Embedding(std::move(TempOut));
58 return true;
59}
60} // namespace llvm::json
61
62// ==----------------------------------------------------------------------===//
63// Embedding
64//===----------------------------------------------------------------------===//
66 assert(this->size() == RHS.size() && "Vectors must have the same dimension");
67 std::transform(this->begin(), this->end(), RHS.begin(), this->begin(),
68 std::plus<double>());
69 return *this;
70}
71
73 Embedding Result(*this);
74 Result += RHS;
75 return Result;
76}
77
79 assert(this->size() == RHS.size() && "Vectors must have the same dimension");
80 std::transform(this->begin(), this->end(), RHS.begin(), this->begin(),
81 std::minus<double>());
82 return *this;
83}
84
86 Embedding Result(*this);
87 Result -= RHS;
88 return Result;
89}
90
92 std::transform(this->begin(), this->end(), this->begin(),
93 [Factor](double Elem) { return Elem * Factor; });
94 return *this;
95}
96
97Embedding Embedding::operator*(double Factor) const {
98 Embedding Result(*this);
99 Result *= Factor;
100 return Result;
101}
102
103Embedding &Embedding::scaleAndAdd(const Embedding &Src, float Factor) {
104 assert(this->size() == Src.size() && "Vectors must have the same dimension");
105 for (size_t Itr = 0; Itr < this->size(); ++Itr)
106 (*this)[Itr] += Src[Itr] * Factor;
107 return *this;
108}
109
111 double Tolerance) const {
112 assert(this->size() == RHS.size() && "Vectors must have the same dimension");
113 for (size_t Itr = 0; Itr < this->size(); ++Itr)
114 if (std::abs((*this)[Itr] - RHS[Itr]) > Tolerance) {
115 LLVM_DEBUG(errs() << "Embedding mismatch at index " << Itr << ": "
116 << (*this)[Itr] << " vs " << RHS[Itr]
117 << "; Tolerance: " << Tolerance << "\n");
118 return false;
119 }
120 return true;
121}
122
124 OS << " [";
125 for (const auto &Elem : Data)
126 OS << " " << format("%.2f", Elem) << " ";
127 OS << "]\n";
128}
129
130// ==----------------------------------------------------------------------===//
131// Embedder and its subclasses
132//===----------------------------------------------------------------------===//
133
134std::unique_ptr<Embedder> Embedder::create(IR2VecKind Mode, const Function &F,
135 const Vocabulary &Vocab) {
136 switch (Mode) {
138 return std::make_unique<SymbolicEmbedder>(F, Vocab);
140 return std::make_unique<FlowAwareEmbedder>(F, Vocab);
141 }
142 return nullptr;
143}
144
146 Embedding FuncVector(Dimension, 0.0);
147
148 if (F.isDeclaration())
149 return FuncVector;
150
151 // Consider only the basic blocks that are reachable from entry
152 for (const BasicBlock *BB : depth_first(&F))
153 FuncVector += computeEmbeddings(*BB);
154 return FuncVector;
155}
156
158 Embedding BBVector(Dimension, 0);
159
160 // We consider only the non-pseudo instructions
161 for (const auto &I : BB)
163 BBVector += computeEmbeddings(I);
164 return BBVector;
165}
166
168 // Currently, we always (re)compute the embeddings for symbolic embedder.
169 // This is cheaper than caching the vectors.
170 Embedding ArgEmb(Dimension, 0);
171 for (const auto &Op : I.operands())
172 ArgEmb += Vocab[*Op];
173 auto InstVector =
174 Vocab[I.getOpcode()] + Vocab[I.getType()->getTypeID()] + ArgEmb;
175 if (const auto *IC = dyn_cast<CmpInst>(&I))
176 InstVector += Vocab[IC->getPredicate()];
177 return InstVector;
178}
179
181 // If we have already computed the embedding for this instruction, return it
182 auto It = InstVecMap.find(&I);
183 if (It != InstVecMap.end())
184 return It->second;
185
186 // TODO: Handle call instructions differently.
187 // For now, we treat them like other instructions
188 Embedding ArgEmb(Dimension, 0);
189 for (const auto &Op : I.operands()) {
190 // If the operand is defined elsewhere, we use its embedding
191 if (const auto *DefInst = dyn_cast<Instruction>(Op)) {
192 auto DefIt = InstVecMap.find(DefInst);
193 // Fixme (#159171): Ideally we should never miss an instruction
194 // embedding here.
195 // But when we have cyclic dependencies (e.g., phi
196 // nodes), we might miss the embedding. In such cases, we fall back to
197 // using the vocabulary embedding. This can be fixed by iterating to a
198 // fixed-point, or by using a simple solver for the set of simultaneous
199 // equations.
200 // Another case when we might miss an instruction embedding is when
201 // the operand instruction is in a different basic block that has not
202 // been processed yet. This can be fixed by processing the basic blocks
203 // in a topological order.
204 if (DefIt != InstVecMap.end())
205 ArgEmb += DefIt->second;
206 else
207 ArgEmb += Vocab[*Op];
208 }
209 // If the operand is not defined by an instruction, we use the
210 // vocabulary
211 else {
212 LLVM_DEBUG(errs() << "Using embedding from vocabulary for operand: "
213 << *Op << "=" << Vocab[*Op][0] << "\n");
214 ArgEmb += Vocab[*Op];
215 }
216 }
217 // Create the instruction vector by combining opcode, type, and arguments
218 // embeddings
219 auto InstVector =
220 Vocab[I.getOpcode()] + Vocab[I.getType()->getTypeID()] + ArgEmb;
221 if (const auto *IC = dyn_cast<CmpInst>(&I))
222 InstVector += Vocab[IC->getPredicate()];
223 InstVecMap[&I] = InstVector;
224 return InstVector;
225}
226
227// ==----------------------------------------------------------------------===//
228// VocabStorage
229//===----------------------------------------------------------------------===//
230
231VocabStorage::VocabStorage(std::vector<std::vector<Embedding>> &&SectionData)
232 : Sections(std::move(SectionData)), TotalSize([&] {
233 assert(!Sections.empty() && "Vocabulary has no sections");
234 // Compute total size across all sections
235 size_t Size = 0;
236 for (const auto &Section : Sections) {
237 assert(!Section.empty() && "Vocabulary section is empty");
238 Size += Section.size();
239 }
240 return Size;
241 }()),
242 Dimension([&] {
243 // Get dimension from the first embedding in the first section - all
244 // embeddings must have the same dimension
245 assert(!Sections.empty() && "Vocabulary has no sections");
246 assert(!Sections[0].empty() && "First section of vocabulary is empty");
247 unsigned ExpectedDim = static_cast<unsigned>(Sections[0][0].size());
248
249 // Verify that all embeddings across all sections have the same
250 // dimension
251 [[maybe_unused]] auto allSameDim =
252 [ExpectedDim](const std::vector<Embedding> &Section) {
253 return std::all_of(Section.begin(), Section.end(),
254 [ExpectedDim](const Embedding &Emb) {
255 return Emb.size() == ExpectedDim;
256 });
257 };
258 assert(std::all_of(Sections.begin(), Sections.end(), allSameDim) &&
259 "All embeddings must have the same dimension");
260
261 return ExpectedDim;
262 }()) {}
263
265 assert(SectionId < Storage->Sections.size() && "Invalid section ID");
266 assert(LocalIndex < Storage->Sections[SectionId].size() &&
267 "Local index out of range");
268 return Storage->Sections[SectionId][LocalIndex];
269}
270
272 ++LocalIndex;
273 // Check if we need to move to the next section
274 if (SectionId < Storage->getNumSections() &&
275 LocalIndex >= Storage->Sections[SectionId].size()) {
276 assert(LocalIndex == Storage->Sections[SectionId].size() &&
277 "Local index should be at the end of the current section");
278 LocalIndex = 0;
279 ++SectionId;
280 }
281 return *this;
282}
283
285 const const_iterator &Other) const {
286 return Storage == Other.Storage && SectionId == Other.SectionId &&
287 LocalIndex == Other.LocalIndex;
288}
289
291 const const_iterator &Other) const {
292 return !(*this == Other);
293}
294
296 const json::Value &ParsedVocabValue,
297 VocabMap &TargetVocab, unsigned &Dim) {
298 json::Path::Root Path("");
299 const json::Object *RootObj = ParsedVocabValue.getAsObject();
300 if (!RootObj)
302 "JSON root is not an object");
303
304 const json::Value *SectionValue = RootObj->get(Key);
305 if (!SectionValue)
307 "Missing '" + std::string(Key) +
308 "' section in vocabulary file");
309 if (!json::fromJSON(*SectionValue, TargetVocab, Path))
311 "Unable to parse '" + std::string(Key) +
312 "' section from vocabulary");
313
314 Dim = TargetVocab.begin()->second.size();
315 if (Dim == 0)
317 "Dimension of '" + std::string(Key) +
318 "' section of the vocabulary is zero");
319
320 if (!std::all_of(TargetVocab.begin(), TargetVocab.end(),
321 [Dim](const std::pair<StringRef, Embedding> &Entry) {
322 return Entry.second.size() == Dim;
323 }))
324 return createStringError(
326 "All vectors in the '" + std::string(Key) +
327 "' section of the vocabulary are not of the same dimension");
328
329 return Error::success();
330}
331
332// ==----------------------------------------------------------------------===//
333// Vocabulary
334//===----------------------------------------------------------------------===//
335
337 assert(Opcode >= 1 && Opcode <= MaxOpcodes && "Invalid opcode");
338#define HANDLE_INST(NUM, OPCODE, CLASS) \
339 if (Opcode == NUM) { \
340 return #OPCODE; \
341 }
342#include "llvm/IR/Instruction.def"
343#undef HANDLE_INST
344 return "UnknownOpcode";
345}
346
347// Helper function to classify an operand into OperandKind
357
358unsigned Vocabulary::getPredicateLocalIndex(CmpInst::Predicate P) {
361 else
364}
365
366CmpInst::Predicate Vocabulary::getPredicateFromLocalIndex(unsigned LocalIndex) {
367 unsigned fcmpRange =
369 if (LocalIndex < fcmpRange)
371 LocalIndex);
372 else
374 LocalIndex - fcmpRange);
375}
376
378 static SmallString<16> PredNameBuffer;
380 PredNameBuffer = "FCMP_";
381 else
382 PredNameBuffer = "ICMP_";
383 PredNameBuffer += CmpInst::getPredicateName(Pred);
384 return PredNameBuffer;
385}
386
388 assert(Pos < NumCanonicalEntries && "Position out of bounds in vocabulary");
389 // Opcode
390 if (Pos < MaxOpcodes)
391 return getVocabKeyForOpcode(Pos + 1);
392 // Type
393 if (Pos < OperandBaseOffset)
394 return getVocabKeyForCanonicalTypeID(
395 static_cast<CanonicalTypeID>(Pos - MaxOpcodes));
396 // Operand
397 if (Pos < PredicateBaseOffset)
399 static_cast<OperandKind>(Pos - OperandBaseOffset));
400 // Predicates
401 return getVocabKeyForPredicate(getPredicate(Pos - PredicateBaseOffset));
402}
403
404// For now, assume vocabulary is stable unless explicitly invalidated.
406 ModuleAnalysisManager::Invalidator &Inv) const {
407 auto PAC = PA.getChecker<IR2VecVocabAnalysis>();
408 return !(PAC.preservedWhenStateless());
409}
410
412 float DummyVal = 0.1f;
413
414 // Create sections for opcodes, types, operands, and predicates
415 // Order must match Vocabulary::Section enum
416 std::vector<std::vector<Embedding>> Sections;
417 Sections.reserve(4);
418
419 // Opcodes section
420 std::vector<Embedding> OpcodeSec;
421 OpcodeSec.reserve(MaxOpcodes);
422 for (unsigned I = 0; I < MaxOpcodes; ++I) {
423 OpcodeSec.emplace_back(Dim, DummyVal);
424 DummyVal += 0.1f;
425 }
426 Sections.push_back(std::move(OpcodeSec));
427
428 // Types section
429 std::vector<Embedding> TypeSec;
430 TypeSec.reserve(MaxCanonicalTypeIDs);
431 for (unsigned I = 0; I < MaxCanonicalTypeIDs; ++I) {
432 TypeSec.emplace_back(Dim, DummyVal);
433 DummyVal += 0.1f;
434 }
435 Sections.push_back(std::move(TypeSec));
436
437 // Operands section
438 std::vector<Embedding> OperandSec;
439 OperandSec.reserve(MaxOperandKinds);
440 for (unsigned I = 0; I < MaxOperandKinds; ++I) {
441 OperandSec.emplace_back(Dim, DummyVal);
442 DummyVal += 0.1f;
443 }
444 Sections.push_back(std::move(OperandSec));
445
446 // Predicates section
447 std::vector<Embedding> PredicateSec;
448 PredicateSec.reserve(MaxPredicateKinds);
449 for (unsigned I = 0; I < MaxPredicateKinds; ++I) {
450 PredicateSec.emplace_back(Dim, DummyVal);
451 DummyVal += 0.1f;
452 }
453 Sections.push_back(std::move(PredicateSec));
454
455 return VocabStorage(std::move(Sections));
456}
457
458namespace {
459using VocabMap = std::map<std::string, Embedding>;
460
461/// Read vocabulary JSON file and populate the section maps.
462Error readVocabularyFromFile(StringRef VocabFilePath, VocabMap &OpcVocab,
463 VocabMap &TypeVocab, VocabMap &ArgVocab) {
464 auto BufOrError =
465 MemoryBuffer::getFileOrSTDIN(VocabFilePath, /*IsText=*/true);
466 if (!BufOrError)
467 return createFileError(VocabFilePath, BufOrError.getError());
468
469 auto Content = BufOrError.get()->getBuffer();
470
471 Expected<json::Value> ParsedVocabValue = json::parse(Content);
472 if (!ParsedVocabValue)
473 return ParsedVocabValue.takeError();
474
475 unsigned OpcodeDim = 0, TypeDim = 0, ArgDim = 0;
476 if (auto Err = VocabStorage::parseVocabSection("Opcodes", *ParsedVocabValue,
477 OpcVocab, OpcodeDim))
478 return Err;
479
480 if (auto Err = VocabStorage::parseVocabSection("Types", *ParsedVocabValue,
481 TypeVocab, TypeDim))
482 return Err;
483
484 if (auto Err = VocabStorage::parseVocabSection("Arguments", *ParsedVocabValue,
485 ArgVocab, ArgDim))
486 return Err;
487
488 if (!(OpcodeDim == TypeDim && TypeDim == ArgDim))
490 "Vocabulary sections have different dimensions");
491
492 return Error::success();
493}
494} // anonymous namespace
495
496/// Generate VocabStorage from vocabulary maps.
497VocabStorage Vocabulary::buildVocabStorage(const VocabMap &OpcVocab,
498 const VocabMap &TypeVocab,
499 const VocabMap &ArgVocab) {
500
501 // Helper for handling missing entities in the vocabulary.
502 // Currently, we use a zero vector. In the future, we will throw an error to
503 // ensure that *all* known entities are present in the vocabulary.
504 auto handleMissingEntity = [](const std::string &Val) {
505 LLVM_DEBUG(errs() << Val
506 << " is not in vocabulary, using zero vector; This "
507 "would result in an error in future.\n");
508 ++VocabMissCounter;
509 };
510
511 unsigned Dim = OpcVocab.begin()->second.size();
512 assert(Dim > 0 && "Vocabulary dimension must be greater than zero");
513
514 // Handle Opcodes
515 std::vector<Embedding> NumericOpcodeEmbeddings(Vocabulary::MaxOpcodes,
516 Embedding(Dim));
517 for (unsigned Opcode : seq(0u, Vocabulary::MaxOpcodes)) {
518 StringRef VocabKey = Vocabulary::getVocabKeyForOpcode(Opcode + 1);
519 auto It = OpcVocab.find(VocabKey.str());
520 if (It != OpcVocab.end())
521 NumericOpcodeEmbeddings[Opcode] = It->second;
522 else
523 handleMissingEntity(VocabKey.str());
524 }
525
526 // Handle Types - only canonical types are present in vocabulary
527 std::vector<Embedding> NumericTypeEmbeddings(Vocabulary::MaxCanonicalTypeIDs,
528 Embedding(Dim));
529 for (unsigned CTypeID : seq(0u, Vocabulary::MaxCanonicalTypeIDs)) {
530 StringRef VocabKey = Vocabulary::getVocabKeyForCanonicalTypeID(
531 static_cast<Vocabulary::CanonicalTypeID>(CTypeID));
532 if (auto It = TypeVocab.find(VocabKey.str()); It != TypeVocab.end()) {
533 NumericTypeEmbeddings[CTypeID] = It->second;
534 continue;
535 }
536 handleMissingEntity(VocabKey.str());
537 }
538
539 // Handle Arguments/Operands
540 std::vector<Embedding> NumericArgEmbeddings(Vocabulary::MaxOperandKinds,
541 Embedding(Dim));
542 for (unsigned OpKind : seq(0u, Vocabulary::MaxOperandKinds)) {
544 StringRef VocabKey = Vocabulary::getVocabKeyForOperandKind(Kind);
545 auto It = ArgVocab.find(VocabKey.str());
546 if (It != ArgVocab.end()) {
547 NumericArgEmbeddings[OpKind] = It->second;
548 continue;
549 }
550 handleMissingEntity(VocabKey.str());
551 }
552
553 // Handle Predicates: part of Operands section. We look up predicate keys
554 // in ArgVocab.
555 std::vector<Embedding> NumericPredEmbeddings(Vocabulary::MaxPredicateKinds,
556 Embedding(Dim, 0));
557 for (unsigned PK : seq(0u, Vocabulary::MaxPredicateKinds)) {
558 StringRef VocabKey =
559 Vocabulary::getVocabKeyForPredicate(Vocabulary::getPredicate(PK));
560 auto It = ArgVocab.find(VocabKey.str());
561 if (It != ArgVocab.end()) {
562 NumericPredEmbeddings[PK] = It->second;
563 continue;
564 }
565 handleMissingEntity(VocabKey.str());
566 }
567
568 // Create section-based storage instead of flat vocabulary
569 // Order must match Vocabulary::Section enum
570 std::vector<std::vector<Embedding>> Sections(4);
571 Sections[static_cast<unsigned>(Section::Opcodes)] =
572 std::move(NumericOpcodeEmbeddings); // Section::Opcodes
573 Sections[static_cast<unsigned>(Section::CanonicalTypes)] =
574 std::move(NumericTypeEmbeddings); // Section::CanonicalTypes
575 Sections[static_cast<unsigned>(Section::Operands)] =
576 std::move(NumericArgEmbeddings); // Section::Operands
577 Sections[static_cast<unsigned>(Section::Predicates)] =
578 std::move(NumericPredEmbeddings); // Section::Predicates
579
580 // Create VocabStorage from organized sections
581 return VocabStorage(std::move(Sections));
582}
583
584// ==----------------------------------------------------------------------===//
585// Vocabulary
586//===----------------------------------------------------------------------===//
587
589 float OpcWeight, float TypeWeight,
590 float ArgWeight) {
591 VocabMap OpcVocab, TypeVocab, ArgVocab;
592 if (auto Err =
593 readVocabularyFromFile(VocabFilePath, OpcVocab, TypeVocab, ArgVocab))
594 return std::move(Err);
595
596 // Scale the vocabulary sections based on the provided weights
597 auto scaleVocabSection = [](VocabMap &Vocab, float Weight) {
598 for (auto &Entry : Vocab)
599 Entry.second *= Weight;
600 };
601 scaleVocabSection(OpcVocab, OpcWeight);
602 scaleVocabSection(TypeVocab, TypeWeight);
603 scaleVocabSection(ArgVocab, ArgWeight);
604
605 // Generate the numeric lookup vocabulary
606 return Vocabulary(buildVocabStorage(OpcVocab, TypeVocab, ArgVocab));
607}
608
609// ==----------------------------------------------------------------------===//
610// IR2VecVocabAnalysis
611//===----------------------------------------------------------------------===//
612
613void IR2VecVocabAnalysis::emitError(Error Err) {
614 handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
615 reportFatalUsageError(Twine("error reading vocabulary: ") + EI.message());
616 });
617}
618
621 // If vocabulary is already populated by the constructor, use it.
622 if (Vocab.has_value())
623 return Vocabulary(std::move(Vocab.value()));
624
625 // Otherwise, try to read from the vocabulary file specified via CLI.
626 const AnalysisOptions &Opts = getAnalysisOptions(M);
627 if (Opts.ir2vec_vocab_path.empty())
628 // FIXME: Use default vocabulary
630 "IR2Vec vocabulary file path not specified; You may need to "
631 "set it using --ir2vec-vocab-path");
632
633 // Use the static factory method to load the vocabulary.
634 auto VocabOrErr =
635 Vocabulary::fromFile(Opts.ir2vec_vocab_path, Opts.ir2vec_opc_weight,
636 Opts.ir2vec_type_weight, Opts.ir2vec_arg_weight);
637 if (!VocabOrErr)
638 emitError(VocabOrErr.takeError());
639
640 return std::move(*VocabOrErr);
641}
642
643// ==----------------------------------------------------------------------===//
644// Printer Passes
645//===----------------------------------------------------------------------===//
646
649 auto &Vocabulary = MAM.getResult<IR2VecVocabAnalysis>(M);
650 assert(Vocabulary.isValid() && "IR2Vec Vocabulary is invalid");
651
652 IR2VecKind Kind = getAnalysisOptions(M).ir2vec_kind;
653 for (Function &F : M) {
654 auto Emb = Embedder::create(Kind, F, Vocabulary);
655 if (!Emb) {
656 OS << "Error creating IR2Vec embeddings \n";
657 continue;
658 }
659
660 OS << "IR2Vec embeddings for function " << F.getName() << ":\n";
661 OS << "Function vector: ";
662 Emb->getFunctionVector().print(OS);
663
664 OS << "Basic block vectors:\n";
665 for (const BasicBlock &BB : F) {
666 OS << "Basic block: " << BB.getName() << ":\n";
667 Emb->getBBVector(BB).print(OS);
668 }
669
670 OS << "Instruction vectors:\n";
671 for (const BasicBlock &BB : F) {
672 for (const Instruction &I : BB) {
673 OS << "Instruction: ";
674 I.print(OS);
675 Emb->getInstVector(I).print(OS);
676 }
677 }
678 }
679 return PreservedAnalyses::all();
680}
681
684 auto &IR2VecVocabulary = MAM.getResult<IR2VecVocabAnalysis>(M);
685 assert(IR2VecVocabulary.isValid() && "IR2Vec Vocabulary is invalid");
686
687 // Print each entry
688 unsigned Pos = 0;
689 for (const auto &Entry : IR2VecVocabulary) {
690 OS << "Key: " << IR2VecVocabulary.getStringKey(Pos++) << ": ";
691 Entry.print(OS);
692 }
693 return PreservedAnalyses::all();
694}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
ModuleAnalysisManager MAM
Provides some synthesis utilities to produce sequences of values.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
static LLVM_ABI StringRef getPredicateName(Predicate P)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
Base class for error info classes.
Definition Error.h:44
virtual std::string message() const
Return the error message as a string.
Definition Error.h:52
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition IR2Vec.cpp:647
This analysis provides the vocabulary for IR2Vec.
Definition IR2Vec.h:628
ir2vec::Vocabulary Result
Definition IR2Vec.h:638
LLVM_ABI Result run(Module &M, ModuleAnalysisManager &MAM)
Definition IR2Vec.cpp:620
static LLVM_ABI AnalysisKey Key
Definition IR2Vec.h:634
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition IR2Vec.cpp:682
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition Analysis.h:275
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI std::unique_ptr< Embedder > create(IR2VecKind Mode, const Function &F, const Vocabulary &Vocab)
Factory method to create an Embedder object.
Definition IR2Vec.cpp:134
const Vocabulary & Vocab
Definition IR2Vec.h:547
const unsigned Dimension
Dimension of the vector representation; captured from the input vocabulary.
Definition IR2Vec.h:550
LLVM_ABI Embedding computeEmbeddings() const
Function to compute embeddings.
Definition IR2Vec.cpp:145
const Function & F
Definition IR2Vec.h:546
Iterator support for section-based access.
Definition IR2Vec.h:199
const_iterator(const VocabStorage *Storage, unsigned SectionId, size_t LocalIndex)
Definition IR2Vec.h:205
LLVM_ABI bool operator!=(const const_iterator &Other) const
Definition IR2Vec.cpp:290
LLVM_ABI const_iterator & operator++()
Definition IR2Vec.cpp:271
LLVM_ABI const Embedding & operator*() const
Definition IR2Vec.cpp:264
LLVM_ABI bool operator==(const const_iterator &Other) const
Definition IR2Vec.cpp:284
Generic storage class for section-based vocabularies.
Definition IR2Vec.h:154
static LLVM_ABI Error parseVocabSection(StringRef Key, const json::Value &ParsedVocabValue, VocabMap &TargetVocab, unsigned &Dim)
Parse a vocabulary section from JSON and populate the target vocabulary map.
Definition IR2Vec.cpp:295
unsigned getNumSections() const
Get number of sections.
Definition IR2Vec.h:182
size_t size() const
Get total number of entries across all sections.
Definition IR2Vec.h:179
VocabStorage()=default
Default constructor creates empty storage (invalid state)
const_iterator begin() const
Definition IR2Vec.h:215
std::map< std::string, Embedding > VocabMap
Definition IR2Vec.h:220
Class for storing and accessing the IR2Vec vocabulary.
Definition IR2Vec.h:245
LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &Inv) const
Definition IR2Vec.cpp:405
static LLVM_ABI Expected< Vocabulary > fromFile(StringRef VocabFilePath, float OpcWeight=1.0, float TypeWeight=0.5, float ArgWeight=0.2)
Create a Vocabulary by loading embeddings from a JSON file.
Definition IR2Vec.cpp:588
static LLVM_ABI OperandKind getOperandKind(const Value *Op)
Function to classify an operand into OperandKind.
Definition IR2Vec.cpp:348
static StringRef getVocabKeyForOperandKind(OperandKind Kind)
Function to get vocabulary key for a given OperandKind.
Definition IR2Vec.h:364
friend class llvm::IR2VecVocabAnalysis
Definition IR2Vec.h:246
static LLVM_ABI StringRef getStringKey(unsigned Pos)
Returns the string key for a given index position in the vocabulary.
Definition IR2Vec.cpp:387
static constexpr unsigned MaxCanonicalTypeIDs
Definition IR2Vec.h:316
static constexpr unsigned MaxOperandKinds
Definition IR2Vec.h:318
OperandKind
Operand kinds supported by IR2Vec Vocabulary.
Definition IR2Vec.h:302
static LLVM_ABI StringRef getVocabKeyForPredicate(CmpInst::Predicate P)
Function to get vocabulary key for a given predicate.
Definition IR2Vec.cpp:377
static LLVM_ABI StringRef getVocabKeyForOpcode(unsigned Opcode)
Function to get vocabulary key for a given Opcode.
Definition IR2Vec.cpp:336
bool isValid() const
Definition IR2Vec.h:344
static LLVM_ABI VocabStorage createDummyVocabForTest(unsigned Dim=1)
Create a dummy vocabulary for testing purposes.
Definition IR2Vec.cpp:411
static constexpr unsigned MaxPredicateKinds
Definition IR2Vec.h:322
CanonicalTypeID
Canonical type IDs supported by IR2Vec Vocabulary.
Definition IR2Vec.h:284
An Object is a JSON object, which maps strings to heterogenous JSON values.
Definition JSON.h:98
LLVM_ABI Value * get(StringRef K)
Definition JSON.cpp:30
The root is the trivial Path to the root value.
Definition JSON.h:700
A "cursor" marking a position within a Value.
Definition JSON.h:653
A Value is an JSON value of unknown type.
Definition JSON.h:291
const json::Object * getAsObject() const
Definition JSON.h:465
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
LLVM_ABI IR2VecKind getEmbeddingKind(const LLVMContext &C)
Return -ir2vec-kind.
Definition IR2Vec.cpp:42
LLVM_ABI StringRef getVocabFile(const LLVMContext &C)
Return -ir2vec-vocab-path.
Definition IR2Vec.cpp:39
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
Definition JSON.cpp:681
bool fromJSON(const Value &E, std::string &Out, Path P)
Definition JSON.h:729
ir2vec::Embedding Embedding
Definition MIR2Vec.h:79
This is an optimization pass for GlobalISel generic memory operations.
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition Error.h:1415
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition Error.h:1013
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ illegal_byte_sequence
Definition Errc.h:52
@ invalid_argument
Definition Errc.h:56
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
IR2VecKind
IR2Vec computes two kinds of embeddings: Symbolic and Flow-aware.
Definition IR2Vec.h:70
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:102
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Other
Any other memory.
Definition ModRef.h:68
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
Embedding is a datatype that wraps std::vector<double>.
Definition IR2Vec.h:85
LLVM_ABI bool approximatelyEquals(const Embedding &RHS, double Tolerance=1e-4) const
Returns true if the embedding is approximately equal to the RHS embedding within the specified tolera...
Definition IR2Vec.cpp:110
LLVM_ABI Embedding & operator+=(const Embedding &RHS)
Arithmetic operators.
Definition IR2Vec.cpp:65
LLVM_ABI Embedding operator-(const Embedding &RHS) const
Definition IR2Vec.cpp:85
LLVM_ABI Embedding & operator-=(const Embedding &RHS)
Definition IR2Vec.cpp:78
LLVM_ABI Embedding operator*(double Factor) const
Definition IR2Vec.cpp:97
size_t size() const
Definition IR2Vec.h:98
LLVM_ABI Embedding & operator*=(double Factor)
Definition IR2Vec.cpp:91
LLVM_ABI Embedding operator+(const Embedding &RHS) const
Definition IR2Vec.cpp:72
LLVM_ABI Embedding & scaleAndAdd(const Embedding &Src, float Factor)
Adds Src Embedding scaled by Factor with the called Embedding.
Definition IR2Vec.cpp:103
LLVM_ABI void print(raw_ostream &OS) const
Definition IR2Vec.cpp:123