diff options
Diffstat (limited to 'llvm/include')
29 files changed, 528 insertions, 83 deletions
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h index d02cf98..3d22f859 100644 --- a/llvm/include/llvm-c/Core.h +++ b/llvm/include/llvm-c/Core.h @@ -1207,6 +1207,22 @@ LLVM_C_ABI LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy); /** + * Obtain or insert a function into a module. + * + * If a function with the specified name already exists in the module, it + * is returned. Otherwise, a new function is created in the module with the + * specified name and type and is returned. + * + * The returned value corresponds to a llvm::Function instance. + * + * @see llvm::Module::getOrInsertFunction() + */ +LLVM_C_ABI LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, + const char *Name, + size_t NameLen, + LLVMTypeRef FunctionTy); + +/** * Obtain a Function value from a Module by its name. * * The returned value corresponds to a llvm::Function value. diff --git a/llvm/include/llvm/ADT/Bitset.h b/llvm/include/llvm/ADT/Bitset.h index ecb6b14..b1e539e 100644 --- a/llvm/include/llvm/ADT/Bitset.h +++ b/llvm/include/llvm/ADT/Bitset.h @@ -28,15 +28,15 @@ namespace llvm { /// initialization. template <unsigned NumBits> class Bitset { - typedef uintptr_t BitWord; + using BitWord = uintptr_t; - enum { BITWORD_SIZE = (unsigned)sizeof(BitWord) * CHAR_BIT }; + static constexpr unsigned BitwordBits = sizeof(BitWord) * CHAR_BIT; - static_assert(BITWORD_SIZE == 64 || BITWORD_SIZE == 32, + static_assert(BitwordBits == 64 || BitwordBits == 32, "Unsupported word size"); static constexpr unsigned NumWords = - (NumBits + BITWORD_SIZE - 1) / BITWORD_SIZE; + (NumBits + BitwordBits - 1) / BitwordBits; protected: using StorageType = std::array<BitWord, NumWords>; @@ -60,23 +60,23 @@ public: } constexpr Bitset &set(unsigned I) { - Bits[I / BITWORD_SIZE] |= BitWord(1) << (I % BITWORD_SIZE); + Bits[I / BitwordBits] |= BitWord(1) << (I % BitwordBits); return *this; } constexpr Bitset &reset(unsigned I) { - Bits[I / BITWORD_SIZE] &= ~(BitWord(1) << (I % BITWORD_SIZE)); + Bits[I / BitwordBits] &= ~(BitWord(1) << (I % BitwordBits)); return *this; } constexpr Bitset &flip(unsigned I) { - Bits[I / BITWORD_SIZE] ^= BitWord(1) << (I % BITWORD_SIZE); + Bits[I / BitwordBits] ^= BitWord(1) << (I % BitwordBits); return *this; } constexpr bool operator[](unsigned I) const { - BitWord Mask = BitWord(1) << (I % BITWORD_SIZE); - return (Bits[I / BITWORD_SIZE] & Mask) != 0; + BitWord Mask = BitWord(1) << (I % BitwordBits); + return (Bits[I / BitwordBits] & Mask) != 0; } constexpr bool test(unsigned I) const { return (*this)[I]; } diff --git a/llvm/include/llvm/ADT/EquivalenceClasses.h b/llvm/include/llvm/ADT/EquivalenceClasses.h index 90d8948..5e8c2fa 100644 --- a/llvm/include/llvm/ADT/EquivalenceClasses.h +++ b/llvm/include/llvm/ADT/EquivalenceClasses.h @@ -128,7 +128,7 @@ private: /// ECValues, it just keeps the key as part of the value. DenseMap<ElemTy, ECValue *> TheMapping; - /// List of all members, used to provide a determinstic iteration order. + /// List of all members, used to provide a deterministic iteration order. SmallVector<const ECValue *> Members; mutable BumpPtrAllocator ECValueAllocator; diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 4a91b06..5b20d6bd 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1692,6 +1692,28 @@ template <typename R, typename E> auto accumulate(R &&Range, E &&Init) { std::forward<E>(Init)); } +/// Wrapper for std::accumulate with a binary operator. +template <typename R, typename E, typename BinaryOp> +auto accumulate(R &&Range, E &&Init, BinaryOp &&Op) { + return std::accumulate(adl_begin(Range), adl_end(Range), + std::forward<E>(Init), std::forward<BinaryOp>(Op)); +} + +/// Returns the sum of all values in `Range` with `Init` initial value. +/// The default initial value is 0. +template <typename R, typename E = detail::ValueOfRange<R>> +auto sum_of(R &&Range, E Init = E{0}) { + return accumulate(std::forward<R>(Range), std::move(Init)); +} + +/// Returns the product of all values in `Range` with `Init` initial value. +/// The default initial value is 1. +template <typename R, typename E = detail::ValueOfRange<R>> +auto product_of(R &&Range, E Init = E{1}) { + return accumulate(std::forward<R>(Range), std::move(Init), + std::multiplies<>{}); +} + /// Provide wrappers to std::for_each which take ranges instead of having to /// pass begin/end explicitly. template <typename R, typename UnaryFunction> diff --git a/llvm/include/llvm/Analysis/HeatUtils.h b/llvm/include/llvm/Analysis/HeatUtils.h index 179862c..2391086 100644 --- a/llvm/include/llvm/Analysis/HeatUtils.h +++ b/llvm/include/llvm/Analysis/HeatUtils.h @@ -23,17 +23,17 @@ class BlockFrequencyInfo; class Function; // Returns number of calls of calledFunction by callerFunction. -LLVM_ABI uint64_t getNumOfCalls(Function &callerFunction, - Function &calledFunction); +LLVM_ABI uint64_t getNumOfCalls(const Function &CallerFunction, + const Function &CalledFunction); // Returns the maximum frequency of a BB in a function. LLVM_ABI uint64_t getMaxFreq(const Function &F, const BlockFrequencyInfo *BFI); // Calculates heat color based on current and maximum frequencies. -LLVM_ABI std::string getHeatColor(uint64_t freq, uint64_t maxFreq); +LLVM_ABI std::string getHeatColor(uint64_t Freq, uint64_t MaxFreq); // Calculates heat color based on percent of "hotness". -LLVM_ABI std::string getHeatColor(double percent); +LLVM_ABI std::string getHeatColor(double Percent); } // namespace llvm diff --git a/llvm/include/llvm/Analysis/IR2Vec.h b/llvm/include/llvm/Analysis/IR2Vec.h index ed43f19..81409df 100644 --- a/llvm/include/llvm/Analysis/IR2Vec.h +++ b/llvm/include/llvm/Analysis/IR2Vec.h @@ -153,8 +153,11 @@ private: /// Section-based storage std::vector<std::vector<Embedding>> Sections; - const size_t TotalSize; - const unsigned Dimension; + // Fixme: Check if these members can be made const (and delete move + // assignment) after changing Vocabulary creation by using static factory + // methods. + size_t TotalSize = 0; + unsigned Dimension = 0; public: /// Default constructor creates empty storage (invalid state) @@ -164,7 +167,7 @@ public: VocabStorage(std::vector<std::vector<Embedding>> &&SectionData); VocabStorage(VocabStorage &&) = default; - VocabStorage &operator=(VocabStorage &&) = delete; + VocabStorage &operator=(VocabStorage &&) = default; VocabStorage(const VocabStorage &) = delete; VocabStorage &operator=(const VocabStorage &) = delete; diff --git a/llvm/include/llvm/Analysis/IVDescriptors.h b/llvm/include/llvm/Analysis/IVDescriptors.h index f9e6da6..654a5f1 100644 --- a/llvm/include/llvm/Analysis/IVDescriptors.h +++ b/llvm/include/llvm/Analysis/IVDescriptors.h @@ -251,12 +251,18 @@ public: Kind == RecurKind::SMin || Kind == RecurKind::SMax; } + /// Returns true if the recurrence kind is a floating-point minnum/maxnum + /// kind. + static bool isFPMinMaxNumRecurrenceKind(RecurKind Kind) { + return Kind == RecurKind::FMinNum || Kind == RecurKind::FMaxNum; + } + /// Returns true if the recurrence kind is a floating-point min/max kind. static bool isFPMinMaxRecurrenceKind(RecurKind Kind) { return Kind == RecurKind::FMin || Kind == RecurKind::FMax || - Kind == RecurKind::FMinNum || Kind == RecurKind::FMaxNum || Kind == RecurKind::FMinimum || Kind == RecurKind::FMaximum || - Kind == RecurKind::FMinimumNum || Kind == RecurKind::FMaximumNum; + Kind == RecurKind::FMinimumNum || Kind == RecurKind::FMaximumNum || + isFPMinMaxNumRecurrenceKind(Kind); } /// Returns true if the recurrence kind is any min/max kind. diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 858c1d5..8876e4e 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1002,10 +1002,14 @@ public: /// (at every loop iteration). It is, at the same time, the minimum number /// of times S is divisible by 2. For example, given {4,+,8} it returns 2. /// If S is guaranteed to be 0, it returns the bitwidth of S. - LLVM_ABI uint32_t getMinTrailingZeros(const SCEV *S); + /// If \p CtxI is not nullptr, return a constant multiple valid at \p CtxI. + LLVM_ABI uint32_t getMinTrailingZeros(const SCEV *S, + const Instruction *CtxI = nullptr); - /// Returns the max constant multiple of S. - LLVM_ABI APInt getConstantMultiple(const SCEV *S); + /// Returns the max constant multiple of S. If \p CtxI is not nullptr, return + /// a constant multiple valid at \p CtxI. + LLVM_ABI APInt getConstantMultiple(const SCEV *S, + const Instruction *CtxI = nullptr); // Returns the max constant multiple of S. If S is exactly 0, return 1. LLVM_ABI APInt getNonZeroConstantMultiple(const SCEV *S); @@ -1525,8 +1529,10 @@ private: /// Return the Value set from which the SCEV expr is generated. ArrayRef<Value *> getSCEVValues(const SCEV *S); - /// Private helper method for the getConstantMultiple method. - APInt getConstantMultipleImpl(const SCEV *S); + /// Private helper method for the getConstantMultiple method. If \p CtxI is + /// not nullptr, return a constant multiple valid at \p CtxI. + APInt getConstantMultipleImpl(const SCEV *S, + const Instruction *Ctx = nullptr); /// Information about the number of times a particular loop exit may be /// reached before exiting the loop. diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 1c7d346..464f475 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -800,6 +800,7 @@ enum AttributeKindCodes { ATTR_KIND_SANITIZE_TYPE = 101, ATTR_KIND_CAPTURES = 102, ATTR_KIND_DEAD_ON_RETURN = 103, + ATTR_KIND_SANITIZE_ALLOC_TOKEN = 104, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h index 5a1ff3d..93aff35 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -848,6 +848,10 @@ public: bool matchCombineFMinMaxNaN(MachineInstr &MI, unsigned &Info) const; + bool matchRepeatedFPDivisor(MachineInstr &MI, + SmallVector<MachineInstr *> &MatchInfo) const; + void applyRepeatedFPDivisor(SmallVector<MachineInstr *> &MatchInfo) const; + /// Transform G_ADD(x, G_SUB(y, x)) to y. /// Transform G_ADD(G_SUB(y, x), x) to y. bool matchAddSubSameReg(MachineInstr &MI, Register &Src) const; diff --git a/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/llvm/include/llvm/CodeGen/LiveRangeEdit.h index 6473138a..d0ed3ff 100644 --- a/llvm/include/llvm/CodeGen/LiveRangeEdit.h +++ b/llvm/include/llvm/CodeGen/LiveRangeEdit.h @@ -75,24 +75,14 @@ private: /// FirstNew - Index of the first register added to NewRegs. const unsigned FirstNew; - /// ScannedRemattable - true when remattable values have been identified. - bool ScannedRemattable = false; - /// DeadRemats - The saved instructions which have already been dead after /// rematerialization but not deleted yet -- to be done in postOptimization. SmallPtrSet<MachineInstr *, 32> *DeadRemats; - /// Remattable - Values defined by remattable instructions as identified by - /// tii.isTriviallyReMaterializable(). - SmallPtrSet<const VNInfo *, 4> Remattable; - /// Rematted - Values that were actually rematted, and so need to have their /// live range trimmed or entirely removed. SmallPtrSet<const VNInfo *, 4> Rematted; - /// scanRemattable - Identify the Parent values that may rematerialize. - void scanRemattable(); - /// foldAsLoad - If LI has a single use and a single def that can be folded as /// a load, eliminate the register by folding the def into the use. bool foldAsLoad(LiveInterval *LI, SmallVectorImpl<MachineInstr *> &Dead); @@ -175,11 +165,6 @@ public: Register create() { return createFrom(getReg()); } - /// anyRematerializable - Return true if any parent values may be - /// rematerializable. This function must be called before - /// canRematerializeAt is called.. - bool anyRematerializable(); - /// Remat - Information needed to rematerialize at a specific location. struct Remat { const VNInfo *const ParentVNI; // parent_'s value at the remat location. @@ -189,9 +174,9 @@ public: explicit Remat(const VNInfo *ParentVNI) : ParentVNI(ParentVNI) {} }; - /// canRematerializeAt - Determine if ParentVNI can be rematerialized at + /// canRematerializeAt - Determine if RM.Orig can be rematerialized at /// UseIdx. It is assumed that parent_.getVNINfoAt(UseIdx) == ParentVNI. - bool canRematerializeAt(Remat &RM, VNInfo *OrigVNI, SlotIndex UseIdx); + bool canRematerializeAt(Remat &RM, SlotIndex UseIdx); /// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an /// instruction into MBB before MI. The new instruction is mapped, but diff --git a/llvm/include/llvm/CodeGen/MIR2Vec.h b/llvm/include/llvm/CodeGen/MIR2Vec.h new file mode 100644 index 0000000..ea68b45 --- /dev/null +++ b/llvm/include/llvm/CodeGen/MIR2Vec.h @@ -0,0 +1,186 @@ +//===- MIR2Vec.h - Implementation of MIR2Vec ------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM +// Exceptions. See the LICENSE file for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines the MIR2Vec vocabulary +/// analysis(MIR2VecVocabLegacyAnalysis), the core mir2vec::MIREmbedder +/// interface for generating Machine IR embeddings, and related utilities. +/// +/// MIR2Vec extends IR2Vec to support Machine IR embeddings. It represents the +/// LLVM Machine IR as embeddings which can be used as input to machine learning +/// algorithms. +/// +/// The original idea of MIR2Vec is described in the following paper: +/// +/// RL4ReAl: Reinforcement Learning for Register Allocation. S. VenkataKeerthy, +/// Siddharth Jain, Anilava Kundu, Rohit Aggarwal, Albert Cohen, and Ramakrishna +/// Upadrasta. 2023. RL4ReAl: Reinforcement Learning for Register Allocation. +/// Proceedings of the 32nd ACM SIGPLAN International Conference on Compiler +/// Construction (CC 2023). https://doi.org/10.1145/3578360.3580273. +/// https://arxiv.org/abs/2204.02013 +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MIR2VEC_H +#define LLVM_CODEGEN_MIR2VEC_H + +#include "llvm/Analysis/IR2Vec.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorOr.h" +#include <map> +#include <set> +#include <string> + +namespace llvm { + +class Module; +class raw_ostream; +class LLVMContext; +class MIR2VecVocabLegacyAnalysis; +class TargetInstrInfo; + +namespace mir2vec { +extern llvm::cl::OptionCategory MIR2VecCategory; +extern cl::opt<float> OpcWeight; + +using Embedding = ir2vec::Embedding; + +/// Class for storing and accessing the MIR2Vec vocabulary. +/// The MIRVocabulary class manages seed embeddings for LLVM Machine IR +class MIRVocabulary { + friend class llvm::MIR2VecVocabLegacyAnalysis; + using VocabMap = std::map<std::string, ir2vec::Embedding>; + +private: + // Define vocabulary layout - adapted for MIR + struct { + size_t OpcodeBase = 0; + size_t OperandBase = 0; + size_t TotalEntries = 0; + } Layout; + + enum class Section : unsigned { Opcodes = 0, MaxSections }; + + ir2vec::VocabStorage Storage; + mutable std::set<std::string> UniqueBaseOpcodeNames; + const TargetInstrInfo &TII; + void generateStorage(const VocabMap &OpcodeMap); + void buildCanonicalOpcodeMapping(); + + /// Get canonical index for a machine opcode + unsigned getCanonicalOpcodeIndex(unsigned Opcode) const; + +public: + /// Static method for extracting base opcode names (public for testing) + static std::string extractBaseOpcodeName(StringRef InstrName); + + /// Get canonical index for base name (public for testing) + unsigned getCanonicalIndexForBaseName(StringRef BaseName) const; + + /// Get the string key for a vocabulary entry at the given position + std::string getStringKey(unsigned Pos) const; + + MIRVocabulary() = delete; + MIRVocabulary(VocabMap &&Entries, const TargetInstrInfo *TII); + MIRVocabulary(ir2vec::VocabStorage &&Storage, const TargetInstrInfo &TII) + : Storage(std::move(Storage)), TII(TII) {} + + bool isValid() const { + return UniqueBaseOpcodeNames.size() > 0 && + Layout.TotalEntries == Storage.size() && Storage.isValid(); + } + + unsigned getDimension() const { + if (!isValid()) + return 0; + return Storage.getDimension(); + } + + // Accessor methods + const Embedding &operator[](unsigned Opcode) const { + assert(isValid() && "MIR2Vec Vocabulary is invalid"); + unsigned LocalIndex = getCanonicalOpcodeIndex(Opcode); + return Storage[static_cast<unsigned>(Section::Opcodes)][LocalIndex]; + } + + // Iterator access + using const_iterator = ir2vec::VocabStorage::const_iterator; + const_iterator begin() const { + assert(isValid() && "MIR2Vec Vocabulary is invalid"); + return Storage.begin(); + } + + const_iterator end() const { + assert(isValid() && "MIR2Vec Vocabulary is invalid"); + return Storage.end(); + } + + /// Total number of entries in the vocabulary + size_t getCanonicalSize() const { + assert(isValid() && "Invalid vocabulary"); + return Storage.size(); + } +}; + +} // namespace mir2vec + +/// Pass to analyze and populate MIR2Vec vocabulary from a module +class MIR2VecVocabLegacyAnalysis : public ImmutablePass { + using VocabVector = std::vector<mir2vec::Embedding>; + using VocabMap = std::map<std::string, mir2vec::Embedding>; + VocabMap StrVocabMap; + VocabVector Vocab; + + StringRef getPassName() const override; + Error readVocabulary(); + void emitError(Error Err, LLVMContext &Ctx); + +protected: + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<MachineModuleInfoWrapperPass>(); + AU.setPreservesAll(); + } + +public: + static char ID; + MIR2VecVocabLegacyAnalysis() : ImmutablePass(ID) {} + mir2vec::MIRVocabulary getMIR2VecVocabulary(const Module &M); +}; + +/// This pass prints the embeddings in the MIR2Vec vocabulary +class MIR2VecVocabPrinterLegacyPass : public MachineFunctionPass { + raw_ostream &OS; + +public: + static char ID; + explicit MIR2VecVocabPrinterLegacyPass(raw_ostream &OS) + : MachineFunctionPass(ID), OS(OS) {} + + bool runOnMachineFunction(MachineFunction &MF) override; + bool doFinalization(Module &M) override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<MIR2VecVocabLegacyAnalysis>(); + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + StringRef getPassName() const override { + return "MIR2Vec Vocabulary Printer Pass"; + } +}; + +} // namespace llvm + +#endif // LLVM_CODEGEN_MIR2VEC_H
\ No newline at end of file diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index f17d550..272b4ac 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -88,6 +88,11 @@ LLVM_ABI MachineFunctionPass * createMachineFunctionPrinterPass(raw_ostream &OS, const std::string &Banner = ""); +/// MIR2VecVocabPrinter pass - This pass prints out the MIR2Vec vocabulary +/// contents to the given stream as a debugging tool. +LLVM_ABI MachineFunctionPass * +createMIR2VecVocabPrinterLegacyPass(raw_ostream &OS); + /// StackFramePrinter pass - This pass prints out the machine function's /// stack frame to the given stream as a debugging tool. LLVM_ABI MachineFunctionPass *createStackFrameLayoutAnalysisPass(); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h index 68bc54b..7c995a7 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h @@ -34,7 +34,7 @@ public: struct SymbolAddrs { ExecutorAddr Instance; ExecutorAddr Open; - ExecutorAddr Lookup; + ExecutorAddr Resolve; }; /// Create an EPCGenericMemoryAccess instance from a given set of @@ -51,25 +51,25 @@ public: LLVM_ABI Expected<tpctypes::DylibHandle> open(StringRef Path, uint64_t Mode); /// Looks up symbols within the given dylib. - Expected<std::vector<ExecutorSymbolDef>> - lookup(tpctypes::DylibHandle H, const SymbolLookupSet &Lookup) { - std::promise<MSVCPExpected<std::vector<ExecutorSymbolDef>>> RP; + Expected<tpctypes::LookupResult> lookup(tpctypes::DylibHandle H, + const SymbolLookupSet &Lookup) { + std::promise<MSVCPExpected<tpctypes::LookupResult>> RP; auto RF = RP.get_future(); lookupAsync(H, Lookup, [&RP](auto R) { RP.set_value(std::move(R)); }); return RF.get(); } /// Looks up symbols within the given dylib. - Expected<std::vector<ExecutorSymbolDef>> - lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &Lookup) { - std::promise<MSVCPExpected<std::vector<ExecutorSymbolDef>>> RP; + Expected<tpctypes::LookupResult> lookup(tpctypes::DylibHandle H, + const RemoteSymbolLookupSet &Lookup) { + std::promise<MSVCPExpected<tpctypes::LookupResult>> RP; auto RF = RP.get_future(); lookupAsync(H, Lookup, [&RP](auto R) { RP.set_value(std::move(R)); }); return RF.get(); } using SymbolLookupCompleteFn = - unique_function<void(Expected<std::vector<ExecutorSymbolDef>>)>; + unique_function<void(Expected<tpctypes::LookupResult>)>; /// Looks up symbols within the given dylib. LLVM_ABI void lookupAsync(tpctypes::DylibHandle H, diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h new file mode 100644 index 0000000..9b972ed --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/ExecutorResolutionGenerator.h @@ -0,0 +1,74 @@ +//===----- ExecutorResolver.h - Resolve symbols in executor -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Declares ExecutorResolutionGenerator for symbol resolution, +// dynamic library loading, and lookup in an executor process via +// ExecutorResolver. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H +#define LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H + +#include "llvm/ADT/FunctionExtras.h" +#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h" +#include "llvm/ExecutionEngine/Orc/Core.h" + +namespace llvm::orc { + +class ExecutorResolutionGenerator : public DefinitionGenerator { +public: + using SymbolPredicate = unique_function<bool(const SymbolStringPtr &)>; + using AbsoluteSymbolsFn = + unique_function<std::unique_ptr<MaterializationUnit>(SymbolMap)>; + + ExecutorResolutionGenerator( + ExecutionSession &ES, tpctypes::ResolverHandle H, + SymbolPredicate Allow = SymbolPredicate(), + AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols) + : EPC(ES.getExecutorProcessControl()), H(H), Allow(std::move(Allow)), + AbsoluteSymbols(std::move(AbsoluteSymbols)) {} + + ExecutorResolutionGenerator( + ExecutionSession &ES, SymbolPredicate Allow = SymbolPredicate(), + AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols) + : EPC(ES.getExecutorProcessControl()), Allow(std::move(Allow)), + AbsoluteSymbols(std::move(AbsoluteSymbols)) {} + + /// Permanently loads the library at the given path and, on success, returns + /// an ExecutorResolutionGenerator that will search it for symbol + /// definitions in the library. On failure returns the reason the library + /// failed to load. + static Expected<std::unique_ptr<ExecutorResolutionGenerator>> + Load(ExecutionSession &ES, const char *LibraryPath, + SymbolPredicate Allow = SymbolPredicate(), + AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols); + + /// Creates a ExecutorResolutionGenerator that searches for symbols in + /// the target process. + static Expected<std::unique_ptr<ExecutorResolutionGenerator>> + GetForTargetProcess(ExecutionSession &ES, + SymbolPredicate Allow = SymbolPredicate(), + AbsoluteSymbolsFn AbsoluteSymbols = absoluteSymbols) { + return Load(ES, nullptr, std::move(Allow), std::move(AbsoluteSymbols)); + } + + Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, + JITDylibLookupFlags JDLookupFlags, + const SymbolLookupSet &LookupSet) override; + +private: + ExecutorProcessControl &EPC; + tpctypes::ResolverHandle H; + SymbolPredicate Allow; + AbsoluteSymbolsFn AbsoluteSymbols; +}; + +} // namespace llvm::orc + +#endif // LLVM_EXECUTIONENGINE_ORC_EXECUTORRESOLUTIONGENERATOR_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h index 2bc6c12..99ba456 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h @@ -25,7 +25,7 @@ namespace rt { LLVM_ABI extern const char *SimpleExecutorDylibManagerInstanceName; LLVM_ABI extern const char *SimpleExecutorDylibManagerOpenWrapperName; -LLVM_ABI extern const char *SimpleExecutorDylibManagerLookupWrapperName; +LLVM_ABI extern const char *SimpleExecutorDylibManagerResolveWrapperName; LLVM_ABI extern const char *SimpleExecutorMemoryManagerInstanceName; LLVM_ABI extern const char *SimpleExecutorMemoryManagerReserveWrapperName; @@ -66,10 +66,9 @@ using SPSSimpleExecutorDylibManagerOpenSignature = shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr, shared::SPSString, uint64_t); -using SPSSimpleExecutorDylibManagerLookupSignature = - shared::SPSExpected<shared::SPSSequence<shared::SPSExecutorSymbolDef>>( - shared::SPSExecutorAddr, shared::SPSExecutorAddr, - shared::SPSRemoteSymbolLookupSet); +using SPSSimpleExecutorDylibManagerResolveSignature = shared::SPSExpected< + shared::SPSSequence<shared::SPSOptional<shared::SPSExecutorSymbolDef>>>( + shared::SPSExecutorAddr, shared::SPSRemoteSymbolLookupSet); using SPSSimpleExecutorMemoryManagerReserveSignature = shared::SPSExpected<shared::SPSExecutorAddr>(shared::SPSExecutorAddr, diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h index adb07ba..28ff322 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h @@ -114,7 +114,11 @@ struct PointerWrite { /// A handle used to represent a loaded dylib in the target process. using DylibHandle = ExecutorAddr; -using LookupResult = std::vector<ExecutorSymbolDef>; +/// A handle used to reference the resolver associated with a loaded +/// dylib in the target process. +using ResolverHandle = ExecutorAddr; + +using LookupResult = std::vector<std::optional<ExecutorSymbolDef>>; } // end namespace tpctypes diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h new file mode 100644 index 0000000..2c5e98c --- /dev/null +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h @@ -0,0 +1,48 @@ +//===----- ExecutorResolver.h - Symbol resolver -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Executor Symbol resolver. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H +#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H + +#include "llvm/ADT/FunctionExtras.h" + +#include "llvm/ExecutionEngine/Orc/Shared/ExecutorSymbolDef.h" +#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h" +#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h" + +namespace llvm::orc { + +class ExecutorResolver { +public: + using ResolveResult = Expected<std::vector<std::optional<ExecutorSymbolDef>>>; + using YieldResolveResultFn = unique_function<void(ResolveResult)>; + + virtual ~ExecutorResolver() = default; + + virtual void resolveAsync(const RemoteSymbolLookupSet &L, + YieldResolveResultFn &&OnResolve) = 0; +}; + +class DylibSymbolResolver : public ExecutorResolver { +public: + DylibSymbolResolver(tpctypes::DylibHandle H) : Handle(H) {} + + void + resolveAsync(const RemoteSymbolLookupSet &L, + ExecutorResolver::YieldResolveResultFn &&OnResolve) override; + +private: + tpctypes::DylibHandle Handle; +}; + +} // end namespace llvm::orc +#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_EXECUTORRESOLVER_H diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h index 36a6f4b..7526a29d 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h @@ -23,6 +23,7 @@ #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h" #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h" #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h" +#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorResolver.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Error.h" @@ -39,8 +40,6 @@ public: virtual ~SimpleExecutorDylibManager(); Expected<tpctypes::DylibHandle> open(const std::string &Path, uint64_t Mode); - Expected<std::vector<ExecutorSymbolDef>> - lookup(tpctypes::DylibHandle H, const RemoteSymbolLookupSet &L); Error shutdown() override; void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override; @@ -52,10 +51,11 @@ private: openWrapper(const char *ArgData, size_t ArgSize); static llvm::orc::shared::CWrapperFunctionResult - lookupWrapper(const char *ArgData, size_t ArgSize); + resolveWrapper(const char *ArgData, size_t ArgSize); std::mutex M; DylibSet Dylibs; + std::vector<std::unique_ptr<ExecutorResolver>> Resolvers; }; } // end namespace rt_bootstrap diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index ef816fb..8e7d9dc 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -342,6 +342,9 @@ def SanitizeRealtime : EnumAttr<"sanitize_realtime", IntersectPreserve, [FnAttr] /// during a real-time sanitized function (see `sanitize_realtime`). def SanitizeRealtimeBlocking : EnumAttr<"sanitize_realtime_blocking", IntersectPreserve, [FnAttr]>; +/// Allocation token instrumentation is on. +def SanitizeAllocToken : EnumAttr<"sanitize_alloc_token", IntersectPreserve, [FnAttr]>; + /// Speculative Load Hardening is enabled. /// /// Note that this uses the default compatibility (always compatible during diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def index 0603abc..74746cc 100644 --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -56,3 +56,4 @@ LLVM_FIXED_MD_KIND(MD_noalias_addrspace, "noalias.addrspace", 41) LLVM_FIXED_MD_KIND(MD_callee_type, "callee_type", 42) LLVM_FIXED_MD_KIND(MD_nofree, "nofree", 43) LLVM_FIXED_MD_KIND(MD_captures, "captures", 44) +LLVM_FIXED_MD_KIND(MD_alloc_token, "alloc_token", 45) diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index 14685ab..9f56779 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -601,11 +601,9 @@ public: Instruction::CastOps firstOpcode, ///< Opcode of first cast Instruction::CastOps secondOpcode, ///< Opcode of second cast Type *SrcTy, ///< SrcTy of 1st cast - Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast - Type *DstTy, ///< DstTy of 2nd cast - Type *SrcIntPtrTy, ///< Integer type corresponding to Ptr SrcTy, or null - Type *MidIntPtrTy, ///< Integer type corresponding to Ptr MidTy, or null - Type *DstIntPtrTy ///< Integer type corresponding to Ptr DstTy, or null + Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast + Type *DstTy, ///< DstTy of 2nd cast + const DataLayout *DL ///< Optional data layout ); /// Return the opcode of this CastInst diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 88272f0..cd774e7 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -220,6 +220,8 @@ LLVM_ABI void initializeMachinePostDominatorTreeWrapperPassPass(PassRegistry &); LLVM_ABI void initializeMachineRegionInfoPassPass(PassRegistry &); LLVM_ABI void initializeMachineSanitizerBinaryMetadataLegacyPass(PassRegistry &); +LLVM_ABI void initializeMIR2VecVocabLegacyAnalysisPass(PassRegistry &); +LLVM_ABI void initializeMIR2VecVocabPrinterLegacyPassPass(PassRegistry &); LLVM_ABI void initializeMachineSchedulerLegacyPass(PassRegistry &); LLVM_ABI void initializeMachineSinkingLegacyPass(PassRegistry &); LLVM_ABI void initializeMachineTraceMetricsWrapperPassPass(PassRegistry &); diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h index 570d4c0..234c587 100644 --- a/llvm/include/llvm/MC/TargetRegistry.h +++ b/llvm/include/llvm/MC/TargetRegistry.h @@ -737,7 +737,8 @@ struct TargetRegistry { /// \param TripleStr - The triple to use for finding a target. /// \param Error - On failure, an error string describing why no target was /// found. - // TODO: Drop this in favor of the method accepting Triple. + // TODO(boomanaiden154): Remove this function after LLVM 22 branches. + [[deprecated("Use overload accepting Triple instead")]] static const Target *lookupTarget(StringRef TripleStr, std::string &Error) { return lookupTarget(Triple(TripleStr), Error); } diff --git a/llvm/include/llvm/Support/CrashRecoveryContext.h b/llvm/include/llvm/Support/CrashRecoveryContext.h index 773de89..ffee81d 100644 --- a/llvm/include/llvm/Support/CrashRecoveryContext.h +++ b/llvm/include/llvm/Support/CrashRecoveryContext.h @@ -80,9 +80,6 @@ public: /// make as little assumptions as possible about the program state when /// RunSafely has returned false. LLVM_ABI bool RunSafely(function_ref<void()> Fn); - bool RunSafely(void (*Fn)(void*), void *UserData) { - return RunSafely([&]() { Fn(UserData); }); - } /// Execute the provide callback function (with the given arguments) in /// a protected context which is run in another thread (optionally with a @@ -94,10 +91,6 @@ public: /// propagated to the new thread as well. LLVM_ABI bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0); - bool RunSafelyOnThread(void (*Fn)(void*), void *UserData, - unsigned RequestedStackSize = 0) { - return RunSafelyOnThread([&]() { Fn(UserData); }, RequestedStackSize); - } LLVM_ABI bool RunSafelyOnNewStack(function_ref<void()>, unsigned RequestedStackSize = 0); diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 22a62ea..64cad80 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -123,11 +123,18 @@ protected: public: LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber, bool UseRegex); - // Returns the line number in the source file that this query matches to. - // Returns zero if no match is found. - LLVM_ABI unsigned match(StringRef Query) const; + LLVM_ABI void + match(StringRef Query, + llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const; + + LLVM_ABI bool matchAny(StringRef Query) const { + bool R = false; + match(Query, [&](StringRef, unsigned) { R = true; }); + return R; + } struct Glob { + Glob(StringRef Name, unsigned LineNo) : Name(Name), LineNo(LineNo) {} std::string Name; unsigned LineNo; GlobPattern Pattern; @@ -137,8 +144,18 @@ protected: Glob() = default; }; + struct Reg { + Reg(StringRef Name, unsigned LineNo, Regex &&Rg) + : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {} + std::string Name; + unsigned LineNo; + Regex Rg; + Reg(Reg &&) = delete; + Reg() = default; + }; + std::vector<std::unique_ptr<Matcher::Glob>> Globs; - std::vector<std::pair<std::unique_ptr<Regex>, unsigned>> RegExes; + std::vector<std::unique_ptr<Reg>> RegExes; }; using SectionEntries = StringMap<StringMap<Matcher>>; @@ -147,10 +164,26 @@ protected: Section(StringRef Str, unsigned FileIdx) : SectionStr(Str), FileIdx(FileIdx) {}; - std::unique_ptr<Matcher> SectionMatcher = std::make_unique<Matcher>(); + Section(Section &&) = default; + + Matcher SectionMatcher; SectionEntries Entries; std::string SectionStr; unsigned FileIdx; + + // Helper method to search by Prefix, Query, and Category. Returns + // 1-based line number on which rule is defined, or 0 if there is no match. + LLVM_ABI unsigned getLastMatch(StringRef Prefix, StringRef Query, + StringRef Category) const; + + // Helper method to search by Prefix, Query, and Category. Returns + // matching rule, or empty string if there is no match. + LLVM_ABI StringRef getLongestMatch(StringRef Prefix, StringRef Query, + StringRef Category) const; + + private: + LLVM_ABI const SpecialCaseList::Matcher * + findMatcher(StringRef Prefix, StringRef Category) const; }; std::vector<Section> Sections; @@ -162,12 +195,6 @@ protected: /// Parses just-constructed SpecialCaseList entries from a memory buffer. LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB, std::string &Error); - - // Helper method for derived classes to search by Prefix, Query, and Category - // once they have already resolved a section entry. - LLVM_ABI unsigned inSectionBlame(const SectionEntries &Entries, - StringRef Prefix, StringRef Query, - StringRef Category) const; }; } // namespace llvm diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td index 204e1f6..e2b7a5e 100644 --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -213,6 +213,7 @@ def build_fn_matchinfo : GIDefMatchData<"std::function<void(MachineIRBuilder &)>">; def unsigned_matchinfo: GIDefMatchData<"unsigned">; def register_vector_matchinfo : GIDefMatchData<"SmallVector<Register>">; +def mi_vector_matchinfo : GIDefMatchData<"SmallVector<MachineInstr *>">; def copy_prop : GICombineRule< (defs root:$d), @@ -1416,6 +1417,14 @@ def combine_minmax_nan: GICombineRule< [{ return Helper.matchCombineFMinMaxNaN(*${root}, ${info}); }]), (apply [{ Helper.replaceSingleDefInstWithOperand(*${root}, ${info}); }])>; +// Combine multiple FDIVs with the same divisor into multiple FMULs by the +// reciprocal. +def fdiv_repeated_divison: GICombineRule< + (defs root:$root, mi_vector_matchinfo:$matchinfo), + (match (G_FDIV $dst, $src1, $src2):$root, + [{ return Helper.matchRepeatedFPDivisor(*${root}, ${matchinfo}); }]), + (apply [{ Helper.applyRepeatedFPDivisor(${matchinfo}); }])>; + // Transform (add x, (sub y, x)) -> y // Transform (add (sub y, x), x) -> y def add_sub_reg_frags : GICombinePatFrag< @@ -2139,7 +2148,8 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines, constant_fold_cast_op, fabs_fneg_fold, mulh_combines, redundant_neg_operands, and_or_disjoint_mask, fma_combines, fold_binop_into_select, - intrem_combines, intdiv_combines, sub_add_reg, select_to_minmax, + intrem_combines, intdiv_combines, fdiv_repeated_divison, + sub_add_reg, select_to_minmax, fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors, simplify_neg_minmax, combine_concat_vector, sext_trunc, zext_trunc, prefer_sign_combines, shuffle_combines, diff --git a/llvm/include/llvm/Transforms/Instrumentation/AllocToken.h b/llvm/include/llvm/Transforms/Instrumentation/AllocToken.h new file mode 100644 index 0000000..b1391cb0 --- /dev/null +++ b/llvm/include/llvm/Transforms/Instrumentation/AllocToken.h @@ -0,0 +1,46 @@ +//===- AllocToken.h - Allocation token instrumentation --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the AllocTokenPass, an instrumentation pass that +// replaces allocation calls with ones including an allocation token. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ALLOCTOKEN_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_ALLOCTOKEN_H + +#include "llvm/IR/Analysis.h" +#include "llvm/IR/PassManager.h" +#include <optional> + +namespace llvm { + +class Module; + +struct AllocTokenOptions { + std::optional<uint64_t> MaxTokens; + bool FastABI = false; + bool Extended = false; + AllocTokenOptions() = default; +}; + +/// A module pass that rewrites heap allocations to use token-enabled +/// allocation functions based on various source-level properties. +class AllocTokenPass : public PassInfoMixin<AllocTokenPass> { +public: + LLVM_ABI explicit AllocTokenPass(AllocTokenOptions Opts = {}); + LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); + static bool isRequired() { return true; } + +private: + const AllocTokenOptions Options; +}; + +} // namespace llvm + +#endif // LLVM_TRANSFORMS_INSTRUMENTATION_ALLOCTOKEN_H diff --git a/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h b/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h index ee3cc95..2d0f957 100644 --- a/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h +++ b/llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h @@ -24,6 +24,7 @@ struct SimplifyCFGOptions { int BonusInstThreshold = 1; bool ForwardSwitchCondToPhi = false; bool ConvertSwitchRangeToICmp = false; + bool ConvertSwitchToArithmetic = false; bool ConvertSwitchToLookupTable = false; bool NeedCanonicalLoop = true; bool HoistCommonInsts = false; @@ -48,6 +49,10 @@ struct SimplifyCFGOptions { ConvertSwitchRangeToICmp = B; return *this; } + SimplifyCFGOptions &convertSwitchToArithmetic(bool B) { + ConvertSwitchToArithmetic = B; + return *this; + } SimplifyCFGOptions &convertSwitchToLookupTable(bool B) { ConvertSwitchToLookupTable = B; return *this; |