diff options
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/ADT/Bitset.h | 18 | ||||
-rw-r--r-- | llvm/include/llvm/Analysis/IVDescriptors.h | 10 | ||||
-rw-r--r-- | llvm/include/llvm/Analysis/ScalarEvolution.h | 16 | ||||
-rw-r--r-- | llvm/include/llvm/BinaryFormat/Dwarf.def | 3 | ||||
-rw-r--r-- | llvm/include/llvm/BinaryFormat/Dwarf.h | 9 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h | 11 | ||||
-rw-r--r-- | llvm/include/llvm/CodeGen/MIR2Vec.h | 45 | ||||
-rw-r--r-- | llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h | 153 | ||||
-rw-r--r-- | llvm/include/llvm/Frontend/OpenMP/OMPKinds.def | 3 | ||||
-rw-r--r-- | llvm/include/llvm/IR/DIBuilder.h | 9 | ||||
-rw-r--r-- | llvm/include/llvm/IR/DebugInfoMetadata.h | 76 | ||||
-rw-r--r-- | llvm/include/llvm/IR/DiagnosticInfo.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Intrinsics.td | 86 | ||||
-rw-r--r-- | llvm/include/llvm/Support/SpecialCaseList.h | 84 | ||||
-rw-r--r-- | llvm/include/llvm/Support/TrailingObjects.h | 7 | ||||
-rw-r--r-- | llvm/include/llvm/Target/GlobalISel/Combine.td | 12 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/Utils/SimplifyCFGOptions.h | 5 |
18 files changed, 264 insertions, 289 deletions
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/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/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index 2c9a3c0..fbf22cc 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -424,6 +424,9 @@ HANDLE_DW_AT(0x89, export_symbols, 5, DWARF) HANDLE_DW_AT(0x8a, deleted, 5, DWARF) HANDLE_DW_AT(0x8b, defaulted, 5, DWARF) HANDLE_DW_AT(0x8c, loclists_base, 5, DWARF) +// New in Dwarf v6: +HANDLE_DW_AT(0x90, language_name, 6, DWARF) +HANDLE_DW_AT(0x91, language_version, 6, DWARF) // Vendor extensions: HANDLE_DW_AT(0x806, GHS_namespace_alias, 0, GHS) diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h index 2c50125..815e85d 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.h +++ b/llvm/include/llvm/BinaryFormat/Dwarf.h @@ -500,8 +500,15 @@ toDW_LNAME(SourceLanguage language) { return {}; } +/// Returns a version-independent language name. LLVM_ABI llvm::StringRef LanguageDescription(SourceLanguageName name); +/// Returns a language name corresponding to the specified version. +/// If the version is not recognized for the specified language, returns +/// the version-independent name. +LLVM_ABI llvm::StringRef LanguageDescription(SourceLanguageName Name, + uint32_t Version); + inline bool isCPlusPlus(SourceLanguage S) { bool result = false; // Deliberately enumerate all the language options so we get a warning when @@ -997,6 +1004,7 @@ LLVM_ABI StringRef VisibilityString(unsigned Visibility); LLVM_ABI StringRef VirtualityString(unsigned Virtuality); LLVM_ABI StringRef EnumKindString(unsigned EnumKind); LLVM_ABI StringRef LanguageString(unsigned Language); +LLVM_ABI StringRef SourceLanguageNameString(SourceLanguageName Lang); LLVM_ABI StringRef CaseString(unsigned Case); LLVM_ABI StringRef ConventionString(unsigned Convention); LLVM_ABI StringRef InlineCodeString(unsigned Code); @@ -1038,6 +1046,7 @@ LLVM_ABI unsigned getSubOperationEncoding(unsigned OpEncoding, LLVM_ABI unsigned getVirtuality(StringRef VirtualityString); LLVM_ABI unsigned getEnumKind(StringRef EnumKindString); LLVM_ABI unsigned getLanguage(StringRef LanguageString); +LLVM_ABI unsigned getSourceLanguageName(StringRef SourceLanguageNameString); LLVM_ABI unsigned getCallingConvention(StringRef LanguageString); LLVM_ABI unsigned getAttributeEncoding(StringRef EncodingString); LLVM_ABI unsigned getMacinfo(StringRef MacinfoString); 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/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index fd72a38..9855444 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -115,14 +115,17 @@ struct LegalityQuery { struct MemDesc { LLT MemoryTy; uint64_t AlignInBits; - AtomicOrdering Ordering; + AtomicOrdering Ordering; //< For cmpxchg this is the success ordering. + AtomicOrdering FailureOrdering; //< For cmpxchg, otherwise NotAtomic. MemDesc() = default; - MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering) - : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {} + MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering, + AtomicOrdering FailureOrdering) + : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering), + FailureOrdering(FailureOrdering) {} MemDesc(const MachineMemOperand &MMO) : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8, - MMO.getSuccessOrdering()) {} + MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {} }; /// Operations which require memory can use this to place requirements on the diff --git a/llvm/include/llvm/CodeGen/MIR2Vec.h b/llvm/include/llvm/CodeGen/MIR2Vec.h index ea68b45..7b1b5d9 100644 --- a/llvm/include/llvm/CodeGen/MIR2Vec.h +++ b/llvm/include/llvm/CodeGen/MIR2Vec.h @@ -38,6 +38,7 @@ #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include <map> #include <set> @@ -92,46 +93,31 @@ public: /// 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(); - } + unsigned getDimension() const { 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 begin() const { return Storage.begin(); } - const_iterator end() const { - assert(isValid() && "MIR2Vec Vocabulary is invalid"); - return Storage.end(); - } + const_iterator end() const { return Storage.end(); } /// Total number of entries in the vocabulary - size_t getCanonicalSize() const { - assert(isValid() && "Invalid vocabulary"); - return Storage.size(); - } + size_t getCanonicalSize() const { return Storage.size(); } + + MIRVocabulary() = delete; + + /// Factory method to create MIRVocabulary from vocabulary map + static Expected<MIRVocabulary> create(VocabMap &&Entries, + const TargetInstrInfo &TII); + +private: + MIRVocabulary(VocabMap &&Entries, const TargetInstrInfo &TII); }; } // namespace mir2vec @@ -145,7 +131,6 @@ class MIR2VecVocabLegacyAnalysis : public ImmutablePass { StringRef getPassName() const override; Error readVocabulary(); - void emitError(Error Err, LLVMContext &Ctx); protected: void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -156,7 +141,7 @@ protected: public: static char ID; MIR2VecVocabLegacyAnalysis() : ImmutablePass(ID) {} - mir2vec::MIRVocabulary getMIR2VecVocabulary(const Module &M); + Expected<mir2vec::MIRVocabulary> getMIR2VecVocabulary(const Module &M); }; /// This pass prints the embeddings in the MIR2Vec vocabulary diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h index bfcbf72..7ef6667 100644 --- a/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h +++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h @@ -27,160 +27,15 @@ class Metadata; namespace hlsl { namespace rootsig { - -template <typename T> class RootSignatureValidationError - : public ErrorInfo<RootSignatureValidationError<T>> { -public: - static char ID; - StringRef ParamName; - T Value; - - RootSignatureValidationError(StringRef ParamName, T Value) - : ParamName(ParamName), Value(Value) {} - - void log(raw_ostream &OS) const override { - OS << "Invalid value for " << ParamName << ": " << Value; - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class OffsetAppendAfterOverflow : public ErrorInfo<OffsetAppendAfterOverflow> { -public: - static char ID; - dxil::ResourceClass Type; - uint32_t Register; - uint32_t Space; - - OffsetAppendAfterOverflow(dxil::ResourceClass Type, uint32_t Register, - uint32_t Space) - : Type(Type), Register(Register), Space(Space) {} - - void log(raw_ostream &OS) const override { - OS << "Range " << getResourceClassName(Type) << "(register=" << Register - << ", space=" << Space << ") " - << "cannot be appended after an unbounded range "; - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class ShaderRegisterOverflowError - : public ErrorInfo<ShaderRegisterOverflowError> { -public: - static char ID; - dxil::ResourceClass Type; - uint32_t Register; - uint32_t Space; - - ShaderRegisterOverflowError(dxil::ResourceClass Type, uint32_t Register, - uint32_t Space) - : Type(Type), Register(Register), Space(Space) {} - - void log(raw_ostream &OS) const override { - OS << "Overflow for shader register range: " << getResourceClassName(Type) - << "(register=" << Register << ", space=" << Space << ")."; - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class OffsetOverflowError : public ErrorInfo<OffsetOverflowError> { -public: - static char ID; - dxil::ResourceClass Type; - uint32_t Register; - uint32_t Space; - - OffsetOverflowError(dxil::ResourceClass Type, uint32_t Register, - uint32_t Space) - : Type(Type), Register(Register), Space(Space) {} - - void log(raw_ostream &OS) const override { - OS << "Offset overflow for descriptor range: " << getResourceClassName(Type) - << "(register=" << Register << ", space=" << Space << ")."; - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class TableSamplerMixinError : public ErrorInfo<TableSamplerMixinError> { + : public ErrorInfo<RootSignatureValidationError> { public: static char ID; - dxil::ResourceClass Type; - uint32_t Location; - - TableSamplerMixinError(dxil::ResourceClass Type, uint32_t Location) - : Type(Type), Location(Location) {} - - void log(raw_ostream &OS) const override { - OS << "Samplers cannot be mixed with other " - << "resource types in a descriptor table, " << getResourceClassName(Type) - << "(location=" << Location << ")"; - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class GenericRSMetadataError : public ErrorInfo<GenericRSMetadataError> { -public: - LLVM_ABI static char ID; - StringRef Message; - MDNode *MD; - - GenericRSMetadataError(StringRef Message, MDNode *MD) - : Message(Message), MD(MD) {} - - void log(raw_ostream &OS) const override { - OS << Message; - if (MD) { - OS << "\n"; - MD->printTree(OS); - } - } - - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class InvalidRSMetadataFormat : public ErrorInfo<InvalidRSMetadataFormat> { -public: - LLVM_ABI static char ID; - StringRef ElementName; + std::string Msg; - InvalidRSMetadataFormat(StringRef ElementName) : ElementName(ElementName) {} - - void log(raw_ostream &OS) const override { - OS << "Invalid format for " << ElementName; - } + RootSignatureValidationError(const Twine &Msg) : Msg(Msg.str()) {} - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } -}; - -class InvalidRSMetadataValue : public ErrorInfo<InvalidRSMetadataValue> { -public: - LLVM_ABI static char ID; - StringRef ParamName; - - InvalidRSMetadataValue(StringRef ParamName) : ParamName(ParamName) {} - - void log(raw_ostream &OS) const override { - OS << "Invalid value for " << ParamName; - } + void log(raw_ostream &OS) const override { OS << Msg; } std::error_code convertToErrorCode() const override { return llvm::inconvertibleErrorCode(); diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 01ca8da..1694a33 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -42,6 +42,7 @@ __OMP_TYPE(Double) OMP_TYPE(SizeTy, M.getDataLayout().getIntPtrType(Ctx)) OMP_TYPE(Int63, Type::getIntNTy(Ctx, 63)) +OMP_TYPE(FuncPtrTy, PointerType::get(Ctx, M.getDataLayout().getProgramAddressSpace())) __OMP_PTR_TYPE(VoidPtr) __OMP_PTR_TYPE(VoidPtrPtr) @@ -471,7 +472,7 @@ __OMP_RTL(__kmpc_target_init, false, Int32, KernelEnvironmentPtr, KernelLaunchEn __OMP_RTL(__kmpc_target_deinit, false, Void,) __OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr) __OMP_RTL(__kmpc_parallel_51, false, Void, IdentPtr, Int32, Int32, Int32, Int32, - VoidPtr, VoidPtr, VoidPtrPtr, SizeTy) + FuncPtrTy, VoidPtr, VoidPtrPtr, SizeTy) __OMP_RTL(__kmpc_for_static_loop_4, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8) __OMP_RTL(__kmpc_for_static_loop_4u, false, Void, IdentPtr, VoidPtr, VoidPtr, Int32, Int32, Int32, Int8) __OMP_RTL(__kmpc_for_static_loop_8, false, Void, IdentPtr, VoidPtr, VoidPtr, Int64, Int64, Int64, Int8) diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h index 25cbc38..f3839c9 100644 --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -146,9 +146,9 @@ namespace llvm { /// \param SDK The SDK name. On Darwin, this is the last component /// of the sysroot. LLVM_ABI DICompileUnit * - createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, - bool isOptimized, StringRef Flags, unsigned RV, - StringRef SplitName = StringRef(), + createCompileUnit(DISourceLanguageName Lang, DIFile *File, + StringRef Producer, bool isOptimized, StringRef Flags, + unsigned RV, StringRef SplitName = StringRef(), DICompileUnit::DebugEmissionKind Kind = DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId = 0, bool SplitDebugInlining = true, @@ -729,7 +729,8 @@ namespace llvm { /// \param Subscripts Subscripts. LLVM_ABI DICompositeType *createVectorType(uint64_t Size, uint32_t AlignInBits, DIType *Ty, - DINodeArray Subscripts); + DINodeArray Subscripts, + Metadata *BitStride = nullptr); /// Create debugging information entry for an /// enumeration. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 7c6e709..c626efc 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -66,6 +66,55 @@ namespace dwarf { enum Tag : uint16_t; } +/// Wrapper structure that holds a language name and its version. +/// +/// Some debug-info formats, particularly DWARF, distniguish between +/// language codes that include the version name and codes that don't. +/// DISourceLanguageName may hold either of these. +/// +class DISourceLanguageName { + /// Language version. The version scheme is language + /// dependent. + uint32_t Version = 0; + + /// Language name. + /// If \ref HasVersion is \c true, then this name + /// is version independent (i.e., doesn't include the language + /// version in its name). + uint16_t Name; + + /// If \c true, then \ref Version is interpretable and \ref Name + /// is a version independent name. + bool HasVersion; + +public: + bool hasVersionedName() const { return HasVersion; } + + /// Returns a versioned or unversioned language name. + uint16_t getName() const { return Name; } + + /// Transitional API for cases where we do not yet support + /// versioned source language names. Use \ref getName instead. + /// + /// FIXME: remove once all callers of this API account for versioned + /// names. + uint16_t getUnversionedName() const { + assert(!hasVersionedName()); + return Name; + } + + /// Returns language version. Only valid for versioned language names. + uint32_t getVersion() const { + assert(hasVersionedName()); + return Version; + } + + DISourceLanguageName(uint16_t Lang, uint32_t Version) + : Version(Version), Name(Lang), HasVersion(true) {}; + DISourceLanguageName(uint16_t Lang) + : Version(0), Name(Lang), HasVersion(false) {}; +}; + class DbgVariableRecord; LLVM_ABI extern cl::opt<bool> EnableFSDiscriminator; @@ -2003,7 +2052,7 @@ public: LLVM_ABI static const char *nameTableKindString(DebugNameTableKind PK); private: - unsigned SourceLanguage; + DISourceLanguageName SourceLanguage; unsigned RuntimeVersion; uint64_t DWOId; unsigned EmissionKind; @@ -2013,16 +2062,17 @@ private: bool DebugInfoForProfiling; bool RangesBaseAddress; - DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage, - bool IsOptimized, unsigned RuntimeVersion, - unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, - bool DebugInfoForProfiling, unsigned NameTableKind, - bool RangesBaseAddress, ArrayRef<Metadata *> Ops); + DICompileUnit(LLVMContext &C, StorageType Storage, + DISourceLanguageName SourceLanguage, bool IsOptimized, + unsigned RuntimeVersion, unsigned EmissionKind, uint64_t DWOId, + bool SplitDebugInlining, bool DebugInfoForProfiling, + unsigned NameTableKind, bool RangesBaseAddress, + ArrayRef<Metadata *> Ops); ~DICompileUnit() = default; static DICompileUnit * - getImpl(LLVMContext &Context, unsigned SourceLanguage, DIFile *File, - StringRef Producer, bool IsOptimized, StringRef Flags, + getImpl(LLVMContext &Context, DISourceLanguageName SourceLanguage, + DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, StringRef SplitDebugFilename, unsigned EmissionKind, DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, @@ -2042,8 +2092,8 @@ private: getCanonicalMDString(Context, SDK), Storage, ShouldCreate); } LLVM_ABI static DICompileUnit * - getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, - MDString *Producer, bool IsOptimized, MDString *Flags, + getImpl(LLVMContext &Context, DISourceLanguageName SourceLanguage, + Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, Metadata *ImportedEntities, @@ -2068,7 +2118,7 @@ public: DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, - (unsigned SourceLanguage, DIFile *File, StringRef Producer, + (DISourceLanguageName SourceLanguage, DIFile *File, StringRef Producer, bool IsOptimized, StringRef Flags, unsigned RuntimeVersion, StringRef SplitDebugFilename, DebugEmissionKind EmissionKind, DICompositeTypeArray EnumTypes, DIScopeArray RetainedTypes, @@ -2084,7 +2134,7 @@ public: SysRoot, SDK)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, - (unsigned SourceLanguage, Metadata *File, MDString *Producer, + (DISourceLanguageName SourceLanguage, Metadata *File, MDString *Producer, bool IsOptimized, MDString *Flags, unsigned RuntimeVersion, MDString *SplitDebugFilename, unsigned EmissionKind, Metadata *EnumTypes, Metadata *RetainedTypes, Metadata *GlobalVariables, @@ -2099,7 +2149,7 @@ public: TempDICompileUnit clone() const { return cloneImpl(); } - unsigned getSourceLanguage() const { return SourceLanguage; } + DISourceLanguageName getSourceLanguage() const { return SourceLanguage; } bool isOptimized() const { return IsOptimized; } unsigned getRuntimeVersion() const { return RuntimeVersion; } DebugEmissionKind getEmissionKind() const { diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h index 5f7225e..a426fb0 100644 --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/Support/BranchProbability.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -555,6 +556,7 @@ public: Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {} LLVM_ABI Argument(StringRef Key, DebugLoc dl); LLVM_ABI Argument(StringRef Key, InstructionCost C); + LLVM_ABI Argument(StringRef Key, BranchProbability P); }; /// \p PassName is the name of the pass emitting this diagnostic. \p diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 96da698..8856eda 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -1983,16 +1983,16 @@ def int_experimental_vector_match : DefaultAttrsIntrinsic< [ llvm_anyvector_ty, llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty> ], // Mask - [ IntrNoMem ]>; + [ IntrNoMem, IntrSpeculatable ]>; // Extract based on mask bits def int_experimental_vector_extract_last_active: DefaultAttrsIntrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - LLVMVectorElementType<0>], [IntrNoMem]>; + LLVMVectorElementType<0>], [IntrNoMem, IntrSpeculatable]>; // Operators -let IntrProperties = [IntrNoMem] in { +let IntrProperties = [IntrNoMem, IntrSpeculatable] in { // Integer arithmetic def int_vp_add : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], [ LLVMMatchType<0>, @@ -2039,26 +2039,6 @@ let IntrProperties = [IntrNoMem] in { LLVMMatchType<0>, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_i32_ty]>; - def int_vp_sdiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - llvm_i32_ty]>; - def int_vp_udiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - llvm_i32_ty]>; - def int_vp_srem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - llvm_i32_ty]>; - def int_vp_urem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], - [ LLVMMatchType<0>, - LLVMMatchType<0>, - LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, - llvm_i32_ty]>; def int_vp_abs : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], [ LLVMMatchType<0>, llvm_i1_ty, @@ -2390,7 +2370,29 @@ let IntrProperties = [IntrNoMem] in { llvm_i32_ty]>; } -let IntrProperties = [IntrNoMem, ImmArg<ArgIndex<1>>] in { +// Integer VP division and remainder: not speculatable. +def int_vp_sdiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, + llvm_i32_ty], [IntrNoMem]>; +def int_vp_udiv : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, + llvm_i32_ty], [IntrNoMem]>; +def int_vp_srem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, + llvm_i32_ty], [IntrNoMem]>; +def int_vp_urem : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], + [ LLVMMatchType<0>, + LLVMMatchType<0>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, + llvm_i32_ty], [IntrNoMem]>; + +let IntrProperties = [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>] in { def int_vp_ctlz : DefaultAttrsIntrinsic<[ llvm_anyvector_ty ], [ LLVMMatchType<0>, llvm_i1_ty, @@ -2422,18 +2424,18 @@ def int_loop_dependence_war_mask: def int_get_active_lane_mask: DefaultAttrsIntrinsic<[llvm_anyvector_ty], [llvm_anyint_ty, LLVMMatchType<1>], - [IntrNoMem]>; + [IntrNoMem, IntrSpeculatable]>; def int_experimental_get_vector_length: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_anyint_ty, llvm_i32_ty, llvm_i1_ty], - [IntrNoMem, + [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>; def int_experimental_cttz_elts: DefaultAttrsIntrinsic<[llvm_anyint_ty], [llvm_anyvector_ty, llvm_i1_ty], - [IntrNoMem, ImmArg<ArgIndex<1>>]>; + [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>; def int_experimental_vp_splice: DefaultAttrsIntrinsic<[llvm_anyvector_ty], @@ -2442,21 +2444,21 @@ def int_experimental_vp_splice: llvm_i32_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, ImmArg<ArgIndex<2>>]>; + [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>]>; def int_experimental_vp_reverse: DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, IntrSpeculatable]>; def int_experimental_vp_splat: DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, IntrSpeculatable]>; def int_vp_is_fpclass: DefaultAttrsIntrinsic<[ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], @@ -2753,16 +2755,22 @@ def int_preserve_static_offset : DefaultAttrsIntrinsic<[llvm_ptr_ty], def int_vector_reverse : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>], - [IntrNoMem]>; + [IntrNoMem, + IntrSpeculatable]>; def int_vector_splice : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], - [IntrNoMem, ImmArg<ArgIndex<2>>]>; + [IntrNoMem, + IntrSpeculatable, + ImmArg<ArgIndex<2>>]>; //===---------- Intrinsics to query properties of scalable vectors --------===// -def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], [], [IntrNoMem]>; +def int_vscale : DefaultAttrsIntrinsic<[llvm_anyint_ty], + [], + [IntrNoMem, + IntrSpeculatable]>; //===---------- Intrinsics to perform subvector insertion/extraction ------===// def int_vector_insert : DefaultAttrsIntrinsic<[llvm_anyvector_ty], @@ -2776,18 +2784,22 @@ def int_vector_extract : DefaultAttrsIntrinsic<[llvm_anyvector_ty], foreach n = 2...8 in { def int_vector_interleave#n : DefaultAttrsIntrinsic<[llvm_anyvector_ty], !listsplat(LLVMOneNthElementsVectorType<0, n>, n), - [IntrNoMem]>; + [IntrNoMem, + IntrSpeculatable]>; def int_vector_deinterleave#n : DefaultAttrsIntrinsic<!listsplat(LLVMOneNthElementsVectorType<0, n>, n), [llvm_anyvector_ty], - [IntrNoMem]>; + [IntrNoMem, + IntrSpeculatable]>; } //===-------------- Intrinsics to perform partial reduction ---------------===// def int_vector_partial_reduce_add : DefaultAttrsIntrinsic<[LLVMMatchType<0>], - [llvm_anyvector_ty, llvm_anyvector_ty], - [IntrNoMem]>; + [llvm_anyvector_ty, + llvm_anyvector_ty], + [IntrNoMem, + IntrSpeculatable]>; //===----------------- Pointer Authentication Intrinsics ------------------===// // diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 64cad80..466e2a4 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -12,13 +12,16 @@ #ifndef LLVM_SUPPORT_SPECIALCASELIST_H #define LLVM_SUPPORT_SPECIALCASELIST_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/GlobPattern.h" #include "llvm/Support/Regex.h" #include <memory> #include <string> #include <utility> +#include <variant> #include <vector> namespace llvm { @@ -118,11 +121,49 @@ protected: SpecialCaseList(SpecialCaseList const &) = delete; SpecialCaseList &operator=(SpecialCaseList const &) = delete; - /// Represents a set of globs and their line numbers +private: + // Lagacy v1 matcher. + class RegexMatcher { + public: + LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); + LLVM_ABI void + match(StringRef Query, + llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const; + + struct Reg { + Reg(StringRef Name, unsigned LineNo, Regex &&Rg) + : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {} + StringRef Name; + unsigned LineNo; + Regex Rg; + }; + + std::vector<Reg> RegExes; + }; + + class GlobMatcher { + public: + LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); + LLVM_ABI void + match(StringRef Query, + llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const; + + struct Glob { + Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern) + : Name(Name), LineNo(LineNo), Pattern(std::move(Pattern)) {} + StringRef Name; + unsigned LineNo; + GlobPattern Pattern; + }; + + std::vector<GlobMatcher::Glob> Globs; + }; + + /// Represents a set of patterns and their line numbers class Matcher { public: - LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber, - bool UseRegex); + LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash); + LLVM_ABI void match(StringRef Query, llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const; @@ -133,36 +174,19 @@ protected: return R; } - struct Glob { - Glob(StringRef Name, unsigned LineNo) : Name(Name), LineNo(LineNo) {} - std::string Name; - unsigned LineNo; - GlobPattern Pattern; - // neither copyable nor movable because GlobPattern contains - // Glob::StringRef that points to Glob::Name. - Glob(Glob &&) = delete; - 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; - }; + LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); - std::vector<std::unique_ptr<Matcher::Glob>> Globs; - std::vector<std::unique_ptr<Reg>> RegExes; + std::variant<RegexMatcher, GlobMatcher> M; + bool RemoveDotSlash; }; using SectionEntries = StringMap<StringMap<Matcher>>; +protected: struct Section { - Section(StringRef Str, unsigned FileIdx) - : SectionStr(Str), FileIdx(FileIdx) {}; + Section(StringRef Str, unsigned FileIdx, bool UseGlobs) + : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false), SectionStr(Str), + FileIdx(FileIdx) {} Section(Section &&) = default; @@ -186,11 +210,15 @@ protected: findMatcher(StringRef Prefix, StringRef Category) const; }; + ArrayRef<const Section> sections() const { return Sections; } + +private: + BumpPtrAllocator StrAlloc; std::vector<Section> Sections; LLVM_ABI Expected<Section *> addSection(StringRef SectionStr, unsigned FileIdx, unsigned LineNo, - bool UseGlobs = true); + bool UseGlobs); /// Parses just-constructed SpecialCaseList entries from a memory buffer. LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB, diff --git a/llvm/include/llvm/Support/TrailingObjects.h b/llvm/include/llvm/Support/TrailingObjects.h index dc03285..c479765 100644 --- a/llvm/include/llvm/Support/TrailingObjects.h +++ b/llvm/include/llvm/Support/TrailingObjects.h @@ -182,8 +182,6 @@ protected: static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar) { return SizeSoFar; } - - template <bool CheckAlignment> static void verifyTrailingObjectsAlignment() {} }; } // end namespace trailing_objects_internal @@ -203,10 +201,7 @@ class TrailingObjects template <typename... Tys> class Foo {}; - typedef trailing_objects_internal::TrailingObjectsImpl< - trailing_objects_internal::MaxAlignment<TrailingTys...>, BaseTy, - TrailingObjects<BaseTy, TrailingTys...>, BaseTy, TrailingTys...> - ParentType; + using ParentType = typename TrailingObjects::TrailingObjectsImpl; using TrailingObjectsBase = trailing_objects_internal::TrailingObjectsBase; using ParentType::getTrailingObjectsImpl; 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/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; |