LLVM 24.0.0git
IR2Vec.h
Go to the documentation of this file.
1//===- IR2Vec.h - Implementation of IR2Vec ----------------------*- C++ -*-===//
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 defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis),
11/// the core ir2vec::Embedder interface for generating IR embeddings,
12/// and related utilities like the IR2VecPrinterPass.
13///
14/// Program Embeddings are typically or derived-from a learned
15/// representation of the program. Such embeddings are used to represent the
16/// programs as input to machine learning algorithms. IR2Vec represents the
17/// LLVM IR as embeddings.
18///
19/// The IR2Vec algorithm is described in the following paper:
20///
21/// IR2Vec: LLVM IR Based Scalable Program Embeddings, S. VenkataKeerthy,
22/// Rohit Aggarwal, Shalini Jain, Maunendra Sankar Desarkar, Ramakrishna
23/// Upadrasta, and Y. N. Srikant, ACM Transactions on Architecture and
24/// Code Optimization (TACO), 2020. https://doi.org/10.1145/3418463.
25/// https://arxiv.org/abs/1909.06228
26///
27/// To obtain embeddings:
28/// First run IR2VecVocabAnalysis to populate the vocabulary.
29/// Then, use the Embedder interface to generate embeddings for the desired IR
30/// entities. See the documentation for more details -
31/// https://llvm.org/docs/MLGO.html#ir2vec-embeddings
32///
33//===----------------------------------------------------------------------===//
34
35#ifndef LLVM_ANALYSIS_IR2VEC_H
36#define LLVM_ANALYSIS_IR2VEC_H
37
38#include "llvm/ADT/DenseMap.h"
40#include "llvm/IR/PassManager.h"
41#include "llvm/IR/Type.h"
44#include "llvm/Support/JSON.h"
45#include <array>
46#include <map>
47#include <optional>
48
49namespace llvm {
50
51class Module;
52class BasicBlock;
53class Instruction;
54class Function;
55class Value;
56class raw_ostream;
57class LLVMContext;
59
60/// IR2Vec computes two kinds of embeddings: Symbolic and Flow-aware.
61/// Symbolic embeddings capture the "syntactic" and "statistical correlation"
62/// of the IR entities. Flow-aware embeddings build on top of symbolic
63/// embeddings and additionally capture the flow information in the IR.
64/// IR2VecKind is used to specify the type of embeddings to generate.
65/// Note: Implementation of FlowAware embeddings is not same as the one
66/// described in the paper. The current implementation is a simplified version
67/// that captures the flow information (SSA-based use-defs) without tracing
68/// through memory level use-defs in the embedding computation described in the
69/// paper.
71
72namespace ir2vec {
73
74/// Return -ir2vec-vocab-path.
76/// Return -ir2vec-kind.
78
79/// Embedding is a datatype that wraps std::vector<double>. It provides
80/// additional functionality for arithmetic and comparison operations.
81/// It is meant to be used *like* std::vector<double> but is more restrictive
82/// in the sense that it does not allow the user to change the size of the
83/// embedding vector. The dimension of the embedding is fixed at the time of
84/// construction of Embedding object. But the elements can be modified in-place.
85struct Embedding {
86private:
87 std::vector<double> Data;
88
89public:
90 Embedding() = default;
91 Embedding(const std::vector<double> &V) : Data(V) {}
92 Embedding(std::vector<double> &&V) : Data(std::move(V)) {}
93 Embedding(std::initializer_list<double> IL) : Data(IL) {}
94
95 explicit Embedding(size_t Size) : Data(Size, 0.0) {}
96 Embedding(size_t Size, double InitialValue) : Data(Size, InitialValue) {}
97
98 size_t size() const { return Data.size(); }
99 bool empty() const { return Data.empty(); }
100
101 double &operator[](size_t Itr) {
102 assert(Itr < Data.size() && "Index out of bounds");
103 return Data[Itr];
104 }
105
106 const double &operator[](size_t Itr) const {
107 assert(Itr < Data.size() && "Index out of bounds");
108 return Data[Itr];
109 }
110
111 using iterator = std::vector<double>::iterator;
112 using const_iterator = std::vector<double>::const_iterator;
113
114 iterator begin() { return Data.begin(); }
115 iterator end() { return Data.end(); }
116 const_iterator begin() const { return Data.begin(); }
117 const_iterator end() const { return Data.end(); }
118 const_iterator cbegin() const { return Data.cbegin(); }
119 const_iterator cend() const { return Data.cend(); }
120
121 const std::vector<double> &getData() const { return Data; }
122
123 /// Arithmetic operators
128 LLVM_ABI Embedding &operator*=(double Factor);
129 LLVM_ABI Embedding operator*(double Factor) const;
130
131 /// Adds Src Embedding scaled by Factor with the called Embedding.
132 /// Called_Embedding += Src * Factor
133 LLVM_ABI Embedding &scaleAndAdd(const Embedding &Src, float Factor);
134
135 /// Returns true if the embedding is approximately equal to the RHS embedding
136 /// within the specified tolerance.
138 double Tolerance = 1e-4) const;
139
140 /// Returns true if all elements of the embedding are zero.
141 bool isZero() const {
142 return llvm::all_of(Data, [](double D) { return D == 0.0; });
143 }
144
145 LLVM_ABI void print(raw_ostream &OS) const;
146};
147
150
151/// Generic storage class for section-based vocabularies.
152/// VocabStorage provides a generic foundation for storing and accessing
153/// embeddings organized into sections.
155private:
156 /// Section-based storage
157 std::vector<std::vector<Embedding>> Sections;
158
159 // Fixme: Check if these members can be made const (and delete move
160 // assignment) after changing Vocabulary creation by using static factory
161 // methods.
162 size_t TotalSize = 0;
163 unsigned Dimension = 0;
164
165public:
166 /// Default constructor creates empty storage (invalid state)
167 VocabStorage() = default;
168
169 /// Create a VocabStorage with pre-organized section data
170 LLVM_ABI VocabStorage(std::vector<std::vector<Embedding>> &&SectionData);
171
174
175 VocabStorage(const VocabStorage &) = delete;
177
178 /// Get total number of entries across all sections
179 size_t size() const { return TotalSize; }
180
181 /// Get number of sections
182 unsigned getNumSections() const {
183 return static_cast<unsigned>(Sections.size());
184 }
185
186 /// Section-based access: Storage[sectionId][localIndex]
187 const std::vector<Embedding> &operator[](unsigned SectionId) const {
188 assert(SectionId < Sections.size() && "Invalid section ID");
189 return Sections[SectionId];
190 }
191
192 /// Get vocabulary dimension
193 unsigned getDimension() const { return Dimension; }
194
195 /// Check if vocabulary is valid (has data)
196 bool isValid() const { return TotalSize > 0; }
197
198 /// Iterator support for section-based access
200 const VocabStorage *Storage;
201 unsigned SectionId = 0;
202 size_t LocalIndex = 0;
203
204 public:
205 const_iterator(const VocabStorage *Storage, unsigned SectionId,
206 size_t LocalIndex)
207 : Storage(Storage), SectionId(SectionId), LocalIndex(LocalIndex) {}
208
209 LLVM_ABI const Embedding &operator*() const;
211 LLVM_ABI bool operator==(const const_iterator &Other) const;
212 LLVM_ABI bool operator!=(const const_iterator &Other) const;
213 };
214
215 const_iterator begin() const { return const_iterator(this, 0, 0); }
217 return const_iterator(this, getNumSections(), 0);
218 }
219
220 using VocabMap = std::map<std::string, Embedding>;
221 /// Parse a vocabulary section from JSON and populate the target vocabulary
222 /// map.
224 const json::Value &ParsedVocabValue,
225 VocabMap &TargetVocab, unsigned &Dim);
226};
227
228/// Class for storing and accessing the IR2Vec vocabulary.
229/// The Vocabulary class manages seed embeddings for LLVM IR entities. The
230/// seed embeddings are the initial learned representations of the entities
231/// of LLVM IR. The IR2Vec representation for a given IR is derived from these
232/// seed embeddings.
233///
234/// The vocabulary contains the seed embeddings for three types of entities:
235/// instruction opcodes, types, and operands. Types are grouped/canonicalized
236/// for better learning (e.g., all float variants map to FloatTy). The
237/// vocabulary abstracts away the canonicalization effectively, the exposed APIs
238/// handle all the known LLVM IR opcodes, types and operands.
239///
240/// This class helps populate the seed embeddings in an internal vector-based
241/// ADT. It provides logic to map every IR entity to a specific slot index or
242/// position in this vector, enabling O(1) embedding lookup while avoiding
243/// unnecessary computations involving string based lookups while generating the
244/// embeddings.
247
248 // Vocabulary Layout:
249 // +----------------+------------------------------------------------------+
250 // | Entity Type | Index Range |
251 // +----------------+------------------------------------------------------+
252 // | Opcodes | [0 .. (MaxOpcodes-1)] |
253 // | Canonical Types| [MaxOpcodes .. (MaxOpcodes+MaxCanonicalTypeIDs-1)] |
254 // | Operands | [(MaxOpcodes+MaxCanonicalTypeIDs) .. NumCanEntries] |
255 // +----------------+------------------------------------------------------+
256 // Note: MaxOpcodes is the number of unique opcodes supported by LLVM IR.
257 // MaxCanonicalTypeIDs is the number of canonicalized type IDs.
258 // "Similar" LLVM Types are grouped/canonicalized together. E.g., all
259 // float variants (FloatTy, DoubleTy, HalfTy, etc.) map to
260 // CanonicalTypeID::FloatTy. This helps reduce the vocabulary size
261 // and improves learning. Operands include Comparison predicates
262 // (ICmp/FCmp) along with other operand types. This can be extended to
263 // include other specializations in future.
264 enum class Section : unsigned {
265 Opcodes = 0,
266 CanonicalTypes = 1,
267 Operands = 2,
268 Predicates = 3,
269 MaxSections
270 };
271
272 // Use section-based storage for better organization and efficiency
273 VocabStorage Storage;
274
275 static constexpr unsigned NumICmpPredicates =
276 static_cast<unsigned>(CmpInst::LAST_ICMP_PREDICATE) -
277 static_cast<unsigned>(CmpInst::FIRST_ICMP_PREDICATE) + 1;
278 static constexpr unsigned NumFCmpPredicates =
279 static_cast<unsigned>(CmpInst::LAST_FCMP_PREDICATE) -
280 static_cast<unsigned>(CmpInst::FIRST_FCMP_PREDICATE) + 1;
281
282public:
283 /// Canonical type IDs supported by IR2Vec Vocabulary
300
301 /// Operand kinds supported by IR2Vec Vocabulary
309
310 /// Vocabulary layout constants
311#define LAST_OTHER_INST(NUM) static constexpr unsigned MaxOpcodes = NUM;
312#include "llvm/IR/Instruction.def"
313#undef LAST_OTHER_INST
314
315 static constexpr unsigned MaxTypeIDs = Type::TypeID::TargetExtTyID + 1;
316 static constexpr unsigned MaxCanonicalTypeIDs =
317 static_cast<unsigned>(CanonicalTypeID::MaxCanonicalType);
318 static constexpr unsigned MaxOperandKinds =
319 static_cast<unsigned>(OperandKind::MaxOperandKind);
320 // CmpInst::Predicate has gaps. We want the vocabulary to be dense without
321 // empty slots.
322 static constexpr unsigned MaxPredicateKinds =
323 NumICmpPredicates + NumFCmpPredicates;
324
325 Vocabulary() = default;
326 Vocabulary(VocabStorage &&Storage) : Storage(std::move(Storage)) {}
327
328 Vocabulary(const Vocabulary &) = delete;
329 Vocabulary &operator=(const Vocabulary &) = delete;
330
331 Vocabulary(Vocabulary &&) = default;
333
334 /// Create a Vocabulary by loading embeddings from a JSON file.
335 /// This is the primary entry point for programmatic vocabulary creation,
336 /// suitable for use in Python bindings or other contexts where command-line
337 /// options are not available. Weights are applied to scale the embeddings
338 /// for opcodes, types, and arguments respectively.
339 LLVM_ABI static Expected<Vocabulary> fromFile(StringRef VocabFilePath,
340 float OpcWeight = 1.0,
341 float TypeWeight = 0.5,
342 float ArgWeight = 0.2);
343
344 bool isValid() const { return Storage.size() == NumCanonicalEntries; }
345
346 unsigned getDimension() const {
347 assert(isValid() && "IR2Vec Vocabulary is invalid");
348 return Storage.getDimension();
349 }
350
351 /// Total number of entries (opcodes + canonicalized types + operand kinds +
352 /// predicates)
353 static constexpr size_t getCanonicalSize() { return NumCanonicalEntries; }
354
355 /// Function to get vocabulary key for a given Opcode
356 LLVM_ABI static StringRef getVocabKeyForOpcode(unsigned Opcode);
357
358 /// Function to get vocabulary key for a given TypeID
360 return getVocabKeyForCanonicalTypeID(getCanonicalTypeID(TypeID));
361 }
362
363 /// Function to get vocabulary key for a given OperandKind
365 unsigned Index = static_cast<unsigned>(Kind);
366 assert(Index < MaxOperandKinds && "Invalid OperandKind");
367 return OperandKindNames[Index];
368 }
369
370 /// Function to classify an operand into OperandKind
372
373 /// Function to get vocabulary key for a given predicate
375
376 /// Functions to return flat index
377 static unsigned getIndex(unsigned Opcode) {
378 assert(Opcode >= 1 && Opcode <= MaxOpcodes && "Invalid opcode");
379 return Opcode - 1; // Convert to zero-based index
380 }
381
382 static unsigned getIndex(Type::TypeID TypeID) {
383 assert(static_cast<unsigned>(TypeID) < MaxTypeIDs && "Invalid type ID");
384 return MaxOpcodes + static_cast<unsigned>(getCanonicalTypeID(TypeID));
385 }
386
387 static unsigned getIndex(const Value &Op) {
388 unsigned Index = static_cast<unsigned>(getOperandKind(&Op));
389 assert(Index < MaxOperandKinds && "Invalid OperandKind");
390 return OperandBaseOffset + Index;
391 }
392
393 static unsigned getIndex(CmpInst::Predicate P) {
394 return PredicateBaseOffset + getPredicateLocalIndex(P);
395 }
396
397 /// Accessors to get the embedding for a given entity.
398 const ir2vec::Embedding &operator[](unsigned Opcode) const {
399 assert(Opcode >= 1 && Opcode <= MaxOpcodes && "Invalid opcode");
400 return Storage[static_cast<unsigned>(Section::Opcodes)][Opcode - 1];
401 }
402
404 assert(static_cast<unsigned>(TypeID) < MaxTypeIDs && "Invalid type ID");
405 unsigned LocalIndex = static_cast<unsigned>(getCanonicalTypeID(TypeID));
406 return Storage[static_cast<unsigned>(Section::CanonicalTypes)][LocalIndex];
407 }
408
409 const ir2vec::Embedding &operator[](const Value &Arg) const {
410 unsigned LocalIndex = static_cast<unsigned>(getOperandKind(&Arg));
411 assert(LocalIndex < MaxOperandKinds && "Invalid OperandKind");
412 return Storage[static_cast<unsigned>(Section::Operands)][LocalIndex];
413 }
414
416 unsigned LocalIndex = getPredicateLocalIndex(P);
417 return Storage[static_cast<unsigned>(Section::Predicates)][LocalIndex];
418 }
419
420 /// Const Iterator type aliases
422
424 assert(isValid() && "IR2Vec Vocabulary is invalid");
425 return Storage.begin();
426 }
427
428 const_iterator cbegin() const { return begin(); }
429
431 assert(isValid() && "IR2Vec Vocabulary is invalid");
432 return Storage.end();
433 }
434
435 const_iterator cend() const { return end(); }
436
437 /// Returns the string key for a given index position in the vocabulary.
438 /// This is useful for debugging or printing the vocabulary. Do not use this
439 /// for embedding generation as string based lookups are inefficient.
440 LLVM_ABI static StringRef getStringKey(unsigned Pos);
441
442 /// Create a dummy vocabulary for testing purposes.
443 LLVM_ABI static VocabStorage createDummyVocabForTest(unsigned Dim = 1);
444
445 LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA,
446 ModuleAnalysisManager::Invalidator &Inv) const;
447
448private:
449 constexpr static unsigned NumCanonicalEntries =
451
452 // Base offsets for flat index computation
453 constexpr static unsigned OperandBaseOffset =
454 MaxOpcodes + MaxCanonicalTypeIDs;
455 constexpr static unsigned PredicateBaseOffset =
456 OperandBaseOffset + MaxOperandKinds;
457
458 /// Functions for predicate index calculations
459 LLVM_ABI static unsigned getPredicateLocalIndex(CmpInst::Predicate P);
461 getPredicateFromLocalIndex(unsigned LocalIndex);
462
463 /// String mappings for CanonicalTypeID values
464 static constexpr StringLiteral CanonicalTypeNames[] = {
465 "FloatTy", "VoidTy", "LabelTy", "MetadataTy", "VectorTy",
466 "TokenTy", "IntegerTy", "ByteTy", "FunctionTy", "PointerTy",
467 "StructTy", "ArrayTy", "UnknownTy"};
468 static_assert(std::size(CanonicalTypeNames) ==
469 static_cast<unsigned>(CanonicalTypeID::MaxCanonicalType),
470 "CanonicalTypeNames array size must match MaxCanonicalType");
471
472 /// String mappings for OperandKind values
473 static constexpr StringLiteral OperandKindNames[] = {"Function", "Pointer",
474 "Constant", "Variable"};
475 static_assert(std::size(OperandKindNames) ==
476 static_cast<unsigned>(OperandKind::MaxOperandKind),
477 "OperandKindNames array size must match MaxOperandKind");
478
479 /// Every known TypeID defined in llvm/IR/Type.h is expected to have a
480 /// corresponding mapping here in the same order as enum Type::TypeID.
481 static constexpr std::array<CanonicalTypeID, MaxTypeIDs> TypeIDMapping = {{
482 CanonicalTypeID::FloatTy, // HalfTyID = 0
483 CanonicalTypeID::FloatTy, // BFloatTyID
484 CanonicalTypeID::FloatTy, // FloatTyID
485 CanonicalTypeID::FloatTy, // DoubleTyID
486 CanonicalTypeID::FloatTy, // X86_FP80TyID
487 CanonicalTypeID::FloatTy, // FP128TyID
488 CanonicalTypeID::FloatTy, // PPC_FP128TyID
489 CanonicalTypeID::VoidTy, // VoidTyID
490 CanonicalTypeID::LabelTy, // LabelTyID
491 CanonicalTypeID::MetadataTy, // MetadataTyID
492 CanonicalTypeID::VectorTy, // X86_AMXTyID
493 CanonicalTypeID::TokenTy, // TokenTyID
494 CanonicalTypeID::IntegerTy, // IntegerTyID
495 CanonicalTypeID::ByteTy, // ByteTyID
496 CanonicalTypeID::FunctionTy, // FunctionTyID
497 CanonicalTypeID::PointerTy, // PointerTyID
498 CanonicalTypeID::StructTy, // StructTyID
499 CanonicalTypeID::ArrayTy, // ArrayTyID
500 CanonicalTypeID::VectorTy, // FixedVectorTyID
501 CanonicalTypeID::VectorTy, // ScalableVectorTyID
502 CanonicalTypeID::PointerTy, // TypedPointerTyID
503 CanonicalTypeID::UnknownTy // TargetExtTyID
504 }};
505 static_assert(TypeIDMapping.size() == MaxTypeIDs,
506 "TypeIDMapping must cover all Type::TypeID values");
507
508 /// Function to get vocabulary key for canonical type by enum
509 static StringRef getVocabKeyForCanonicalTypeID(CanonicalTypeID CType) {
510 unsigned Index = static_cast<unsigned>(CType);
511 assert(Index < MaxCanonicalTypeIDs && "Invalid CanonicalTypeID");
512 return CanonicalTypeNames[Index];
513 }
514
515 /// Function to convert TypeID to CanonicalTypeID
516 static CanonicalTypeID getCanonicalTypeID(Type::TypeID TypeID) {
517 unsigned Index = static_cast<unsigned>(TypeID);
518 assert(Index < MaxTypeIDs && "Invalid TypeID");
519 return TypeIDMapping[Index];
520 }
521
522 /// Function to get the predicate enum value for a given index. Index is
523 /// relative to the predicates section of the vocabulary. E.g., Index 0
524 /// corresponds to the first predicate.
525 LLVM_ABI static CmpInst::Predicate getPredicate(unsigned Index) {
526 assert(Index < MaxPredicateKinds && "Invalid predicate index");
527 return getPredicateFromLocalIndex(Index);
528 }
529
530 using VocabMap = std::map<std::string, Embedding>;
531
532 /// Generate VocabStorage from vocabulary maps.
533 static VocabStorage buildVocabStorage(const VocabMap &OpcVocab,
534 const VocabMap &TypeVocab,
535 const VocabMap &ArgVocab);
536};
537
538/// Embedder provides the interface to generate embeddings (vector
539/// representations) for instructions, basic blocks, and functions. The
540/// vector representations are generated using IR2Vec algorithms.
541///
542/// The Embedder class is an abstract class and it is intended to be
543/// subclassed for different IR2Vec algorithms like Symbolic and Flow-aware.
544class Embedder {
545protected:
546 const Function &F;
548
549 /// Dimension of the vector representation; captured from the input vocabulary
550 const unsigned Dimension;
551
553 : F(F), Vocab(Vocab), Dimension(Vocab.getDimension()) {}
554
555 /// Function to compute embeddings.
557
558 /// Function to compute the embedding for a given basic block.
560
561 /// Function to compute the embedding for a given instruction.
562 /// Specific to the kind of embeddings being computed.
563 virtual Embedding computeEmbeddings(const Instruction &I) const = 0;
564
565public:
566 virtual ~Embedder() = default;
567
568 /// Factory method to create an Embedder object.
569 LLVM_ABI static std::unique_ptr<Embedder>
571
572 /// Computes and returns the embedding for a given instruction in the function
573 /// F
575 return computeEmbeddings(I);
576 }
577
578 /// Computes and returns the embedding for a given basic block in the function
579 /// F
581 return computeEmbeddings(BB);
582 }
583
584 /// Computes and returns the embedding for the current function.
586
587 /// Invalidate embeddings if cached. The embeddings may not be relevant
588 /// anymore when the IR changes due to transformations. In such cases, the
589 /// cached embeddings should be invalidated to ensure
590 /// correctness/recomputation. This is a no-op for SymbolicEmbedder but
591 /// removes all the cached entries in FlowAwareEmbedder.
592 virtual void invalidateEmbeddings() {}
593};
594
595/// Class for computing the Symbolic embeddings of IR2Vec.
596/// Symbolic embeddings are constructed based on the entity-level
597/// representations obtained from the Vocabulary.
599private:
600 Embedding computeEmbeddings(const Instruction &I) const override;
601
602public:
605};
606
607/// Class for computing the Flow-aware embeddings of IR2Vec.
608/// Flow-aware embeddings build on the vocabulary, just like Symbolic
609/// embeddings, and additionally capture the flow information in the IR.
611private:
612 // FlowAware embeddings would benefit from caching instruction embeddings as
613 // they are reused while computing the embeddings of other instructions.
614 mutable InstEmbeddingsMap InstVecMap;
615 Embedding computeEmbeddings(const Instruction &I) const override;
616
617public:
620 void invalidateEmbeddings() override { InstVecMap.clear(); }
621};
622
623} // namespace ir2vec
624
625/// This analysis provides the vocabulary for IR2Vec. The vocabulary provides a
626/// mapping between an entity of the IR (like opcode, type, argument, etc.) and
627/// its corresponding embedding.
628class IR2VecVocabAnalysis : public AnalysisInfoMixin<IR2VecVocabAnalysis> {
629 std::optional<ir2vec::VocabStorage> Vocab;
630
631 void emitError(Error Err);
632
633public:
637 : Vocab(std::move(Vocab)) {}
640};
641
642/// This pass prints the IR2Vec embeddings for instructions, basic blocks, and
643/// functions.
644class IR2VecPrinterPass : public RequiredPassInfoMixin<IR2VecPrinterPass> {
645 raw_ostream &OS;
646
647public:
648 explicit IR2VecPrinterPass(raw_ostream &OS) : OS(OS) {}
650};
651
652/// This pass prints the embeddings in the vocabulary
654 : public RequiredPassInfoMixin<IR2VecVocabPrinterPass> {
655 raw_ostream &OS;
656
657public:
658 explicit IR2VecVocabPrinterPass(raw_ostream &OS) : OS(OS) {}
660};
661
662} // namespace llvm
663
664#endif // LLVM_ANALYSIS_IR2VEC_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ABI
Definition Compiler.h:211
This file defines the DenseMap class.
Provides ErrorOr<T> smart pointer.
This header defines various interfaces for pass management in LLVM.
This file supports working with JSON data.
#define I(x, y, z)
Definition MD5.cpp:57
Type::TypeID TypeID
#define P(N)
ModuleAnalysisManager MAM
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Value * RHS
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
IR2VecPrinterPass(raw_ostream &OS)
Definition IR2Vec.h:648
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition IR2Vec.cpp:647
This analysis provides the vocabulary for IR2Vec.
Definition IR2Vec.h:628
IR2VecVocabAnalysis(ir2vec::VocabStorage &&Vocab)
Definition IR2Vec.h:636
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
IR2VecVocabPrinterPass(raw_ostream &OS)
Definition IR2Vec.h:658
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
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
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition StringRef.h:888
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
TypeID
Definitions of all of the base types for the Type system.
Definition Type.h:55
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
virtual Embedding computeEmbeddings(const Instruction &I) const =0
Function to compute the embedding for a given instruction.
Embedder(const Function &F, const Vocabulary &Vocab)
Definition IR2Vec.h:552
Embedding getBBVector(const BasicBlock &BB) const
Computes and returns the embedding for a given basic block in the function F.
Definition IR2Vec.h:580
const Vocabulary & Vocab
Definition IR2Vec.h:547
virtual ~Embedder()=default
Embedding getInstVector(const Instruction &I) const
Computes and returns the embedding for a given instruction in the function F.
Definition IR2Vec.h:574
const unsigned Dimension
Dimension of the vector representation; captured from the input vocabulary.
Definition IR2Vec.h:550
virtual void invalidateEmbeddings()
Invalidate embeddings if cached.
Definition IR2Vec.h:592
Embedding getFunctionVector() const
Computes and returns the embedding for the current function.
Definition IR2Vec.h:585
LLVM_ABI Embedding computeEmbeddings() const
Function to compute embeddings.
Definition IR2Vec.cpp:145
const Function & F
Definition IR2Vec.h:546
void invalidateEmbeddings() override
Invalidate embeddings if cached.
Definition IR2Vec.h:620
FlowAwareEmbedder(const Function &F, const Vocabulary &Vocab)
Definition IR2Vec.h:618
SymbolicEmbedder(const Function &F, const Vocabulary &Vocab)
Definition IR2Vec.h:603
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
VocabStorage & operator=(VocabStorage &&)=default
const_iterator end() const
Definition IR2Vec.h:216
unsigned getNumSections() const
Get number of sections.
Definition IR2Vec.h:182
VocabStorage & operator=(const VocabStorage &)=delete
unsigned getDimension() const
Get vocabulary dimension.
Definition IR2Vec.h:193
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
bool isValid() const
Check if vocabulary is valid (has data)
Definition IR2Vec.h:196
VocabStorage(VocabStorage &&)=default
std::map< std::string, Embedding > VocabMap
Definition IR2Vec.h:220
const std::vector< Embedding > & operator[](unsigned SectionId) const
Section-based access: Storage[sectionId][localIndex].
Definition IR2Vec.h:187
VocabStorage(const VocabStorage &)=delete
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
const_iterator begin() const
Definition IR2Vec.h:423
Vocabulary(Vocabulary &&)=default
static LLVM_ABI OperandKind getOperandKind(const Value *Op)
Function to classify an operand into OperandKind.
Definition IR2Vec.cpp:348
const ir2vec::Embedding & operator[](Type::TypeID TypeID) const
Definition IR2Vec.h:403
static StringRef getVocabKeyForOperandKind(OperandKind Kind)
Function to get vocabulary key for a given OperandKind.
Definition IR2Vec.h:364
Vocabulary & operator=(const Vocabulary &)=delete
static LLVM_ABI StringRef getStringKey(unsigned Pos)
Returns the string key for a given index position in the vocabulary.
Definition IR2Vec.cpp:387
Vocabulary(VocabStorage &&Storage)
Definition IR2Vec.h:326
static constexpr unsigned MaxCanonicalTypeIDs
Definition IR2Vec.h:316
unsigned getDimension() const
Definition IR2Vec.h:346
static constexpr unsigned MaxOperandKinds
Definition IR2Vec.h:318
Vocabulary(const Vocabulary &)=delete
const_iterator cbegin() const
Definition IR2Vec.h:428
OperandKind
Operand kinds supported by IR2Vec Vocabulary.
Definition IR2Vec.h:302
static constexpr size_t getCanonicalSize()
Total number of entries (opcodes + canonicalized types + operand kinds + predicates)
Definition IR2Vec.h:353
const ir2vec::Embedding & operator[](CmpInst::Predicate P) const
Definition IR2Vec.h:415
static unsigned getIndex(Type::TypeID TypeID)
Definition IR2Vec.h:382
static LLVM_ABI StringRef getVocabKeyForPredicate(CmpInst::Predicate P)
Function to get vocabulary key for a given predicate.
Definition IR2Vec.cpp:377
static constexpr unsigned MaxTypeIDs
Definition IR2Vec.h:315
const_iterator end() const
Definition IR2Vec.h:430
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 unsigned getIndex(CmpInst::Predicate P)
Definition IR2Vec.h:393
static StringRef getVocabKeyForTypeID(Type::TypeID TypeID)
Function to get vocabulary key for a given TypeID.
Definition IR2Vec.h:359
VocabStorage::const_iterator const_iterator
Const Iterator type aliases.
Definition IR2Vec.h:421
const_iterator cend() const
Definition IR2Vec.h:435
static unsigned getIndex(unsigned Opcode)
Functions to return flat index.
Definition IR2Vec.h:377
Vocabulary & operator=(Vocabulary &&Other)=delete
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
static unsigned getIndex(const Value &Op)
Definition IR2Vec.h:387
CanonicalTypeID
Canonical type IDs supported by IR2Vec Vocabulary.
Definition IR2Vec.h:284
const ir2vec::Embedding & operator[](unsigned Opcode) const
Accessors to get the embedding for a given entity.
Definition IR2Vec.h:398
const ir2vec::Embedding & operator[](const Value &Arg) const
Definition IR2Vec.h:409
A Value is an JSON value of unknown type.
Definition JSON.h:291
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
DenseMap< const Instruction *, Embedding > InstEmbeddingsMap
Definition IR2Vec.h:148
LLVM_ABI IR2VecKind getEmbeddingKind(const LLVMContext &C)
Return -ir2vec-kind.
Definition IR2Vec.cpp:42
DenseMap< const BasicBlock *, Embedding > BBEmbeddingsMap
Definition IR2Vec.h:149
LLVM_ABI StringRef getVocabFile(const LLVMContext &C)
Return -ir2vec-vocab-path.
Definition IR2Vec.cpp:39
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
IR2VecKind
IR2Vec computes two kinds of embeddings: Symbolic and Flow-aware.
Definition IR2Vec.h:70
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ 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
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
A CRTP mix-in that provides informational APIs needed for analysis passes.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A CRTP mix-in for passes that should not be skipped.
Embedding is a datatype that wraps std::vector<double>.
Definition IR2Vec.h:85
const_iterator end() const
Definition IR2Vec.h:117
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
const_iterator cbegin() const
Definition IR2Vec.h:118
std::vector< double >::iterator iterator
Definition IR2Vec.h:111
LLVM_ABI Embedding & operator+=(const Embedding &RHS)
Arithmetic operators.
Definition IR2Vec.cpp:65
std::vector< double >::const_iterator const_iterator
Definition IR2Vec.h:112
LLVM_ABI Embedding operator-(const Embedding &RHS) const
Definition IR2Vec.cpp:85
const std::vector< double > & getData() const
Definition IR2Vec.h:121
Embedding(size_t Size, double InitialValue)
Definition IR2Vec.h:96
LLVM_ABI Embedding & operator-=(const Embedding &RHS)
Definition IR2Vec.cpp:78
const_iterator cend() const
Definition IR2Vec.h:119
bool isZero() const
Returns true if all elements of the embedding are zero.
Definition IR2Vec.h:141
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
Embedding(std::initializer_list< double > IL)
Definition IR2Vec.h:93
Embedding(const std::vector< double > &V)
Definition IR2Vec.h:91
LLVM_ABI Embedding operator+(const Embedding &RHS) const
Definition IR2Vec.cpp:72
bool empty() const
Definition IR2Vec.h:99
LLVM_ABI Embedding & scaleAndAdd(const Embedding &Src, float Factor)
Adds Src Embedding scaled by Factor with the called Embedding.
Definition IR2Vec.cpp:103
Embedding(std::vector< double > &&V)
Definition IR2Vec.h:92
const double & operator[](size_t Itr) const
Definition IR2Vec.h:106
Embedding(size_t Size)
Definition IR2Vec.h:95
LLVM_ABI void print(raw_ostream &OS) const
Definition IR2Vec.cpp:123
const_iterator begin() const
Definition IR2Vec.h:116
double & operator[](size_t Itr)
Definition IR2Vec.h:101