diff options
Diffstat (limited to 'include')
169 files changed, 2376 insertions, 1711 deletions
diff --git a/include/llvm-c/OrcBindings.h b/include/llvm-c/OrcBindings.h index de2969ab1c9bb..d86ea88088893 100644 --- a/include/llvm-c/OrcBindings.h +++ b/include/llvm-c/OrcBindings.h @@ -29,6 +29,8 @@ extern "C" { #endif +typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef; +typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef; typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef; typedef uint32_t LLVMOrcModuleHandle; typedef uint64_t LLVMOrcTargetAddress; @@ -39,6 +41,45 @@ typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack, typedef enum { LLVMOrcErrSuccess = 0, LLVMOrcErrGeneric } LLVMOrcErrorCode; /** + * Turn an LLVMModuleRef into an LLVMSharedModuleRef. + * + * The JIT uses shared ownership for LLVM modules, since it is generally + * difficult to know when the JIT will be finished with a module (and the JIT + * has no way of knowing when a user may be finished with one). + * + * Calling this method with an LLVMModuleRef creates a shared-pointer to the + * module, and returns a reference to this shared pointer. + * + * The shared module should be disposed when finished with by calling + * LLVMOrcDisposeSharedModule (not LLVMDisposeModule). The Module will be + * deleted when the last shared pointer owner relinquishes it. + */ + +LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod); + +/** + * Dispose of a shared module. + * + * The module should not be accessed after this call. The module will be + * deleted once all clients (including the JIT itself) have released their + * shared pointers. + */ + +void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod); + +/** + * Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef. + */ +LLVMSharedObjectBufferRef +LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer); + +/** + * Dispose of a shared object buffer. + */ +void +LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer); + +/** * Create an ORC JIT stack. * * The client owns the resulting stack, and must call OrcDisposeInstance(...) @@ -95,7 +136,8 @@ LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, * Add module to be eagerly compiled. */ LLVMOrcModuleHandle -LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); @@ -103,7 +145,8 @@ LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, * Add module to be lazily compiled one function at a time. */ LLVMOrcModuleHandle -LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, +LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, + LLVMSharedModuleRef Mod, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); @@ -111,7 +154,7 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod, * Add an object file. */ LLVMOrcModuleHandle LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, - LLVMObjectFileRef Obj, + LLVMSharedObjectBufferRef Obj, LLVMOrcSymbolResolverFn SymbolResolver, void *SymbolResolverCtx); diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index bef6efde1f012..9c5e392c48087 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -140,8 +140,8 @@ enum lostFraction { // Example of truncated bits: // implementation classes. This struct should not define any non-static data // members. struct APFloatBase { - // TODO remove this and use APInt typedef directly. typedef APInt::WordType integerPart; + static const unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD; /// A signed type to represent a floating point numbers unbiased exponent. typedef signed short ExponentType; diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index ef9c66d2d700b..e5f0c35534ac9 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -213,6 +213,12 @@ private: /// out-of-line slow case for countLeadingZeros unsigned countLeadingZerosSlowCase() const LLVM_READONLY; + /// out-of-line slow case for countLeadingOnes. + unsigned countLeadingOnesSlowCase() const LLVM_READONLY; + + /// out-of-line slow case for countTrailingZeros. + unsigned countTrailingZerosSlowCase() const LLVM_READONLY; + /// out-of-line slow case for countTrailingOnes unsigned countTrailingOnesSlowCase() const LLVM_READONLY; @@ -383,7 +389,7 @@ public: bool isAllOnesValue() const { if (isSingleWord()) return U.VAL == WORD_MAX >> (APINT_BITS_PER_WORD - BitWidth); - return countPopulationSlowCase() == BitWidth; + return countTrailingOnesSlowCase() == BitWidth; } /// \brief Determine if all bits are clear @@ -408,7 +414,9 @@ public: /// This checks to see if the value of this APInt is the maximum signed /// value for the APInt's bit width. bool isMaxSignedValue() const { - return !isNegative() && countPopulation() == BitWidth - 1; + if (isSingleWord()) + return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1); + return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1; } /// \brief Determine if this is the smallest unsigned value. @@ -422,7 +430,9 @@ public: /// This checks to see if the value of this APInt is the minimum signed /// value for the APInt's bit width. bool isMinSignedValue() const { - return isNegative() && isPowerOf2(); + if (isSingleWord()) + return U.VAL == (WordType(1) << (BitWidth - 1)); + return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1; } /// \brief Check if this APInt has an N-bits unsigned integer value. @@ -1574,7 +1584,11 @@ public: /// /// \returns 0 if the high order bit is not set, otherwise returns the number /// of 1 bits from the most significant to the least - unsigned countLeadingOnes() const LLVM_READONLY; + unsigned countLeadingOnes() const { + if (isSingleWord()) + return llvm::countLeadingOnes(U.VAL << (APINT_BITS_PER_WORD - BitWidth)); + return countLeadingOnesSlowCase(); + } /// Computes the number of leading bits of this APInt that are equal to its /// sign bit. @@ -1590,7 +1604,11 @@ public: /// /// \returns BitWidth if the value is zero, otherwise returns the number of /// zeros from the least significant bit to the first one bit. - unsigned countTrailingZeros() const LLVM_READONLY; + unsigned countTrailingZeros() const { + if (isSingleWord()) + return std::min(unsigned(llvm::countTrailingZeros(U.VAL)), BitWidth); + return countTrailingZerosSlowCase(); + } /// \brief Count the number of trailing one bits. /// diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index ffcf998a3d323..cc32bf43f29c8 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -15,10 +15,12 @@ #define LLVM_ADT_STRINGEXTRAS_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include <cassert> #include <cstddef> #include <cstdint> +#include <cstdlib> #include <cstring> #include <iterator> #include <string> @@ -129,6 +131,32 @@ template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) { return !S.getAsInteger(Base, Num); } +namespace detail { +template <typename N> +inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) { + SmallString<32> Storage; + StringRef S = T.toNullTerminatedStringRef(Storage); + char *End; + N Temp = StrTo(S.data(), &End); + if (*End != '\0') + return false; + Num = Temp; + return true; +} +} + +inline bool to_float(const Twine &T, float &Num) { + return detail::to_float(T, Num, strtof); +} + +inline bool to_float(const Twine &T, double &Num) { + return detail::to_float(T, Num, strtod); +} + +inline bool to_float(const Twine &T, long double &Num) { + return detail::to_float(T, Num, strtold); +} + static inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[21]; char *BufPtr = std::end(Buffer); diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 26a991812a3a5..cd560658ca4ec 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -147,6 +147,7 @@ public: enum OSType { UnknownOS, + Ananas, CloudABI, Darwin, DragonFly, diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h index 7b178fc7bcc21..787c88cc6ec1a 100644 --- a/include/llvm/Analysis/LazyValueInfo.h +++ b/include/llvm/Analysis/LazyValueInfo.h @@ -93,6 +93,13 @@ public: Constant *getConstantOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB, Instruction *CxtI = nullptr); + /// Return the ConstantRage constraint that is known to hold for the + /// specified value on the specified edge. This may be only be called + /// on integer-typed Values. + ConstantRange getConstantRangeOnEdge(Value *V, BasicBlock *FromBB, + BasicBlock *ToBB, + Instruction *CxtI = nullptr); + /// Inform the analysis cache that we have threaded an edge from /// PredBB to OldSucc to be from PredBB to NewSucc instead. void threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, BasicBlock *NewSucc); diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h index a59c1f88e229f..f110c28bfc6d2 100644 --- a/include/llvm/Analysis/Loads.h +++ b/include/llvm/Analysis/Loads.h @@ -39,6 +39,15 @@ bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, const Instruction *CtxI = nullptr, const DominatorTree *DT = nullptr); +/// Returns true if V is always dereferenceable for Size byte with alignment +/// greater or equal than requested. If the context instruction is specified +/// performs context-sensitive analysis and returns true if the pointer is +/// dereferenceable at the specified instruction. +bool isDereferenceableAndAlignedPointer(const Value *V, unsigned Align, + const APInt &Size, const DataLayout &DL, + const Instruction *CtxI = nullptr, + const DominatorTree *DT = nullptr); + /// Return true if we know that executing a load from this value cannot trap. /// /// If DT and ScanFrom are specified this method performs context-sensitive diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 6ff4335f1ad5d..372fc8b21745c 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -91,8 +91,9 @@ getExitEdges(SmallVectorImpl<Edge> &ExitEdges) const { /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop -/// from outside of the loop. If this is the case, the block branching to the -/// header of the loop is the preheader node. +/// from outside of the loop and it is legal to hoist instructions into the +/// predecessor. If this is the case, the block branching to the header of the +/// loop is the preheader node. /// /// This method returns null if there is no preheader for the loop. /// @@ -102,6 +103,10 @@ BlockT *LoopBase<BlockT, LoopT>::getLoopPreheader() const { BlockT *Out = getLoopPredecessor(); if (!Out) return nullptr; + // Make sure we are allowed to hoist instructions into the predecessor. + if (!Out->isLegalToHoistInto()) + return nullptr; + // Make sure there is only one exit out of the preheader. typedef GraphTraits<BlockT*> BlockTraits; typename BlockTraits::ChildIteratorType SI = BlockTraits::child_begin(Out); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 2a4b768256d1b..002a3174fd19d 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -784,7 +784,9 @@ private: } /// Determine the range for a particular SCEV. - ConstantRange getRange(const SCEV *S, RangeSignHint Hint); + /// NOTE: This returns a reference to an entry in a cache. It must be + /// copied if its needed for longer. + const ConstantRange &getRangeRef(const SCEV *S, RangeSignHint Hint); /// Determines the range for the affine SCEVAddRecExpr {\p Start,+,\p Stop}. /// Helper for \c getRange. @@ -1464,15 +1466,35 @@ public: uint32_t GetMinTrailingZeros(const SCEV *S); /// Determine the unsigned range for a particular SCEV. - /// + /// NOTE: This returns a copy of the reference returned by getRangeRef. ConstantRange getUnsignedRange(const SCEV *S) { - return getRange(S, HINT_RANGE_UNSIGNED); + return getRangeRef(S, HINT_RANGE_UNSIGNED); + } + + /// Determine the min of the unsigned range for a particular SCEV. + APInt getUnsignedRangeMin(const SCEV *S) { + return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMin(); + } + + /// Determine the max of the unsigned range for a particular SCEV. + APInt getUnsignedRangeMax(const SCEV *S) { + return getRangeRef(S, HINT_RANGE_UNSIGNED).getUnsignedMax(); } /// Determine the signed range for a particular SCEV. - /// + /// NOTE: This returns a copy of the reference returned by getRangeRef. ConstantRange getSignedRange(const SCEV *S) { - return getRange(S, HINT_RANGE_SIGNED); + return getRangeRef(S, HINT_RANGE_SIGNED); + } + + /// Determine the min of the signed range for a particular SCEV. + APInt getSignedRangeMin(const SCEV *S) { + return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMin(); + } + + /// Determine the max of the signed range for a particular SCEV. + APInt getSignedRangeMax(const SCEV *S) { + return getRangeRef(S, HINT_RANGE_SIGNED).getSignedMax(); } /// Test if the given expression is known to be negative. diff --git a/include/llvm/BinaryFormat/COFF.h b/include/llvm/BinaryFormat/COFF.h index 5171c72b9e670..df173a80e09b1 100644 --- a/include/llvm/BinaryFormat/COFF.h +++ b/include/llvm/BinaryFormat/COFF.h @@ -46,6 +46,12 @@ static const char ClGlObjMagic[] = { '\xac', '\x9b', '\xd6', '\xb6', '\x22', '\x26', '\x53', '\xc2', }; +// The signature bytes that start a .res file. +static const char WinResMagic[] = { + '\x00', '\x00', '\x00', '\x00', '\x20', '\x00', '\x00', '\x00', + '\xff', '\xff', '\x00', '\x00', '\xff', '\xff', '\x00', '\x00', +}; + // Sizes in bytes of various things in the COFF format. enum { Header16Size = 20, diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index b7a056b18119d..ab927565d05d5 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/include/llvm/BinaryFormat/Dwarf.h @@ -484,7 +484,7 @@ private: }; /// Constants that define the DWARF format as 32 or 64 bit. -enum DwarfFormat { DWARF32, DWARF64 }; +enum DwarfFormat : uint8_t { DWARF32, DWARF64 }; } // End of namespace dwarf diff --git a/include/llvm/BinaryFormat/MachO.h b/include/llvm/BinaryFormat/MachO.h index 8ab6dde800c2b..3529c72acd9d6 100644 --- a/include/llvm/BinaryFormat/MachO.h +++ b/include/llvm/BinaryFormat/MachO.h @@ -78,7 +78,8 @@ enum { MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u, MH_HAS_TLV_DESCRIPTORS = 0x00800000u, MH_NO_HEAP_EXECUTION = 0x01000000u, - MH_APP_EXTENSION_SAFE = 0x02000000u + MH_APP_EXTENSION_SAFE = 0x02000000u, + MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u }; enum : uint32_t { diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index fcd8ad957040f..470c20ddc7d90 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -176,6 +176,11 @@ enum class ValType { // Linking metadata kinds. enum : unsigned { WASM_STACK_POINTER = 0x1, + WASM_SYMBOL_INFO = 0x2, +}; + +enum : unsigned { + WASM_SYMBOL_FLAG_WEAK = 0x1, }; #define WASM_RELOC(name, value) name = value, diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index 5ed5faa2c4150..f809fc97fe593 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -121,8 +121,8 @@ public: /// Print the abbreviation using the specified asm printer. void Emit(const AsmPrinter *AP) const; - void print(raw_ostream &O); - void dump(); + void print(raw_ostream &O) const; + void dump() const; }; //===--------------------------------------------------------------------===// @@ -780,7 +780,7 @@ public: DIEValue findAttribute(dwarf::Attribute Attribute) const; void print(raw_ostream &O, unsigned IndentCount = 0) const; - void dump(); + void dump() const; }; //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index 1a865c3f0dce7..b3ef7c2dc1859 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -29,6 +29,7 @@ class MachineOperand; class MachineRegisterInfo; class RegisterBankInfo; class TargetInstrInfo; +class TargetRegisterClass; class TargetRegisterInfo; /// Container class for CodeGen predicate results. @@ -79,6 +80,16 @@ protected: InstructionSelector(); + /// Constrain a register operand of an instruction \p I to a specified + /// register class. This could involve inserting COPYs before (for uses) or + /// after (for defs) and may replace the operand of \p I. + /// \returns whether operand regclass constraining succeeded. + bool constrainOperandRegToRegClass(MachineInstr &I, unsigned OpIdx, + const TargetRegisterClass &RC, + const TargetInstrInfo &TII, + const TargetRegisterInfo &TRI, + const RegisterBankInfo &RBI) const; + /// Mutate the newly-selected instruction \p I to constrain its (possibly /// generic) virtual register operands to the instruction's register class. /// This could involve inserting COPYs before (for uses) or after (for defs). diff --git a/include/llvm/CodeGen/GlobalISel/Legalizer.h b/include/llvm/CodeGen/GlobalISel/Legalizer.h index bed7230cc013b..9b9b8b563a30e 100644 --- a/include/llvm/CodeGen/GlobalISel/Legalizer.h +++ b/include/llvm/CodeGen/GlobalISel/Legalizer.h @@ -59,7 +59,7 @@ public: const TargetInstrInfo &TII); bool combineMerges(MachineInstr &MI, MachineRegisterInfo &MRI, - const TargetInstrInfo &TII); + const TargetInstrInfo &TII, MachineIRBuilder &MIRBuilder); bool runOnMachineFunction(MachineFunction &MF) override; }; diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 4e7b8350038b8..c9327d50432e1 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -471,10 +471,12 @@ public: /// Build and insert \p Res = IMPLICIT_DEF. MachineInstrBuilder buildUndef(unsigned Dst); - /// Build and insert \p Res<def> = G_SEQUENCE \p Op0, \p Idx0... + /// Build and insert instructions to put \p Ops together at the specified p + /// Indices to form a larger register. /// - /// G_SEQUENCE inserts each element of Ops into an IMPLICIT_DEF register, - /// where each entry starts at the bit-index specified by \p Indices. + /// If the types of the input registers are uniform and cover the entirity of + /// \p Res then a G_MERGE_VALUES will be produced. Otherwise an IMPLICIT_DEF + /// followed by a sequence of G_INSERT instructions. /// /// \pre setBasicBlock or setMI must have been called. /// \pre The final element of the sequence must not extend past the end of the @@ -482,11 +484,8 @@ public: /// \pre The bits defined by each Op (derived from index and scalar size) must /// not overlap. /// \pre \p Indices must be in ascending order of bit position. - /// - /// \return a MachineInstrBuilder for the newly created instruction. - MachineInstrBuilder buildSequence(unsigned Res, - ArrayRef<unsigned> Ops, - ArrayRef<uint64_t> Indices); + void buildSequence(unsigned Res, ArrayRef<unsigned> Ops, + ArrayRef<uint64_t> Indices); /// Build and insert \p Res<def> = G_MERGE_VALUES \p Op0, ... /// @@ -513,24 +512,6 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildUnmerge(ArrayRef<unsigned> Res, unsigned Op); - void addUsesWithIndices(MachineInstrBuilder MIB) {} - - template <typename... ArgTys> - void addUsesWithIndices(MachineInstrBuilder MIB, unsigned Reg, - unsigned BitIndex, ArgTys... Args) { - MIB.addUse(Reg).addImm(BitIndex); - addUsesWithIndices(MIB, Args...); - } - - template <typename... ArgTys> - MachineInstrBuilder buildSequence(unsigned Res, unsigned Op, - unsigned Index, ArgTys... Args) { - MachineInstrBuilder MIB = - buildInstr(TargetOpcode::G_SEQUENCE).addDef(Res); - addUsesWithIndices(MIB, Op, Index, Args...); - return MIB; - } - MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index); diff --git a/include/llvm/CodeGen/GlobalISel/Utils.h b/include/llvm/CodeGen/GlobalISel/Utils.h index 69d5070698082..50ddbeb9432a3 100644 --- a/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/include/llvm/CodeGen/GlobalISel/Utils.h @@ -29,13 +29,26 @@ class RegisterBankInfo; class TargetInstrInfo; class TargetPassConfig; class TargetRegisterInfo; +class TargetRegisterClass; class Twine; class ConstantFP; +/// Try to constrain Reg to the specified register class. If this fails, +/// create a new virtual register in the correct class and insert a COPY before +/// \p InsertPt. The debug location of \p InsertPt is used for the new copy. +/// +/// \return The virtual register constrained to the right register class. +unsigned constrainRegToClass(MachineRegisterInfo &MRI, + const TargetInstrInfo &TII, + const RegisterBankInfo &RBI, + MachineInstr &InsertPt, unsigned Reg, + const TargetRegisterClass &RegClass); + /// Try to constrain Reg so that it is usable by argument OpIdx of the /// provided MCInstrDesc \p II. If this fails, create a new virtual /// register in the correct class and insert a COPY before \p InsertPt. -/// The debug location of \p InsertPt is used for the new copy. +/// This is equivalent to constrainRegToClass() with RegClass obtained from the +/// MCInstrDesc. The debug location of \p InsertPt is used for the new copy. /// /// \return The virtual register constrained to the right register class. unsigned constrainOperandRegClass(const MachineFunction &MF, diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index 79fa12ec2fbbb..3ba503487823d 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -196,7 +196,7 @@ public: } /// dump - Print data structures to dbgs(). - void dump(); + void dump() const; /// getOrCreateAbstractScope - Find or create an abstract lexical scope. LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope); diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 051908c40df71..97a49ce4dc4fa 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -376,6 +376,9 @@ public: /// Indicates if this is the entry block of a cleanup funclet. void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; } + /// Returns true if it is legal to hoist instructions into this block. + bool isLegalToHoistInto() const; + // Code Layout methods. /// Move 'this' block before or after the specified block. This only moves diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h index 4d83f27eac3c3..78adce507b8cd 100644 --- a/include/llvm/CodeGen/MachineMemOperand.h +++ b/include/llvm/CodeGen/MachineMemOperand.h @@ -59,6 +59,11 @@ struct MachinePointerInfo { return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O); } + /// Return true if memory region [V, V+Offset+Size) is known to be + /// dereferenceable. + bool isDereferenceable(unsigned Size, LLVMContext &C, + const DataLayout &DL) const; + /// Return the LLVM IR address space number that this pointer points into. unsigned getAddrSpace() const; diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index 61cff3890b75f..34b21ceddd434 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -77,33 +77,6 @@ public: SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); } }; -/// MachineModuleInfoWasm - This is a MachineModuleInfoImpl implementation -/// for Wasm targets. -class MachineModuleInfoWasm : public MachineModuleInfoImpl { - /// WebAssembly global variables defined by CodeGen. - std::vector<wasm::Global> Globals; - - /// The WebAssembly global variable which is the stack pointer. - unsigned StackPointerGlobal; - - virtual void anchor(); // Out of line virtual method. -public: - MachineModuleInfoWasm(const MachineModuleInfo &) - : StackPointerGlobal(-1U) {} - - void addGlobal(const wasm::Global &G) { Globals.push_back(G); } - const std::vector<wasm::Global> &getGlobals() const { return Globals; } - - bool hasStackPointerGlobal() const { - return StackPointerGlobal != -1U; - } - unsigned getStackPointerGlobal() const { - assert(hasStackPointerGlobal() && "Stack ptr global hasn't been set"); - return StackPointerGlobal; - } - void setStackPointerGlobal(unsigned Global) { StackPointerGlobal = Global; } -}; - } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index 3b02ec400abac..34cbffa78203a 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -203,7 +203,7 @@ public: MachineBasicBlock::iterator End, unsigned NumRegionInstrs) {} - virtual void dumpPolicy() {} + virtual void dumpPolicy() const {} /// Check if pressure tracking is needed before building the DAG and /// initializing this strategy. Called after initPolicy. @@ -555,7 +555,7 @@ public: return Queue.begin() + idx; } - void dump(); + void dump() const; }; /// Summarize the unscheduled region. @@ -756,7 +756,7 @@ public: SUnit *pickOnlyChoice(); #ifndef NDEBUG - void dumpScheduledState(); + void dumpScheduledState() const; #endif }; @@ -890,7 +890,7 @@ public: MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override; - void dumpPolicy() override; + void dumpPolicy() const override; bool shouldTrackPressure() const override { return RegionPolicy.ShouldTrackPressure; diff --git a/include/llvm/CodeGen/MacroFusion.h b/include/llvm/CodeGen/MacroFusion.h new file mode 100644 index 0000000000000..473784bc58412 --- /dev/null +++ b/include/llvm/CodeGen/MacroFusion.h @@ -0,0 +1,41 @@ +//===- MacroFusion.h - Macro Fusion ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file This file contains the definition of the DAG scheduling mutation to +/// pair instructions back to back. +// +//===----------------------------------------------------------------------===// + +#include <functional> +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/CodeGen/MachineScheduler.h" + +namespace llvm { + +/// \brief Check if the instr pair, FirstMI and SecondMI, should be fused +/// together. Given SecondMI, when FirstMI is unspecified, then check if +/// SecondMI may be part of a fused pair at all. +typedef std::function<bool(const TargetInstrInfo &TII, + const TargetSubtargetInfo &TSI, + const MachineInstr *FirstMI, + const MachineInstr &SecondMI)> ShouldSchedulePredTy; + +/// \brief Create a DAG scheduling mutation to pair instructions back to back +/// for instructions that benefit according to the target-specific +/// shouldScheduleAdjacent predicate function. +std::unique_ptr<ScheduleDAGMutation> +createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); + +/// \brief Create a DAG scheduling mutation to pair branch instructions with one +/// of their predecessors back to back for instructions that benefit according +/// to the target-specific shouldScheduleAdjacent predicate function. +std::unique_ptr<ScheduleDAGMutation> +createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); + +} // end namespace llvm diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index ad1efe18c72d3..489c72b81a985 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -156,12 +156,24 @@ public: /// available and do the appropriate bookkeeping. SPAdj is the stack /// adjustment due to call frame, it's passed along to eliminateFrameIndex(). /// Returns the scavenged register. + /// This is deprecated as it depends on the quality of the kill flags being + /// present; Use scavengeRegisterBackwards() instead! unsigned scavengeRegister(const TargetRegisterClass *RegClass, MachineBasicBlock::iterator I, int SPAdj); unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) { return scavengeRegister(RegClass, MBBI, SPAdj); } + /// Make a register of the specific register class available from the current + /// position backwards to the place before \p To. If \p RestoreAfter is true + /// this includes the instruction following the current position. + /// SPAdj is the stack adjustment due to call frame, it's passed along to + /// eliminateFrameIndex(). + /// Returns the scavenged register. + unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC, + MachineBasicBlock::iterator To, + bool RestoreAfter, int SPAdj); + /// Tell the scavenger a register is used. void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll()); @@ -202,6 +214,12 @@ private: /// Mark live-in registers of basic block as used. void setLiveInsUsed(const MachineBasicBlock &MBB); + + /// Spill a register after position \p After and reload it before position + /// \p UseMI. + ScavengedInfo &spill(unsigned Reg, const TargetRegisterClass &RC, int SPAdj, + MachineBasicBlock::iterator After, + MachineBasicBlock::iterator &UseMI); }; /// Replaces all frame index virtual registers with physical registers. Uses the diff --git a/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h new file mode 100644 index 0000000000000..d82ab7d647e75 --- /dev/null +++ b/include/llvm/CodeGen/SelectionDAGAddressAnalysis.h @@ -0,0 +1,64 @@ +//===-- llvm/CodeGen/SelectionDAGAddressAnalysis.h ------- DAG Address Analysis +//---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// + +#ifndef LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H +#define LLVM_CODEGEN_SELECTIONDAGADDRESSANALYSIS_H + +#include "llvm/CodeGen/ISDOpcodes.h" +#include "llvm/CodeGen/SelectionDAG.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" + +namespace llvm { +/// Helper struct to parse and store a memory address as base + index + offset. +/// We ignore sign extensions when it is safe to do so. +/// The following two expressions are not equivalent. To differentiate we need +/// to store whether there was a sign extension involved in the index +/// computation. +/// (load (i64 add (i64 copyfromreg %c) +/// (i64 signextend (add (i8 load %index) +/// (i8 1)))) +/// vs +/// +/// (load (i64 add (i64 copyfromreg %c) +/// (i64 signextend (i32 add (i32 signextend (i8 load %index)) +/// (i32 1))))) +class BaseIndexOffset { +private: + SDValue Base; + SDValue Index; + int64_t Offset; + bool IsIndexSignExt; + +public: + BaseIndexOffset() : Offset(0), IsIndexSignExt(false) {} + + BaseIndexOffset(SDValue Base, SDValue Index, int64_t Offset, + bool IsIndexSignExt) + : Base(Base), Index(Index), Offset(Offset), + IsIndexSignExt(IsIndexSignExt) {} + + SDValue getBase() { return Base; } + SDValue getIndex() { return Index; } + + bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG) { + int64_t Off; + return equalBaseIndex(Other, DAG, Off); + } + + bool equalBaseIndex(BaseIndexOffset &Other, const SelectionDAG &DAG, + int64_t &Off); + + /// Parses tree in Ptr for base, index, offset addresses. + static BaseIndexOffset match(SDValue Ptr); +}; +} // namespace llvm + +#endif diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 0cd26d35a4829..af418d3050e45 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -2107,7 +2107,7 @@ class MaskedGatherScatterSDNode : public MemSDNode { public: friend class SelectionDAG; - MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, + MaskedGatherScatterSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO) : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {} diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 8df15ef970265..1289551f0739a 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -356,6 +356,9 @@ /* Define if this is Win32ish platform */ #cmakedefine LLVM_ON_WIN32 ${LLVM_ON_WIN32} +/* Define if overriding target triple is enabled */ +#cmakedefine LLVM_TARGET_TRIPLE_ENV "${LLVM_TARGET_TRIPLE_ENV}" + /* Define if we have the Intel JIT API runtime support library */ #cmakedefine01 LLVM_USE_INTEL_JITEVENTS diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index 4c6bbedc6bbdd..44040e04388af 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -27,9 +27,12 @@ namespace codeview { template <typename Kind> class CVRecord { public: - CVRecord() = default; + CVRecord() : Type(static_cast<Kind>(0)) {} + CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {} + bool valid() const { return Type != static_cast<Kind>(0); } + uint32_t length() const { return RecordData.size(); } Kind kind() const { return Type; } ArrayRef<uint8_t> data() const { return RecordData; } diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index 6820e26b754c0..b7a7e33abadf8 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -402,6 +402,16 @@ enum class LocalSymFlags : uint16_t { }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(LocalSymFlags) +/// Corresponds to the CV_PUBSYMFLAGS bitfield. +enum class PublicSymFlags : uint32_t { + None = 0, + Code = 1 << 0, + Function = 1 << 1, + Managed = 1 << 2, + MSIL = 1 << 3, +}; +CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(PublicSymFlags) + /// Corresponds to the CV_PROCFLAGS bitfield. enum class ProcSymFlags : uint8_t { None = 0, diff --git a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h index 6947317420643..ee17b47d8e631 100644 --- a/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h +++ b/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h @@ -51,11 +51,23 @@ class DebugSubsectionRecordBuilder { public: DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection, CodeViewContainer Container); + + /// Use this to copy existing subsections directly from source to destination. + /// For example, line table subsections in an object file only need to be + /// relocated before being copied into the PDB. + DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents, + CodeViewContainer Container); + uint32_t calculateSerializedLength(); Error commit(BinaryStreamWriter &Writer) const; private: + /// The subsection to build. Will be null if Contents is non-empty. std::shared_ptr<DebugSubsection> Subsection; + + /// The bytes of the subsection. Only non-empty if Subsection is null. + DebugSubsectionRecord Contents; + CodeViewContainer Container; }; diff --git a/include/llvm/DebugInfo/CodeView/EnumTables.h b/include/llvm/DebugInfo/CodeView/EnumTables.h index 013e440613fc1..5d54bb4cca841 100644 --- a/include/llvm/DebugInfo/CodeView/EnumTables.h +++ b/include/llvm/DebugInfo/CodeView/EnumTables.h @@ -22,6 +22,7 @@ namespace codeview { ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames(); ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames(); ArrayRef<EnumEntry<uint16_t>> getRegisterNames(); +ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames(); ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames(); ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames(); ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames(); diff --git a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h index 0d056e42b45f5..8b1540abf903e 100644 --- a/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h +++ b/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h @@ -11,18 +11,15 @@ #define LLVM_DEBUGINFO_CODEVIEW_LAZYRANDOMTYPECOLLECTION_H #include "llvm/DebugInfo/CodeView/TypeCollection.h" -#include "llvm/DebugInfo/CodeView/TypeDatabase.h" -#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h" #include "llvm/DebugInfo/CodeView/TypeIndex.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" +#include "llvm/Support/StringSaver.h" namespace llvm { namespace codeview { -class TypeDatabase; -class TypeVisitorCallbacks; - /// \brief Provides amortized O(1) random access to a CodeView type stream. /// Normally to access a type from a type stream, you must know its byte /// offset into the type stream, because type records are variable-lengthed. @@ -47,6 +44,11 @@ class TypeVisitorCallbacks; /// of O(N/M) and an amortized time of O(1). class LazyRandomTypeCollection : public TypeCollection { typedef FixedStreamArray<TypeIndexOffset> PartialOffsetArray; + struct CacheEntry { + CVType Type; + uint32_t Offset; + StringRef Name; + }; public: explicit LazyRandomTypeCollection(uint32_t RecordCountHint); @@ -56,8 +58,10 @@ public: PartialOffsetArray PartialOffsets); LazyRandomTypeCollection(const CVTypeArray &Types, uint32_t RecordCountHint); - void reset(ArrayRef<uint8_t> Data); - void reset(StringRef Data); + void reset(ArrayRef<uint8_t> Data, uint32_t RecordCountHint); + void reset(StringRef Data, uint32_t RecordCountHint); + + uint32_t getOffsetOfType(TypeIndex Index); CVType getType(TypeIndex Index) override; StringRef getTypeName(TypeIndex Index) override; @@ -68,27 +72,26 @@ public: Optional<TypeIndex> getNext(TypeIndex Prev) override; private: - const TypeDatabase &database() const { return Database; } Error ensureTypeExists(TypeIndex Index); + void ensureCapacityFor(TypeIndex Index); Error visitRangeForType(TypeIndex TI); Error fullScanForType(TypeIndex TI); - Error visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End); - Error visitOneRecord(TypeIndex TI, uint32_t Offset, CVType &Record); + void visitRange(TypeIndex Begin, uint32_t BeginOffset, TypeIndex End); + + /// Number of actual records. + uint32_t Count = 0; - /// Visited records get automatically added to the type database. - TypeDatabase Database; + /// The largest type index which we've visited. + TypeIndex LargestTypeIndex = TypeIndex::None(); + + BumpPtrAllocator Allocator; + StringSaver NameStorage; /// The type array to allow random access visitation of. CVTypeArray Types; - /// The database visitor which adds new records to the database. - TypeDatabaseVisitor DatabaseVisitor; - - /// A vector mapping type indices to type offset. For every record that has - /// been visited, contains the absolute offset of that record in the record - /// array. - std::vector<uint32_t> KnownOffsets; + std::vector<CacheEntry> Records; /// An array of index offsets for the given type stream, allowing log(N) /// lookups of a type record by index. Similar to KnownOffsets but only diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h index 5f85ed28cb3a1..1cf77fcdecbe0 100644 --- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h +++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h @@ -363,7 +363,7 @@ public: : SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset) {} - TypeIndex Index; + PublicSymFlags Flags; uint32_t Offset; uint16_t Segment; StringRef Name; diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h deleted file mode 100644 index a743e7f70855f..0000000000000 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ /dev/null @@ -1,84 +0,0 @@ -//===- TypeDatabase.h - A collection of CodeView type records ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASE_H - -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/CodeView/TypeCollection.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/StringSaver.h" - -namespace llvm { -namespace codeview { -class TypeDatabase : public TypeCollection { - friend class RandomAccessTypeVisitor; - -public: - explicit TypeDatabase(uint32_t Capacity); - - /// Records the name of a type, and reserves its type index. - TypeIndex appendType(StringRef Name, const CVType &Data); - - /// Records the name of a type, and reserves its type index. - void recordType(StringRef Name, TypeIndex Index, const CVType &Data); - - /// Saves the name in a StringSet and creates a stable StringRef. - StringRef saveTypeName(StringRef TypeName); - - StringRef getTypeName(TypeIndex Index) const; - - const CVType &getTypeRecord(TypeIndex Index) const; - CVType &getTypeRecord(TypeIndex Index); - - bool contains(TypeIndex Index) const; - uint32_t size() const; - uint32_t capacity() const; - bool empty() const; - - CVType getType(TypeIndex Index) override; - StringRef getTypeName(TypeIndex Index) override; - bool contains(TypeIndex Index) override; - uint32_t size() override; - uint32_t capacity() override; - - Optional<TypeIndex> getFirst() override; - Optional<TypeIndex> getNext(TypeIndex Prev) override; - - Optional<TypeIndex> largestTypeIndexLessThan(TypeIndex TI) const; - -private: - TypeIndex getAppendIndex() const; - - void grow(); - void grow(TypeIndex Index); - - BumpPtrAllocator Allocator; - - uint32_t Count = 0; - TypeIndex LargestTypeIndex; - - /// All user defined type records in .debug$T live in here. Type indices - /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to - /// index into this vector. - SmallVector<StringRef, 10> CVUDTNames; - SmallVector<CVType, 10> TypeRecords; - - StringSaver TypeNameStorage; - - BitVector ValidRecords; -}; -} -} - -#endif
\ No newline at end of file diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h b/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h deleted file mode 100644 index 77dbc91a7d38c..0000000000000 --- a/include/llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h +++ /dev/null @@ -1,62 +0,0 @@ -//===-- TypeDatabaseVisitor.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H -#define LLVM_DEBUGINFO_CODEVIEW_TYPEDATABASEVISITOR_H - -#include "llvm/ADT/PointerUnion.h" - -#include "llvm/DebugInfo/CodeView/TypeDatabase.h" -#include "llvm/DebugInfo/CodeView/TypeIndex.h" -#include "llvm/DebugInfo/CodeView/TypeRecord.h" -#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" - -namespace llvm { -namespace codeview { - -/// Dumper for CodeView type streams found in COFF object files and PDB files. -class TypeDatabaseVisitor : public TypeVisitorCallbacks { -public: - explicit TypeDatabaseVisitor(TypeDatabase &TypeDB) : TypeDB(&TypeDB) {} - - /// Paired begin/end actions for all types. Receives all record data, - /// including the fixed-length record prefix. - Error visitTypeBegin(CVType &Record) override; - Error visitTypeBegin(CVType &Record, TypeIndex Index) override; - Error visitTypeEnd(CVType &Record) override; - Error visitMemberBegin(CVMemberRecord &Record) override; - Error visitMemberEnd(CVMemberRecord &Record) override; - -#define TYPE_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownRecord(CVType &CVR, Name##Record &Record) override; -#define MEMBER_RECORD(EnumName, EnumVal, Name) \ - Error visitKnownMember(CVMemberRecord &CVR, Name##Record &Record) override; -#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) -#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" - -private: - StringRef getTypeName(TypeIndex Index) const; - StringRef saveTypeName(StringRef Name); - - bool IsInFieldList = false; - - /// Name of the current type. Only valid before visitTypeEnd. - StringRef Name; - /// Current type index. Only valid before visitTypeEnd, and if we are - /// visiting a random access type database. - Optional<TypeIndex> CurrentTypeIndex; - - TypeDatabase *TypeDB; -}; - -} // end namespace codeview -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_TYPEDUMPER_H diff --git a/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h index 82ceb50383166..c393b42cd27c5 100644 --- a/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h +++ b/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEXDISCOVERY_H #include "llvm/ADT/SmallVector.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/TypeRecord.h" #include "llvm/Support/Error.h" @@ -27,6 +28,11 @@ void discoverTypeIndices(ArrayRef<uint8_t> RecordData, SmallVectorImpl<TiReference> &Refs); void discoverTypeIndices(const CVType &Type, SmallVectorImpl<TiReference> &Refs); + +/// Discover type indices in symbol records. Returns false if this is an unknown +/// record. +bool discoverTypeIndices(const CVSymbol &Symbol, + SmallVectorImpl<TiReference> &Refs); } } diff --git a/include/llvm/DebugInfo/CodeView/TypeName.h b/include/llvm/DebugInfo/CodeView/TypeName.h new file mode 100644 index 0000000000000..a987b4afd283a --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/TypeName.h @@ -0,0 +1,22 @@ +//===- TypeName.h --------------------------------------------- *- C++ --*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPENAME_H + +#include "llvm/DebugInfo/CodeView/TypeCollection.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" + +namespace llvm { +namespace codeview { +std::string computeTypeName(TypeCollection &Types, TypeIndex Index); +} +} // namespace llvm + +#endif diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h index 6156223b25601..cbe8d6066bb9f 100644 --- a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h +++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h @@ -25,6 +25,7 @@ public: explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {} explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {} + using TypeVisitorCallbacks::visitTypeBegin; Error visitTypeBegin(CVType &Record) override; Error visitTypeEnd(CVType &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/TypeSerializer.h b/include/llvm/DebugInfo/CodeView/TypeSerializer.h index f785d45095475..988a2d4aa8346 100644 --- a/include/llvm/DebugInfo/CodeView/TypeSerializer.h +++ b/include/llvm/DebugInfo/CodeView/TypeSerializer.h @@ -93,6 +93,7 @@ public: TypeIndex insertRecord(const RemappedType &Record); Expected<TypeIndex> visitTypeEndGetIndex(CVType &Record); + using TypeVisitorCallbacks::visitTypeBegin; Error visitTypeBegin(CVType &Record) override; Error visitTypeEnd(CVType &Record) override; Error visitMemberBegin(CVMemberRecord &Record) override; diff --git a/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/include/llvm/DebugInfo/CodeView/TypeTableCollection.h index 42b62ba2b6ce5..80326a0ffd39d 100644 --- a/include/llvm/DebugInfo/CodeView/TypeTableCollection.h +++ b/include/llvm/DebugInfo/CodeView/TypeTableCollection.h @@ -11,7 +11,9 @@ #define LLVM_DEBUGINFO_CODEVIEW_TYPETABLECOLLECTION_H #include "llvm/DebugInfo/CodeView/TypeCollection.h" -#include "llvm/DebugInfo/CodeView/TypeDatabase.h" +#include "llvm/Support/StringSaver.h" + +#include <vector> namespace llvm { namespace codeview { @@ -30,11 +32,10 @@ public: uint32_t capacity() override; private: - bool hasCapacityFor(TypeIndex Index) const; - void ensureTypeExists(TypeIndex Index); - + BumpPtrAllocator Allocator; + StringSaver NameStorage; + std::vector<StringRef> Names; ArrayRef<ArrayRef<uint8_t>> Records; - TypeDatabase Database; }; } } diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index 2e82a774cc23b..4126e245ff139 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -57,7 +57,7 @@ struct DILineInfo { } }; -typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable; +using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>; /// DIInliningInfo - a format-neutral container for inlined code description. class DIInliningInfo { @@ -102,7 +102,7 @@ enum class DINameKind { None, ShortName, LinkageName }; /// should be filled with data. struct DILineInfoSpecifier { enum class FileLineInfoKind { None, Default, AbsoluteFilePath }; - typedef DINameKind FunctionNameKind; + using FunctionNameKind = DINameKind; FileLineInfoKind FLIKind; FunctionNameKind FNKind; @@ -174,6 +174,7 @@ public: // No verifier? Just say things went well. return true; } + virtual DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h index e363cff158033..190a69b757390 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -33,6 +33,7 @@ public: dwarf::Attribute Attr; dwarf::Form Form; + /// The following field is used for ByteSize for non-implicit_const /// attributes and as value for implicit_const ones, indicated by /// Form == DW_FORM_implicit_const. @@ -58,7 +59,7 @@ public: /// the ByteSize member. Optional<int64_t> getByteSize(const DWARFUnit &U) const; }; - typedef SmallVector<AttributeSpec, 8> AttributeSpecVector; + using AttributeSpecVector = SmallVector<AttributeSpec, 8>; DWARFAbbreviationDeclaration(); @@ -67,8 +68,8 @@ public: dwarf::Tag getTag() const { return Tag; } bool hasChildren() const { return HasChildren; } - typedef iterator_range<AttributeSpecVector::const_iterator> - attr_iterator_range; + using attr_iterator_range = + iterator_range<AttributeSpecVector::const_iterator>; attr_iterator_range attributes() const { return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end()); diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 3012b39dcc528..8bde63efe1882 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -32,8 +32,9 @@ class DWARFAcceleratorTable { }; struct HeaderData { - typedef uint16_t AtomType; - typedef dwarf::Form Form; + using AtomType = uint16_t; + using Form = dwarf::Form; + uint32_t DIEOffsetBase; SmallVector<std::pair<AtomType, Form>, 3> Atoms; }; diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index c72604a12bfda..4bf34d52bcba9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -10,7 +10,6 @@ #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -25,21 +24,24 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" +#include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" +#include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Error.h" #include "llvm/Support/Host.h" #include <cstdint> #include <deque> #include <map> #include <memory> -#include <utility> namespace llvm { +class DataExtractor; class MemoryBuffer; class raw_ostream; @@ -73,7 +75,7 @@ class DWARFContext : public DIContext { std::unique_ptr<DWARFDebugLocDWO> LocDWO; /// The maximum DWARF version of all units. - unsigned MaxVersion; + unsigned MaxVersion = 0; struct DWOFile { object::OwningBinary<object::ObjectFile> File; @@ -100,7 +102,7 @@ class DWARFContext : public DIContext { void parseDWOTypeUnits(); public: - DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {} + DWARFContext() : DIContext(CK_DWARF) {} DWARFContext(DWARFContext &) = delete; DWARFContext &operator=(DWARFContext &) = delete; @@ -112,9 +114,9 @@ public: bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; - typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range; - typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range; - typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range; + using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; + using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range; + using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>; /// Get compile units in this context. cu_iterator_range compile_units() { @@ -230,8 +232,10 @@ public: virtual bool isLittleEndian() const = 0; virtual uint8_t getAddressSize() const = 0; virtual const DWARFSection &getInfoSection() = 0; - typedef MapVector<object::SectionRef, DWARFSection, - std::map<object::SectionRef, unsigned>> TypeSectionMap; + + using TypeSectionMap = MapVector<object::SectionRef, DWARFSection, + std::map<object::SectionRef, unsigned>>; + virtual const TypeSectionMap &getTypesSections() = 0; virtual StringRef getAbbrevSection() = 0; virtual const DWARFSection &getLocSection() = 0; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index 9f86fe5083896..65571598d7432 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -18,6 +18,8 @@ namespace llvm { +class raw_ostream; + class DWARFAbbreviationDeclarationSet { uint32_t Offset; /// Code of the first abbreviation, if all abbreviations in the set have @@ -25,8 +27,8 @@ class DWARFAbbreviationDeclarationSet { uint32_t FirstAbbrCode; std::vector<DWARFAbbreviationDeclaration> Decls; - typedef std::vector<DWARFAbbreviationDeclaration>::const_iterator - const_iterator; + using const_iterator = + std::vector<DWARFAbbreviationDeclaration>::const_iterator; public: DWARFAbbreviationDeclarationSet(); @@ -51,8 +53,8 @@ private: }; class DWARFDebugAbbrev { - typedef std::map<uint64_t, DWARFAbbreviationDeclarationSet> - DWARFAbbreviationDeclarationSetMap; + using DWARFAbbreviationDeclarationSetMap = + std::map<uint64_t, DWARFAbbreviationDeclarationSet>; DWARFAbbreviationDeclarationSetMap AbbrDeclSets; mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h index 2d82104ea0984..dfbbb95076e81 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h @@ -46,8 +46,8 @@ public: }; private: - typedef std::vector<Descriptor> DescriptorColl; - typedef iterator_range<DescriptorColl::const_iterator> desc_iterator_range; + using DescriptorColl = std::vector<Descriptor>; + using desc_iterator_range = iterator_range<DescriptorColl::const_iterator>; uint32_t Offset; Header HeaderData; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h index 2237aa361d187..ea71a50f3270d 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h @@ -76,8 +76,8 @@ private: } }; - typedef std::vector<Range> RangeColl; - typedef RangeColl::const_iterator RangeCollIterator; + using RangeColl = std::vector<Range>; + using RangeCollIterator = RangeColl::const_iterator; std::vector<RangeEndpoint> Endpoints; RangeColl Aranges; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 39a7ef71de97d..4d624812f1861 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -10,7 +10,9 @@ #ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H #define LLVM_DEBUGINFO_DWARFDEBUGLINE_H +#include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" #include <cstdint> @@ -42,10 +44,10 @@ public: /// The size in bytes of the statement information for this compilation unit /// (not including the total_length field itself). uint64_t TotalLength; - /// Version identifier for the statement information format. - uint16_t Version; - /// In v5, size in bytes of an address (or segment offset). - uint8_t AddressSize; + /// Version, address size (starting in v5), and DWARF32/64 format; these + /// parameters affect interpretation of forms (used in the directory and + /// file tables starting with v5). + DWARFFormParams FormParams; /// In v5, size in bytes of a segment selector. uint8_t SegSelectorSize; /// The number of bytes following the prologue_length field to the beginning @@ -70,15 +72,18 @@ public: std::vector<StringRef> IncludeDirectories; std::vector<FileNameEntry> FileNames; - bool IsDWARF64; + const DWARFFormParams getFormParams() const { return FormParams; } + uint16_t getVersion() const { return FormParams.Version; } + uint8_t getAddressSize() const { return FormParams.AddrSize; } + bool isDWARF64() const { return FormParams.Format == dwarf::DWARF64; } - uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; } + uint32_t sizeofTotalLength() const { return isDWARF64() ? 12 : 4; } - uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; } + uint32_t sizeofPrologueLength() const { return isDWARF64() ? 8 : 4; } /// Length of the prologue in bytes. uint32_t getLength() const { - return PrologueLength + sizeofTotalLength() + sizeof(Version) + + return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) + sizeofPrologueLength(); } @@ -104,7 +109,9 @@ public: void postAppend(); void reset(bool DefaultIsStmt); void dump(raw_ostream &OS) const; + static void dumpTableHeader(raw_ostream &OS); + static bool orderByAddress(const Row &LHS, const Row &RHS) { return LHS.Address < RHS.Address; } @@ -216,11 +223,12 @@ public: bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap, uint32_t *OffsetPtr); + using RowVector = std::vector<Row>; + using RowIter = RowVector::const_iterator; + using SequenceVector = std::vector<Sequence>; + using SequenceIter = SequenceVector::const_iterator; + struct Prologue Prologue; - typedef std::vector<Row> RowVector; - typedef RowVector::const_iterator RowIter; - typedef std::vector<Sequence> SequenceVector; - typedef SequenceVector::const_iterator SequenceIter; RowVector Rows; SequenceVector Sequences; @@ -244,14 +252,14 @@ private: struct LineTable *LineTable; /// The row number that starts at zero for the prologue, and increases for /// each row added to the matrix. - unsigned RowNumber; + unsigned RowNumber = 0; struct Row Row; struct Sequence Sequence; }; - typedef std::map<uint32_t, LineTable> LineTableMapTy; - typedef LineTableMapTy::iterator LineTableIter; - typedef LineTableMapTy::const_iterator LineTableConstIter; + using LineTableMapTy = std::map<uint32_t, LineTable>; + using LineTableIter = LineTableMapTy::iterator; + using LineTableConstIter = LineTableMapTy::const_iterator; const RelocAddrMap *RelocMap; LineTableMapTy LineTableMap; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h index 6d4cd8d1b5a3c..821da8f9b5361 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -39,7 +39,7 @@ class DWARFDebugLoc { SmallVector<Entry, 2> Entries; }; - typedef SmallVector<LocationList, 4> LocationLists; + using LocationLists = SmallVector<LocationList, 4>; /// A list of all the variables in the debug_loc section, each one describing /// the locations in which the variable is stored. @@ -71,7 +71,7 @@ class DWARFDebugLocDWO { SmallVector<Entry, 2> Entries; }; - typedef SmallVector<LocationList, 4> LocationLists; + using LocationLists = SmallVector<LocationList, 4>; LocationLists Locations; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h index 85d98b45afcd5..135c50761e36a 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -40,7 +40,7 @@ class DWARFDebugMacro { }; }; - typedef SmallVector<Entry, 4> MacroList; + using MacroList = SmallVector<Entry, 4>; /// A list of all the macro entries in the debug_macinfo section. MacroList Macros; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index 437060bc8fec1..49beec92ecc67 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -12,10 +12,8 @@ #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/DataExtractor.h" - #include <cassert> #include <cstdint> -#include <utility> #include <vector> namespace llvm { @@ -29,7 +27,7 @@ struct DWARFAddressRange { }; /// DWARFAddressRangesVector - represents a set of absolute address ranges. -typedef std::vector<DWARFAddressRange> DWARFAddressRangesVector; +using DWARFAddressRangesVector = std::vector<DWARFAddressRange>; class DWARFDebugRangeList { public: diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index d6a3b52f2fe1a..78fa6639db087 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -22,6 +22,35 @@ namespace llvm { class DWARFUnit; class raw_ostream; +/// A helper struct for DWARFFormValue methods, providing information that +/// allows it to know the byte size of DW_FORM values that vary in size +/// depending on the DWARF version, address byte size, or DWARF32/DWARF64. +struct DWARFFormParams { + uint16_t Version; + uint8_t AddrSize; + dwarf::DwarfFormat Format; + + /// The definition of the size of form DW_FORM_ref_addr depends on the + /// version. In DWARF v2 it's the size of an address; after that, it's the + /// size of a reference. + uint8_t getRefAddrByteSize() const { + if (Version == 2) + return AddrSize; + return getDwarfOffsetByteSize(); + } + + /// The size of a reference is determined by the DWARF 32/64-bit format. + uint8_t getDwarfOffsetByteSize() const { + switch (Format) { + case dwarf::DwarfFormat::DWARF32: + return 4; + case dwarf::DwarfFormat::DWARF64: + return 8; + } + llvm_unreachable("Invalid Format value"); + } +}; + class DWARFFormValue { public: enum FormClass { @@ -104,79 +133,43 @@ public: /// Get the fixed byte size for a given form. /// - /// If the form always has a fixed valid byte size that doesn't depend on a - /// DWARFUnit, then an Optional with a value will be returned. If the form - /// can vary in size depending on the DWARFUnit (DWARF version, address byte - /// size, or DWARF 32/64) and the DWARFUnit is valid, then an Optional with a - /// valid value is returned. If the form is always encoded using a variable - /// length storage format (ULEB or SLEB numbers or blocks) or the size - /// depends on a DWARFUnit and the DWARFUnit is NULL, then None will be - /// returned. - /// \param Form The DWARF form to get the fixed byte size for - /// \param U The DWARFUnit that can be used to help determine the byte size. - /// - /// \returns Optional<uint8_t> value with the fixed byte size or None if - /// \p Form doesn't have a fixed byte size or a DWARFUnit wasn't supplied - /// and was needed to calculate the byte size. - static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, - const DWARFUnit *U = nullptr); - - /// Get the fixed byte size for a given form. - /// - /// If the form has a fixed byte size given a valid DWARF version and address - /// byte size, then an Optional with a valid value is returned. If the form - /// is always encoded using a variable length storage format (ULEB or SLEB - /// numbers or blocks) then None will be returned. + /// If the form has a fixed byte size, then an Optional with a value will be + /// returned. If the form is always encoded using a variable length storage + /// format (ULEB or SLEB numbers or blocks) then None will be returned. /// - /// \param Form DWARF form to get the fixed byte size for - /// \param Version DWARF version number. - /// \param AddrSize size of an address in bytes. - /// \param Format enum value from llvm::dwarf::DwarfFormat. + /// \param Form DWARF form to get the fixed byte size for. + /// \param FormParams DWARF parameters to help interpret forms. /// \returns Optional<uint8_t> value with the fixed byte size or None if /// \p Form doesn't have a fixed byte size. - static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, uint16_t Version, - uint8_t AddrSize, - llvm::dwarf::DwarfFormat Format); + static Optional<uint8_t> getFixedByteSize(dwarf::Form Form, + const DWARFFormParams FormParams); - /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr. + /// Skip a form's value in \p DebugInfoData at the offset specified by + /// \p OffsetPtr. /// - /// Skips the bytes for this form in the debug info and updates the offset. + /// Skips the bytes for the current form and updates the offset. /// - /// \param DebugInfoData the .debug_info data to use to skip the value. - /// \param OffsetPtr a reference to the offset that will be updated. - /// \param U the DWARFUnit to use when skipping the form in case the form - /// size differs according to data in the DWARFUnit. + /// \param DebugInfoData The data where we want to skip the value. + /// \param OffsetPtr A reference to the offset that will be updated. + /// \param Params DWARF parameters to help interpret forms. /// \returns true on success, false if the form was not skipped. bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, - const DWARFUnit *U) const; - - /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr. - /// - /// Skips the bytes for this form in the debug info and updates the offset. - /// - /// \param Form the DW_FORM enumeration that indicates the form to skip. - /// \param DebugInfoData the .debug_info data to use to skip the value. - /// \param OffsetPtr a reference to the offset that will be updated. - /// \param U the DWARFUnit to use when skipping the form in case the form - /// size differs according to data in the DWARFUnit. - /// \returns true on success, false if the form was not skipped. - static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, const DWARFUnit *U); + const DWARFFormParams Params) const { + return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params); + } - /// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr. + /// Skip a form's value in \p DebugInfoData at the offset specified by + /// \p OffsetPtr. /// - /// Skips the bytes for this form in the debug info and updates the offset. + /// Skips the bytes for the specified form and updates the offset. /// - /// \param Form the DW_FORM enumeration that indicates the form to skip. - /// \param DebugInfoData the .debug_info data to use to skip the value. - /// \param OffsetPtr a reference to the offset that will be updated. - /// \param Version DWARF version number. - /// \param AddrSize size of an address in bytes. - /// \param Format enum value from llvm::dwarf::DwarfFormat. + /// \param Form The DW_FORM enumeration that indicates the form to skip. + /// \param DebugInfoData The data where we want to skip the value. + /// \param OffsetPtr A reference to the offset that will be updated. + /// \param FormParams DWARF parameters to help interpret forms. /// \returns true on success, false if the form was not skipped. static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize, - llvm::dwarf::DwarfFormat Format); + uint32_t *OffsetPtr, const DWARFFormParams FormParams); private: void dumpString(raw_ostream &OS) const; diff --git a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h index f143de334737a..f51838424614a 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ b/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -12,7 +12,6 @@ #include "llvm/ADT/DenseMap.h" #include <cstdint> -#include <utility> namespace llvm { @@ -28,7 +27,7 @@ struct RelocAddrEntry { /// dwarf where we expect relocated values. This adds a bit of complexity to the /// dwarf parsing/extraction at the benefit of not allocating memory for the /// entire size of the debug info sections. -typedef DenseMap<uint64_t, RelocAddrEntry> RelocAddrMap; +using RelocAddrMap = DenseMap<uint64_t, RelocAddrEntry>; } // end namespace llvm diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 945b8999ff22f..d7ccaf82bc9a1 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -19,11 +19,10 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/Support/DataExtractor.h" #include <algorithm> #include <cassert> @@ -31,6 +30,7 @@ #include <cstdint> #include <map> #include <memory> +#include <utility> #include <vector> namespace llvm { @@ -72,9 +72,9 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, bool Parsed = false; public: - typedef SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; - typedef typename UnitVector::iterator iterator; - typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range; + using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>; + using iterator = typename UnitVector::iterator; + using iterator_range = llvm::iterator_range<typename UnitVector::iterator>; UnitType *getUnitForOffset(uint32_t Offset) const override { auto *CU = std::upper_bound( @@ -128,12 +128,13 @@ class DWARFUnit { bool isDWO; const DWARFUnitSectionBase &UnitSection; + // Version, address size, and DWARF format. + DWARFFormParams FormParams; + uint32_t Offset; uint32_t Length; const DWARFAbbreviationDeclarationSet *Abbrevs; - uint16_t Version; uint8_t UnitType; - uint8_t AddrSize; uint64_t BaseAddr; /// The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; @@ -142,8 +143,9 @@ class DWARFUnit { /// IntervalMap does not support range removal, as a result, we use the /// std::map::upper_bound for address range lookup. std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap; - typedef iterator_range<std::vector<DWARFDebugInfoEntry>::iterator> - die_iterator_range; + + using die_iterator_range = + iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>; std::shared_ptr<DWARFUnit> DWO; @@ -159,7 +161,7 @@ protected: virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); /// Size in bytes of the unit header. - virtual uint32_t getHeaderSize() const { return Version <= 4 ? 11 : 12; } + virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; } public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, @@ -197,7 +199,8 @@ public: uint64_t getStringOffsetSectionRelocation(uint32_t Index) const; DataExtractor getDebugInfoExtractor() const { - return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize); + return DataExtractor(InfoSection.Data, isLittleEndian, + getAddressByteSize()); } DataExtractor getStringExtractor() const { @@ -220,10 +223,14 @@ public: uint32_t getOffset() const { return Offset; } uint32_t getNextUnitOffset() const { return Offset + Length + 4; } uint32_t getLength() const { return Length; } - uint16_t getVersion() const { return Version; } - dwarf::DwarfFormat getFormat() const { - return dwarf::DwarfFormat::DWARF32; // FIXME: Support DWARF64. + const DWARFFormParams &getFormParams() const { return FormParams; } + uint16_t getVersion() const { return FormParams.Version; } + dwarf::DwarfFormat getFormat() const { return FormParams.Format; } + uint8_t getAddressByteSize() const { return FormParams.AddrSize; } + uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); } + uint8_t getDwarfOffsetByteSize() const { + return FormParams.getDwarfOffsetByteSize(); } const DWARFAbbreviationDeclarationSet *getAbbreviations() const { @@ -231,19 +238,6 @@ public: } uint8_t getUnitType() const { return UnitType; } - uint8_t getAddressByteSize() const { return AddrSize; } - - uint8_t getRefAddrByteSize() const { - if (Version == 2) - return AddrSize; - return getDwarfOffsetByteSize(); - } - - uint8_t getDwarfOffsetByteSize() const { - if (getFormat() == dwarf::DwarfFormat::DWARF64) - return 8; - return 4; - } uint64_t getBaseAddress() const { return BaseAddr; } diff --git a/include/llvm/DebugInfo/MSF/MSFBuilder.h b/include/llvm/DebugInfo/MSF/MSFBuilder.h index 6d067cc1c2381..b2c8f2d1c20da 100644 --- a/include/llvm/DebugInfo/MSF/MSFBuilder.h +++ b/include/llvm/DebugInfo/MSF/MSFBuilder.h @@ -12,18 +12,16 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" - #include "llvm/DebugInfo/MSF/MSFCommon.h" - #include "llvm/Support/Allocator.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" - +#include <cstdint> #include <utility> #include <vector> namespace llvm { namespace msf { + class MSFBuilder { public: /// \brief Create a new `MSFBuilder`. @@ -122,7 +120,7 @@ private: Error allocateBlocks(uint32_t NumBlocks, MutableArrayRef<uint32_t> Blocks); uint32_t computeDirectoryByteSize() const; - typedef std::vector<uint32_t> BlockList; + using BlockList = std::vector<uint32_t>; BumpPtrAllocator &Allocator; @@ -136,7 +134,8 @@ private: std::vector<uint32_t> DirectoryBlocks; std::vector<std::pair<uint32_t, BlockList>> StreamData; }; -} // namespace msf -} // namespace llvm + +} // end namespace msf +} // end namespace llvm #endif // LLVM_DEBUGINFO_MSF_MSFBUILDER_H diff --git a/include/llvm/DebugInfo/MSF/MSFCommon.h b/include/llvm/DebugInfo/MSF/MSFCommon.h index 93a9c808b7368..eca1b8b89ebd8 100644 --- a/include/llvm/DebugInfo/MSF/MSFCommon.h +++ b/include/llvm/DebugInfo/MSF/MSFCommon.h @@ -12,15 +12,15 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" - #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/MathExtras.h" - +#include <cstdint> #include <vector> namespace llvm { namespace msf { + static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ', 'C', '/', 'C', '+', '+', ' ', 'M', 'S', 'F', ' ', '7', '.', '0', '0', @@ -50,8 +50,9 @@ struct SuperBlock { }; struct MSFLayout { - MSFLayout() : SB(nullptr) {} - const SuperBlock *SB; + MSFLayout() = default; + + const SuperBlock *SB = nullptr; BitVector FreePageMap; ArrayRef<support::ulittle32_t> DirectoryBlocks; ArrayRef<support::ulittle32_t> StreamSizes; @@ -90,15 +91,16 @@ inline uint32_t getFpmIntervalLength(const MSFLayout &L) { inline uint32_t getNumFpmIntervals(const MSFLayout &L) { uint32_t Length = getFpmIntervalLength(L); - return llvm::alignTo(L.SB->NumBlocks, Length) / Length; + return alignTo(L.SB->NumBlocks, Length) / Length; } inline uint32_t getFullFpmByteSize(const MSFLayout &L) { - return llvm::alignTo(L.SB->NumBlocks, 8) / 8; + return alignTo(L.SB->NumBlocks, 8) / 8; } Error validateSuperBlock(const SuperBlock &SB); -} // namespace msf -} // namespace llvm + +} // end namespace msf +} // end namespace llvm #endif // LLVM_DEBUGINFO_MSF_MSFCOMMON_H diff --git a/include/llvm/DebugInfo/MSF/MappedBlockStream.h b/include/llvm/DebugInfo/MSF/MappedBlockStream.h index 02f3cb09b0045..6d88d2be85c9b 100644 --- a/include/llvm/DebugInfo/MSF/MappedBlockStream.h +++ b/include/llvm/DebugInfo/MSF/MappedBlockStream.h @@ -1,5 +1,4 @@ -//===- MappedBlockStream.h - Discontiguous stream data in an MSF -*- C++ -//-*-===// +//==- MappedBlockStream.h - Discontiguous stream data in an MSF --*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -13,7 +12,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/MSF/MSFStreamLayout.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryStream.h" @@ -21,6 +19,7 @@ #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include <cstdint> +#include <memory> #include <vector> namespace llvm { @@ -40,6 +39,7 @@ struct MSFLayout; /// of bytes. class MappedBlockStream : public BinaryStream { friend class WritableMappedBlockStream; + public: static std::unique_ptr<MappedBlockStream> createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, @@ -57,8 +57,8 @@ public: createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator); - llvm::support::endianness getEndian() const override { - return llvm::support::little; + support::endianness getEndian() const override { + return support::little; } Error readBytes(uint32_t Offset, uint32_t Size, @@ -68,7 +68,7 @@ public: uint32_t getLength() override; - llvm::BumpPtrAllocator &getAllocator() { return Allocator; } + BumpPtrAllocator &getAllocator() { return Allocator; } void invalidateCache(); @@ -92,7 +92,7 @@ private: const MSFStreamLayout StreamLayout; BinaryStreamRef MsfData; - typedef MutableArrayRef<uint8_t> CacheEntry; + using CacheEntry = MutableArrayRef<uint8_t>; // We just store the allocator by reference. We use this to allocate // contiguous memory for things like arrays or strings that cross a block @@ -124,8 +124,8 @@ public: createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator); - llvm::support::endianness getEndian() const override { - return llvm::support::little; + support::endianness getEndian() const override { + return support::little; } Error readBytes(uint32_t Offset, uint32_t Size, @@ -141,6 +141,7 @@ public: const MSFStreamLayout &getStreamLayout() const { return ReadInterface.getStreamLayout(); } + uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); } uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); } uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); } @@ -153,7 +154,6 @@ protected: private: MappedBlockStream ReadInterface; - WritableBinaryStreamRef WriteInterface; }; diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h index 3f5818631e7bc..350442556bef8 100644 --- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h +++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h @@ -31,7 +31,7 @@ public: uint64_t getLoadAddress() const override; void setLoadAddress(uint64_t Address) override; - std::unique_ptr<PDBSymbolExe> getGlobalScope() const override; + std::unique_ptr<PDBSymbolExe> getGlobalScope() override; std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; std::unique_ptr<PDBSymbol> diff --git a/include/llvm/DebugInfo/PDB/IPDBSession.h b/include/llvm/DebugInfo/PDB/IPDBSession.h index 85d9fe1248599..cf195095c8d22 100644 --- a/include/llvm/DebugInfo/PDB/IPDBSession.h +++ b/include/llvm/DebugInfo/PDB/IPDBSession.h @@ -29,7 +29,7 @@ public: virtual uint64_t getLoadAddress() const = 0; virtual void setLoadAddress(uint64_t Address) = 0; - virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() const = 0; + virtual std::unique_ptr<PDBSymbolExe> getGlobalScope() = 0; virtual std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const = 0; template <typename T> diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index a89e26ae943c9..e4cb1b24e30d0 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/Support/Error.h" @@ -52,6 +53,9 @@ public: void addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection); + void + addDebugSubsection(const codeview::DebugSubsectionRecord &SubsectionContents); + uint16_t getStreamIndex() const; StringRef getModuleName() const { return ModuleName; } StringRef getObjFileName() const { return ObjFileName; } diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 7123e88cd6423..3bf7907266564 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -63,6 +63,13 @@ public: PDB_Machine getMachineType() const; + BinarySubstreamRef getSectionContributionData() const; + BinarySubstreamRef getSecMapSubstreamData() const; + BinarySubstreamRef getModiSubstreamData() const; + BinarySubstreamRef getFileInfoSubstreamData() const; + BinarySubstreamRef getTypeServerMapSubstreamData() const; + BinarySubstreamRef getECSubstreamData() const; + /// If the given stream type is present, returns its stream index. If it is /// not present, returns InvalidStreamIndex. uint32_t getDebugStreamIndex(DbgHeaderType Type) const; @@ -87,10 +94,12 @@ private: PDBStringTable ECNames; - BinaryStreamRef SecContrSubstream; - BinaryStreamRef SecMapSubstream; - BinaryStreamRef TypeServerMapSubstream; - BinaryStreamRef ECSubstream; + BinarySubstreamRef SecContrSubstream; + BinarySubstreamRef SecMapSubstream; + BinarySubstreamRef ModiSubstream; + BinarySubstreamRef FileInfoSubstream; + BinarySubstreamRef TypeServerMapSubstream; + BinarySubstreamRef ECSubstream; DbiModuleList Modules; diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index aeb2e2ab026a5..744411854181f 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -58,6 +58,7 @@ public: Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName); Error addModuleSourceFile(StringRef Module, StringRef File); + Error addModuleSourceFile(DbiModuleDescriptorBuilder &Module, StringRef File); Expected<uint32_t> getSourceFileNameIndex(StringRef FileName); Error finalizeMsfLayout(); diff --git a/include/llvm/DebugInfo/PDB/Native/InfoStream.h b/include/llvm/DebugInfo/PDB/Native/InfoStream.h index fc91fc7097bd4..37bf5f3b573c3 100644 --- a/include/llvm/DebugInfo/PDB/Native/InfoStream.h +++ b/include/llvm/DebugInfo/PDB/Native/InfoStream.h @@ -47,6 +47,8 @@ public: const NamedStreamMap &getNamedStreams() const; + BinarySubstreamRef getNamedStreamsBuffer() const; + uint32_t getNamedStreamIndex(llvm::StringRef Name) const; iterator_range<StringMapConstIterator<uint32_t>> named_streams() const; @@ -71,6 +73,8 @@ private: // universally unique. PDB_UniqueId Guid; + BinarySubstreamRef SubNamedStreams; + std::vector<PdbRaw_FeatureSig> FeatureSignatures; PdbRaw_Features Features = PdbFeatureNone; diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index c744696ae2508..5565cd5582bc9 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -41,9 +41,12 @@ public: iterator_range<codeview::CVSymbolArray::Iterator> symbols(bool *HadError) const; - const codeview::CVSymbolArray &getSymbolArray() const { - return SymbolsSubstream; - } + const codeview::CVSymbolArray &getSymbolArray() const { return SymbolArray; } + + BinarySubstreamRef getSymbolsSubstream() const; + BinarySubstreamRef getC11LinesSubstream() const; + BinarySubstreamRef getC13LinesSubstream() const; + BinarySubstreamRef getGlobalRefsSubstream() const; ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default; @@ -63,10 +66,12 @@ private: std::shared_ptr<msf::MappedBlockStream> Stream; - codeview::CVSymbolArray SymbolsSubstream; - BinaryStreamRef C11LinesSubstream; - BinaryStreamRef C13LinesSubstream; - BinaryStreamRef GlobalRefsSubstream; + codeview::CVSymbolArray SymbolArray; + + BinarySubstreamRef SymbolsSubstream; + BinarySubstreamRef C11LinesSubstream; + BinarySubstreamRef C13LinesSubstream; + BinarySubstreamRef GlobalRefsSubstream; codeview::DebugSubsectionArray Subsections; }; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h index 22ed61910d94a..1687737f0e7f9 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h @@ -18,7 +18,11 @@ namespace pdb { class NativeCompilandSymbol : public NativeRawSymbol { public: - NativeCompilandSymbol(NativeSession &Session, DbiModuleDescriptor MI); + NativeCompilandSymbol(NativeSession &Session, uint32_t SymbolId, + DbiModuleDescriptor MI); + + std::unique_ptr<NativeRawSymbol> clone() const override; + PDB_SymType getSymTag() const override; bool isEditAndContinueEnabled() const override; uint32_t getLexicalParentId() const override; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h index 9516810539b6b..15bac78df191b 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeExeSymbol.h @@ -18,7 +18,9 @@ namespace pdb { class NativeExeSymbol : public NativeRawSymbol { public: - NativeExeSymbol(NativeSession &Session); + NativeExeSymbol(NativeSession &Session, uint32_t SymbolId); + + std::unique_ptr<NativeRawSymbol> clone() const override; std::unique_ptr<IPDBEnumSymbols> findChildren(PDB_SymType Type) const override; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h index e1e78035ff389..5e4aaafff1a90 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h @@ -19,7 +19,9 @@ class NativeSession; class NativeRawSymbol : public IPDBRawSymbol { public: - explicit NativeRawSymbol(NativeSession &PDBSession); + NativeRawSymbol(NativeSession &PDBSession, uint32_t SymbolId); + + virtual std::unique_ptr<NativeRawSymbol> clone() const = 0; void dump(raw_ostream &OS, int Indent) const override; @@ -201,6 +203,7 @@ public: protected: NativeSession &Session; + uint32_t SymbolId; }; } diff --git a/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/include/llvm/DebugInfo/PDB/Native/NativeSession.h index e6da266f796d5..bbe207738e021 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeSession.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeSession.h @@ -32,7 +32,7 @@ public: uint64_t getLoadAddress() const override; void setLoadAddress(uint64_t Address) override; - std::unique_ptr<PDBSymbolExe> getGlobalScope() const override; + std::unique_ptr<PDBSymbolExe> getGlobalScope() override; std::unique_ptr<PDBSymbol> getSymbolById(uint32_t SymbolId) const override; std::unique_ptr<PDBSymbol> diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/include/llvm/DebugInfo/PDB/Native/PDBFile.h index 4d3c569c3cdfb..4f6ad115e7dfd 100644 --- a/include/llvm/DebugInfo/PDB/Native/PDBFile.h +++ b/include/llvm/DebugInfo/PDB/Native/PDBFile.h @@ -13,6 +13,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/DebugInfo/MSF/IMSFFile.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" +#include "llvm/DebugInfo/MSF/MSFStreamLayout.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/Endian.h" @@ -85,6 +86,8 @@ public: ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const; + msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const; + Error parseFileHeaders(); Error parseStreamData(); diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index 0ee697696ca54..d3475205a6c26 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -16,6 +16,7 @@ #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" #include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Error.h" @@ -57,6 +58,8 @@ public: codeview::LazyRandomTypeCollection &typeCollection() { return *Types; } + BinarySubstreamRef getTypeRecordsSubstream() const; + Error commit(); private: @@ -65,6 +68,8 @@ private: std::unique_ptr<codeview::LazyRandomTypeCollection> Types; + BinarySubstreamRef TypeRecordsSubstream; + codeview::CVTypeArray TypeRecords; std::unique_ptr<BinaryStream> HashStream; diff --git a/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h index e0bec6f6cf859..e576a91e887cc 100644 --- a/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h +++ b/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h @@ -1,4 +1,4 @@ -//===-- SymbolizableModule.h ------------------------------------ C++ -----===// +//===- SymbolizableModule.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,12 +14,7 @@ #define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H #include "llvm/DebugInfo/DIContext.h" - -namespace llvm { -namespace object { -class ObjectFile; -} -} +#include <cstdint> namespace llvm { namespace symbolize { @@ -28,7 +23,8 @@ using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; class SymbolizableModule { public: - virtual ~SymbolizableModule() {} + virtual ~SymbolizableModule() = default; + virtual DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const = 0; @@ -45,7 +41,7 @@ public: virtual uint64_t getModulePreferredBase() const = 0; }; -} // namespace symbolize -} // namespace llvm +} // end namespace symbolize +} // end namespace llvm #endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h index 5103cc03a6bdb..d98d49b24bca2 100644 --- a/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -1,4 +1,4 @@ -//===-- Symbolize.h --------------------------------------------- C++ -----===// +//===- Symbolize.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,21 +10,27 @@ // Header for LLVM symbolization library. // //===----------------------------------------------------------------------===// + #ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H #define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h" +#include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/Error.h" +#include <algorithm> +#include <cstdint> #include <map> #include <memory> #include <string> #include <utility> +#include <vector> namespace llvm { namespace symbolize { using namespace object; + using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; class LLVMSymbolizer { @@ -36,6 +42,7 @@ public: bool RelativeAddresses : 1; std::string DefaultArch; std::vector<std::string> DsymHints; + Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, bool UseSymbolTable = true, bool Demangle = true, bool RelativeAddresses = false, std::string DefaultArch = "") @@ -45,6 +52,7 @@ public: }; LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} + ~LLVMSymbolizer() { flush(); } @@ -56,6 +64,7 @@ public: Expected<DIGlobal> symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); void flush(); + static std::string DemangleName(const std::string &Name, const SymbolizableModule *DbiModuleDescriptor); @@ -63,7 +72,7 @@ public: private: // Bundles together object file with code/data and object file with // corresponding debug info. These objects can be the same. - typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair; + using ObjectPair = std::pair<ObjectFile *, ObjectFile *>; /// Returns a SymbolizableModule or an error if loading debug info failed. /// Only one attempt is made to load a module, and errors during loading are @@ -106,7 +115,7 @@ private: Options Opts; }; -} // namespace symbolize -} // namespace llvm +} // end namespace symbolize +} // end namespace llvm -#endif +#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 1586f7b80669e..2830a26287536 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -15,54 +15,58 @@ #ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H #define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H -#include "RuntimeDyld.h" #include "llvm-c/ExecutionEngine.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" -#include "llvm/IR/ValueHandle.h" -#include "llvm/IR/ValueMap.h" #include "llvm/Object/Binary.h" +#include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Mutex.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include <algorithm> +#include <cstdint> #include <functional> #include <map> +#include <memory> #include <string> #include <vector> namespace llvm { -struct GenericValue; class Constant; -class DataLayout; -class ExecutionEngine; class Function; -class GlobalVariable; +struct GenericValue; class GlobalValue; +class GlobalVariable; class JITEventListener; -class MachineCodeInfo; class MCJITMemoryManager; -class MutexGuard; class ObjectCache; class RTDyldMemoryManager; class Triple; class Type; namespace object { - class Archive; - class ObjectFile; -} + +class Archive; +class ObjectFile; + +} // end namespace object /// \brief Helper class for helping synchronize access to the global address map /// table. Access to this class should be serialized under a mutex. class ExecutionEngineState { public: - typedef StringMap<uint64_t> GlobalAddressMapTy; + using GlobalAddressMapTy = StringMap<uint64_t>; private: - /// GlobalAddressMap - A mapping between LLVM global symbol names values and /// their actualized version... GlobalAddressMapTy GlobalAddressMap; @@ -74,7 +78,6 @@ private: std::map<uint64_t, std::string> GlobalAddressReverseMap; public: - GlobalAddressMapTy &getGlobalAddressMap() { return GlobalAddressMap; } @@ -509,13 +512,15 @@ private: }; namespace EngineKind { + // These are actually bitmasks that get or-ed together. enum Kind { JIT = 0x1, Interpreter = 0x2 }; const static Kind Either = (Kind)(JIT | Interpreter); -} + +} // end namespace EngineKind /// Builder class for ExecutionEngines. Use this by stack-allocating a builder, /// chaining the various set* methods, and terminating it with a .create() @@ -655,6 +660,6 @@ public: // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ExecutionEngine, LLVMExecutionEngineRef) -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h index 537745519ddb6..504e30a018b69 100644 --- a/include/llvm/ExecutionEngine/GenericValue.h +++ b/include/llvm/ExecutionEngine/GenericValue.h @@ -1,4 +1,4 @@ -//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===// +//===- GenericValue.h - Represent any type of LLVM value --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,18 +11,15 @@ // //===----------------------------------------------------------------------===// - #ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H #define LLVM_EXECUTIONENGINE_GENERICVALUE_H #include "llvm/ADT/APInt.h" -#include "llvm/Support/DataTypes.h" #include <vector> namespace llvm { -typedef void* PointerTy; -class APInt; +using PointerTy = void *; struct GenericValue { struct IntPair { @@ -30,25 +27,29 @@ struct GenericValue { unsigned int second; }; union { - double DoubleVal; - float FloatVal; - PointerTy PointerVal; - struct IntPair UIntPairVal; - unsigned char Untyped[8]; + double DoubleVal; + float FloatVal; + PointerTy PointerVal; + struct IntPair UIntPairVal; + unsigned char Untyped[8]; }; - APInt IntVal; // also used for long doubles. + APInt IntVal; // also used for long doubles. // For aggregate data types. std::vector<GenericValue> AggregateVal; // to make code faster, set GenericValue to zero could be omitted, but it is // potentially can cause problems, since GenericValue to store garbage // instead of zero. - GenericValue() : IntVal(1,0) {UIntPairVal.first = 0; UIntPairVal.second = 0;} - explicit GenericValue(void *V) : PointerVal(V), IntVal(1,0) { } + GenericValue() : IntVal(1, 0) { + UIntPairVal.first = 0; + UIntPairVal.second = 0; + } + explicit GenericValue(void *V) : PointerVal(V), IntVal(1, 0) {} }; inline GenericValue PTOGV(void *P) { return GenericValue(P); } -inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; } +inline void *GVTOP(const GenericValue &GV) { return GV.PointerVal; } + +} // end namespace llvm -} // End llvm namespace. -#endif +#endif // LLVM_EXECUTIONENGINE_GENERICVALUE_H diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h index 94ec4e36a199e..ff7840f00a44a 100644 --- a/include/llvm/ExecutionEngine/JITEventListener.h +++ b/include/llvm/ExecutionEngine/JITEventListener.h @@ -15,8 +15,8 @@ #ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H #define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H -#include "RuntimeDyld.h" #include "llvm/Config/llvm-config.h" +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/IR/DebugLoc.h" #include <cstdint> #include <vector> @@ -28,7 +28,9 @@ class MachineFunction; class OProfileWrapper; namespace object { - class ObjectFile; + +class ObjectFile; + } // end namespace object /// JITEvent_EmittedFunctionDetails - Helper struct for containing information @@ -57,7 +59,7 @@ struct JITEvent_EmittedFunctionDetails { /// The default implementation of each method does nothing. class JITEventListener { public: - typedef JITEvent_EmittedFunctionDetails EmittedFunctionDetails; + using EmittedFunctionDetails = JITEvent_EmittedFunctionDetails; public: JITEventListener() = default; diff --git a/include/llvm/ExecutionEngine/JITSymbol.h b/include/llvm/ExecutionEngine/JITSymbol.h index 88929482ce765..f09e95fddb97e 100644 --- a/include/llvm/ExecutionEngine/JITSymbol.h +++ b/include/llvm/ExecutionEngine/JITSymbol.h @@ -1,4 +1,4 @@ -//===----------- JITSymbol.h - JIT symbol abstraction -----------*- C++ -*-===// +//===- JITSymbol.h - JIT symbol abstraction ---------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -26,16 +26,18 @@ namespace llvm { class GlobalValue; namespace object { - class BasicSymbolRef; + +class BasicSymbolRef; + } // end namespace object /// @brief Represents an address in the target process's address space. -typedef uint64_t JITTargetAddress; +using JITTargetAddress = uint64_t; /// @brief Flags for symbols in the JIT. class JITSymbolFlags { public: - typedef uint8_t UnderlyingType; + using UnderlyingType = uint8_t; enum FlagNames : UnderlyingType { None = 0, @@ -46,7 +48,7 @@ public: }; /// @brief Default-construct a JITSymbolFlags instance. - JITSymbolFlags() : Flags(None) {} + JITSymbolFlags() = default; /// @brief Construct a JITSymbolFlags instance from the given flags. JITSymbolFlags(FlagNames Flags) : Flags(Flags) {} @@ -81,15 +83,14 @@ public: static JITSymbolFlags fromObjectSymbol(const object::BasicSymbolRef &Symbol); private: - UnderlyingType Flags; + UnderlyingType Flags = None; }; /// @brief Represents a symbol that has been evaluated to an address already. class JITEvaluatedSymbol { public: /// @brief Create a 'null' symbol. - JITEvaluatedSymbol(std::nullptr_t) - : Address(0) {} + JITEvaluatedSymbol(std::nullptr_t) {} /// @brief Create a symbol for the given address and flags. JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags) @@ -105,19 +106,18 @@ public: JITSymbolFlags getFlags() const { return Flags; } private: - JITTargetAddress Address; + JITTargetAddress Address = 0; JITSymbolFlags Flags; }; /// @brief Represents a symbol in the JIT. class JITSymbol { public: - typedef std::function<JITTargetAddress()> GetAddressFtor; + using GetAddressFtor = std::function<JITTargetAddress()>; /// @brief Create a 'null' symbol that represents failure to find a symbol /// definition. - JITSymbol(std::nullptr_t) - : CachedAddr(0) {} + JITSymbol(std::nullptr_t) {} /// @brief Create a symbol for a definition with a known address. JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags) @@ -137,7 +137,7 @@ public: /// user can materialize the definition at any time by calling the getAddress /// method. JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags) - : GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {} + : GetAddress(std::move(GetAddress)), Flags(Flags) {} /// @brief Returns true if the symbol exists, false otherwise. explicit operator bool() const { return CachedAddr || GetAddress; } @@ -157,7 +157,7 @@ public: private: GetAddressFtor GetAddress; - JITTargetAddress CachedAddr; + JITTargetAddress CachedAddr = 0; JITSymbolFlags Flags; }; diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 2fccf8a0f625e..8ac1b6bca0a7a 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -24,16 +24,20 @@ #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Utils/ValueMapper.h" #include <algorithm> #include <cassert> #include <functional> @@ -46,6 +50,9 @@ #include <vector> namespace llvm { + +class Value; + namespace orc { /// @brief Compile-on-demand layer. @@ -77,15 +84,15 @@ private: return LambdaMaterializer<MaterializerFtor>(std::move(M)); } - typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT; + using BaseLayerModuleHandleT = typename BaseLayerT::ModuleHandleT; // Provide type-erasure for the Modules and MemoryManagers. template <typename ResourceT> class ResourceOwner { public: ResourceOwner() = default; - ResourceOwner(const ResourceOwner&) = delete; - ResourceOwner& operator=(const ResourceOwner&) = delete; + ResourceOwner(const ResourceOwner &) = delete; + ResourceOwner &operator=(const ResourceOwner &) = delete; virtual ~ResourceOwner() = default; virtual ResourceT& getResource() const = 0; @@ -106,7 +113,7 @@ private: template <typename ResourceT, typename ResourcePtrT> std::unique_ptr<ResourceOwner<ResourceT>> wrapOwnership(ResourcePtrT ResourcePtr) { - typedef ResourceOwnerImpl<ResourceT, ResourcePtrT> RO; + using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>; return llvm::make_unique<RO>(std::move(ResourcePtr)); } @@ -130,21 +137,21 @@ private: }; struct LogicalDylib { - typedef std::function<JITSymbol(const std::string&)> SymbolResolverFtor; + using SymbolResolverFtor = std::function<JITSymbol(const std::string&)>; - typedef std::function<typename BaseLayerT::ModuleSetHandleT( - BaseLayerT&, - std::unique_ptr<Module>, - std::unique_ptr<JITSymbolResolver>)> - ModuleAdderFtor; + using ModuleAdderFtor = + std::function<typename BaseLayerT::ModuleHandleT( + BaseLayerT&, + std::unique_ptr<Module>, + std::unique_ptr<JITSymbolResolver>)>; struct SourceModuleEntry { std::unique_ptr<ResourceOwner<Module>> SourceMod; std::set<Function*> StubsToClone; }; - typedef std::vector<SourceModuleEntry> SourceModulesList; - typedef typename SourceModulesList::size_type SourceModuleHandle; + using SourceModulesList = std::vector<SourceModuleEntry>; + using SourceModuleHandle = typename SourceModulesList::size_type; SourceModuleHandle addSourceModule(std::unique_ptr<ResourceOwner<Module>> M) { @@ -174,7 +181,7 @@ private: void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { for (auto &BLH : BaseLayerHandles) - BaseLayer.removeModuleSet(BLH); + BaseLayer.removeModule(BLH); } std::unique_ptr<JITSymbolResolver> ExternalSymbolResolver; @@ -183,21 +190,21 @@ private: StaticGlobalRenamer StaticRenamer; ModuleAdderFtor ModuleAdder; SourceModulesList SourceModules; - std::vector<BaseLayerModuleSetHandleT> BaseLayerHandles; + std::vector<BaseLayerModuleHandleT> BaseLayerHandles; }; - typedef std::list<LogicalDylib> LogicalDylibList; + using LogicalDylibList = std::list<LogicalDylib>; public: - /// @brief Handle to a set of loaded modules. - typedef typename LogicalDylibList::iterator ModuleSetHandleT; + /// @brief Handle to loaded module. + using ModuleHandleT = typename LogicalDylibList::iterator; /// @brief Module partitioning functor. - typedef std::function<std::set<Function*>(Function&)> PartitioningFtor; + using PartitioningFtor = std::function<std::set<Function*>(Function&)>; /// @brief Builder for IndirectStubsManagers. - typedef std::function<std::unique_ptr<IndirectStubsMgrT>()> - IndirectStubsManagerBuilderT; + using IndirectStubsManagerBuilderT = + std::function<std::unique_ptr<IndirectStubsMgrT>()>; /// @brief Construct a compile-on-demand layer instance. CompileOnDemandLayer(BaseLayerT &BaseLayer, PartitioningFtor Partition, @@ -211,15 +218,14 @@ public: ~CompileOnDemandLayer() { while (!LogicalDylibs.empty()) - removeModuleSet(LogicalDylibs.begin()); + removeModule(LogicalDylibs.begin()); } - + /// @brief Add a module to the compile-on-demand layer. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { LogicalDylibs.push_back(LogicalDylib()); auto &LD = LogicalDylibs.back(); @@ -232,23 +238,25 @@ public: LD.ModuleAdder = [&MemMgrRef](BaseLayerT &B, std::unique_ptr<Module> M, std::unique_ptr<JITSymbolResolver> R) { - std::vector<std::unique_ptr<Module>> Ms; - Ms.push_back(std::move(M)); - return B.addModuleSet(std::move(Ms), &MemMgrRef, std::move(R)); + return B.addModule(std::move(M), &MemMgrRef, std::move(R)); }; // Process each of the modules in this module set. - for (auto &M : Ms) - addLogicalModule(LogicalDylibs.back(), std::move(M)); + addLogicalModule(LogicalDylibs.back(), std::move(M)); return std::prev(LogicalDylibs.end()); } + /// @brief Add extra modules to an existing logical module. + void addExtraModule(ModuleHandleT H, std::shared_ptr<Module> M) { + addLogicalModule(*H, std::move(M)); + } + /// @brief Remove the module represented by the given handle. /// /// This will remove all modules in the layers below that were derived from /// the module represented by H. - void removeModuleSet(ModuleSetHandleT H) { + void removeModule(ModuleHandleT H) { H->removeModulesFromBaseLayer(BaseLayer); LogicalDylibs.erase(H); } @@ -270,7 +278,7 @@ public: /// @brief Get the address of a symbol provided by this layer, or some layer /// below this one. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return H->findSymbol(BaseLayer, Name, ExportedSymbolsOnly); } @@ -303,7 +311,6 @@ public: private: template <typename ModulePtrT> void addLogicalModule(LogicalDylib &LD, ModulePtrT SrcMPtr) { - // Rename all static functions / globals to $static.X : // This will unique the names across all modules in the logical dylib, // simplifying symbol lookup. @@ -495,7 +502,7 @@ private: } template <typename PartitionT> - BaseLayerModuleSetHandleT + BaseLayerModuleHandleT emitPartition(LogicalDylib &LD, typename LogicalDylib::SourceModuleHandle LMId, const PartitionT &Part) { @@ -581,6 +588,7 @@ private: }; } // end namespace orc + } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/include/llvm/ExecutionEngine/Orc/CompileUtils.h index ce0864fbd9c9a..b9f7d6accc308 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileUtils.h +++ b/include/llvm/ExecutionEngine/Orc/CompileUtils.h @@ -1,4 +1,4 @@ -//===-- CompileUtils.h - Utilities for compiling IR in the JIT --*- C++ -*-===// +//===- CompileUtils.h - Utilities for compiling IR in the JIT ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,24 +14,47 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H #define LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/ObjectMemoryBuffer.h" #include "llvm/IR/LegacyPassManager.h" -#include "llvm/MC/MCContext.h" +#include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include <algorithm> +#include <memory> namespace llvm { + +class MCContext; +class Module; + namespace orc { /// @brief Simple compile functor: Takes a single IR module and returns an /// ObjectFile. class SimpleCompiler { public: + + using CompileResult = object::OwningBinary<object::ObjectFile>; + /// @brief Construct a simple compile functor with the given target. - SimpleCompiler(TargetMachine &TM) : TM(TM) {} + SimpleCompiler(TargetMachine &TM, ObjectCache *ObjCache = nullptr) + : TM(TM), ObjCache(ObjCache) {} + + /// @brief Set an ObjectCache to query before compiling. + void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } /// @brief Compile a Module to an ObjectFile. - object::OwningBinary<object::ObjectFile> operator()(Module &M) const { + CompileResult operator()(Module &M) { + CompileResult CachedObject = tryToLoadFromObjectCache(M); + if (CachedObject.getBinary()) + return CachedObject; + SmallVector<char, 0> ObjBufferSV; raw_svector_ostream ObjStream(ObjBufferSV); @@ -44,19 +67,47 @@ public: new ObjectMemoryBuffer(std::move(ObjBufferSV))); Expected<std::unique_ptr<object::ObjectFile>> Obj = object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - typedef object::OwningBinary<object::ObjectFile> OwningObj; - if (Obj) - return OwningObj(std::move(*Obj), std::move(ObjBuffer)); + if (Obj) { + notifyObjectCompiled(M, *ObjBuffer); + return CompileResult(std::move(*Obj), std::move(ObjBuffer)); + } // TODO: Actually report errors helpfully. consumeError(Obj.takeError()); - return OwningObj(nullptr, nullptr); + return CompileResult(nullptr, nullptr); } private: + + CompileResult tryToLoadFromObjectCache(const Module &M) { + if (!ObjCache) + return CompileResult(); + + std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M); + if (!ObjBuffer) + return CompileResult(); + + Expected<std::unique_ptr<object::ObjectFile>> Obj = + object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); + if (!Obj) { + // TODO: Actually report errors helpfully. + consumeError(Obj.takeError()); + return CompileResult(); + } + + return CompileResult(std::move(*Obj), std::move(ObjBuffer)); + } + + void notifyObjectCompiled(const Module &M, const MemoryBuffer &ObjBuffer) { + if (ObjCache) + ObjCache->notifyObjectCompiled(&M, ObjBuffer.getMemBufferRef()); + } + TargetMachine &TM; + ObjectCache *ObjCache = nullptr; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc + +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_COMPILEUTILS_H diff --git a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h index 71d847c062644..bf8cca406844d 100644 --- a/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h @@ -1,4 +1,4 @@ -//===-- ExecutionUtils.h - Utilities for executing code in Orc --*- C++ -*-===// +//===- ExecutionUtils.h - Utilities for executing code in Orc ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,8 +17,11 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" +#include <algorithm> +#include <cstdint> +#include <string> #include <vector> +#include <utility> namespace llvm { @@ -37,7 +40,6 @@ namespace orc { /// getConstructors/getDestructors functions. class CtorDtorIterator { public: - /// @brief Accessor for an element of the global_ctors/global_dtors array. /// /// This class provides a read-only view of the element with any casts on @@ -89,17 +91,16 @@ iterator_range<CtorDtorIterator> getDestructors(const Module &M); template <typename JITLayerT> class CtorDtorRunner { public: - /// @brief Construct a CtorDtorRunner for the given range using the given /// name mangling function. CtorDtorRunner(std::vector<std::string> CtorDtorNames, - typename JITLayerT::ModuleSetHandleT H) + typename JITLayerT::ModuleHandleT H) : CtorDtorNames(std::move(CtorDtorNames)), H(H) {} /// @brief Run the recorded constructors/destructors through the given JIT /// layer. bool runViaLayer(JITLayerT &JITLayer) const { - typedef void (*CtorDtorTy)(); + using CtorDtorTy = void (*)(); bool Error = false; for (const auto &CtorDtorName : CtorDtorNames) @@ -115,7 +116,7 @@ public: private: std::vector<std::string> CtorDtorNames; - typename JITLayerT::ModuleSetHandleT H; + typename JITLayerT::ModuleHandleT H; }; /// @brief Support class for static dtor execution. For hosted (in-process) JITs @@ -135,7 +136,6 @@ private: /// called. class LocalCXXRuntimeOverrides { public: - /// Create a runtime-overrides class. template <typename MangleFtorT> LocalCXXRuntimeOverrides(const MangleFtorT &Mangle) { @@ -156,7 +156,6 @@ public: void runDestructors(); private: - template <typename PtrTy> JITTargetAddress toTargetAddress(PtrTy* P) { return static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(P)); @@ -168,15 +167,16 @@ private: StringMap<JITTargetAddress> CXXRuntimeOverrides; - typedef void (*DestructorPtr)(void*); - typedef std::pair<DestructorPtr, void*> CXXDestructorDataPair; - typedef std::vector<CXXDestructorDataPair> CXXDestructorDataPairList; + using DestructorPtr = void (*)(void *); + using CXXDestructorDataPair = std::pair<DestructorPtr, void *>; + using CXXDestructorDataPairList = std::vector<CXXDestructorDataPair>; CXXDestructorDataPairList DSOHandleOverride; static int CXAAtExitOverride(DestructorPtr Destructor, void *Arg, void *DSOHandle); }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc + +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_EXECUTIONUTILS_H diff --git a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h index 634d1480ae4c0..d582e9a33241f 100644 --- a/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/GlobalMappingLayer.h @@ -1,4 +1,4 @@ -//===---- GlobalMappingLayer.h - Run all IR through a functor ---*- C++ -*-===// +//===- GlobalMappingLayer.h - Run all IR through a functor ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,6 +17,7 @@ #include "llvm/ExecutionEngine/JITSymbol.h" #include <map> +#include <string> namespace llvm { namespace orc { @@ -32,7 +33,7 @@ template <typename BaseLayerT> class GlobalMappingLayer { public: /// @brief Handle to a set of added modules. - typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT; + using ModuleSetHandleT = typename BaseLayerT::ModuleSetHandleT; /// @brief Construct an GlobalMappingLayer with the given BaseLayer GlobalMappingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} @@ -102,7 +103,7 @@ private: std::map<std::string, JITTargetAddress> SymbolTable; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_GLOBALMAPPINGLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h index f81d054440fc9..99ccd4d221a5e 100644 --- a/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h @@ -1,4 +1,4 @@ -//===------ IRCompileLayer.h -- Eagerly compile IR for JIT ------*- C++ -*-===// +//===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,79 +14,54 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H +#include "llvm/ADT/STLExtras.h" #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/ExecutionEngine/ObjectCache.h" -#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Error.h" #include <memory> +#include <string> namespace llvm { + +class Module; + namespace orc { /// @brief Eager IR compiling layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It -/// immediately compiles each IR module to an object file (each IR Module is -/// compiled separately). The resulting set of object files is then added to -/// the layer below, which must implement the object layer concept. -template <typename BaseLayerT> class IRCompileLayer { +/// This layer immediately compiles each IR module added via addModule to an +/// object file and adds this module file to the layer below, which must +/// implement the object layer concept. +template <typename BaseLayerT, typename CompileFtor> +class IRCompileLayer { public: - typedef std::function<object::OwningBinary<object::ObjectFile>(Module &)> - CompileFtor; - -private: - typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT; -public: - /// @brief Handle to a set of compiled modules. - typedef ObjSetHandleT ModuleSetHandleT; + /// @brief Handle to a compiled module. + using ModuleHandleT = typename BaseLayerT::ObjHandleT; /// @brief Construct an IRCompileLayer with the given BaseLayer, which must /// implement the ObjectLayer concept. IRCompileLayer(BaseLayerT &BaseLayer, CompileFtor Compile) - : BaseLayer(BaseLayer), Compile(std::move(Compile)), ObjCache(nullptr) {} + : BaseLayer(BaseLayer), Compile(std::move(Compile)) {} - /// @brief Set an ObjectCache to query before compiling. - void setObjectCache(ObjectCache *NewCache) { ObjCache = NewCache; } + /// @brief Get a reference to the compiler functor. + CompileFtor& getCompiler() { return Compile; } - /// @brief Compile each module in the given module set, then add the resulting - /// set of objects to the base layer along with the memory manager and - /// symbol resolver. + /// @brief Compile the module, and add the resulting object to the base layer + /// along with the given memory manager and symbol resolver. /// - /// @return A handle for the added modules. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>> - Objects; - - for (const auto &M : Ms) { - auto Object = - llvm::make_unique<object::OwningBinary<object::ObjectFile>>(); - - if (ObjCache) - *Object = tryToLoadFromObjectCache(*M); - - if (!Object->getBinary()) { - *Object = Compile(*M); - if (ObjCache) - ObjCache->notifyObjectCompiled(&*M, - Object->getBinary()->getMemoryBufferRef()); - } - - Objects.push_back(std::move(Object)); - } - - ModuleSetHandleT H = - BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr), - std::move(Resolver)); - - return H; + /// @return A handle for the added module. + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + using CompileResult = decltype(Compile(*M)); + auto Obj = std::make_shared<CompileResult>(Compile(*M)); + return BaseLayer.addObject(std::move(Obj), std::move(MemMgr), + std::move(Resolver)); } - /// @brief Remove the module set associated with the handle H. - void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeObjectSet(H); } + /// @brief Remove the module associated with the handle H. + void removeModule(ModuleHandleT H) { BaseLayer.removeObject(H); } /// @brief Search for the given named symbol. /// @param Name The name of the symbol to search for. @@ -96,51 +71,33 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the set of - /// compiled modules represented by the handle H. This call is - /// forwarded to the base layer's implementation. - /// @param H The handle for the module set to search in. + /// @brief Get the address of the given symbol in compiled module represented + /// by the handle H. This call is forwarded to the base layer's + /// implementation. + /// @param H The handle for the module to search in. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the - /// given module set. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + /// given module. + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the moduleOB set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { BaseLayer.emitAndFinalize(H); } private: - object::OwningBinary<object::ObjectFile> - tryToLoadFromObjectCache(const Module &M) { - std::unique_ptr<MemoryBuffer> ObjBuffer = ObjCache->getObject(&M); - if (!ObjBuffer) - return object::OwningBinary<object::ObjectFile>(); - - Expected<std::unique_ptr<object::ObjectFile>> Obj = - object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()); - if (!Obj) { - // TODO: Actually report errors helpfully. - consumeError(Obj.takeError()); - return object::OwningBinary<object::ObjectFile>(); - } - - return object::OwningBinary<object::ObjectFile>(std::move(*Obj), - std::move(ObjBuffer)); - } - BaseLayerT &BaseLayer; CompileFtor Compile; - ObjectCache *ObjCache; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc + +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h index c67297b111b93..8e9be6b6f4fe4 100644 --- a/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h @@ -1,4 +1,4 @@ -//===----- IRTransformLayer.h - Run all IR through a functor ----*- C++ -*-===// +//===- IRTransformLayer.h - Run all IR through a functor --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,46 +15,41 @@ #define LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include <string> namespace llvm { namespace orc { /// @brief IR mutating layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet). It -/// immediately applies the user supplied functor to each module, then adds -/// the set of transformed modules to the layer below. +/// This layer applies a user supplied transform to each module that is added, +/// then adds the transformed module to the layer below. template <typename BaseLayerT, typename TransformFtor> class IRTransformLayer { public: + /// @brief Handle to a set of added modules. - typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT; + using ModuleHandleT = typename BaseLayerT::ModuleHandleT; /// @brief Construct an IRTransformLayer with the given BaseLayer IRTransformLayer(BaseLayerT &BaseLayer, TransformFtor Transform = TransformFtor()) : BaseLayer(BaseLayer), Transform(std::move(Transform)) {} - /// @brief Apply the transform functor to each module in the module set, then - /// add the resulting set of modules to the base layer, along with the - /// memory manager and symbol resolver. + /// @brief Apply the transform functor to the module, then add the module to + /// the layer below, along with the memory manager and symbol resolver. /// /// @return A handle for the added modules. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - - for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I) - *I = Transform(std::move(*I)); - - return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr), - std::move(Resolver)); + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return BaseLayer.addModule(Transform(std::move(M)), std::move(MemMgr), + std::move(Resolver)); } - /// @brief Remove the module set associated with the handle H. - void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); } + /// @brief Remove the module associated with the handle H. + void removeModule(ModuleHandleT H) { BaseLayer.removeModule(H); } /// @brief Search for the given named symbol. /// @param Name The name of the symbol to search for. @@ -64,23 +59,23 @@ public: return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); } - /// @brief Get the address of the given symbol in the context of the set of - /// modules represented by the handle H. This call is forwarded to the - /// base layer's implementation. - /// @param H The handle for the module set to search in. + /// @brief Get the address of the given symbol in the context of the module + /// represented by the handle H. This call is forwarded to the base + /// layer's implementation. + /// @param H The handle for the module to search in. /// @param Name The name of the symbol to search for. /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the - /// given module set. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + /// given module. + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } - /// @brief Immediately emit and finalize the module set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { BaseLayer.emitAndFinalize(H); } @@ -95,7 +90,7 @@ private: TransformFtor Transform; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_IRTRANSFORMLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index 07bbd921dad62..e038093d7628c 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -1,4 +1,4 @@ -//===-- IndirectionUtils.h - Utilities for adding indirections --*- C++ -*-===// +//===- IndirectionUtils.h - Utilities for adding indirections ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,9 +18,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ExecutionEngine/JITSymbol.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Mangler.h" -#include "llvm/IR/Module.h" #include "llvm/Support/Error.h" #include "llvm/Support/Memory.h" #include "llvm/Support/Process.h" @@ -36,12 +33,23 @@ #include <vector> namespace llvm { + +class Constant; +class Function; +class FunctionType; +class GlobalAlias; +class GlobalVariable; +class Module; +class PointerType; +class Triple; +class Value; + namespace orc { /// @brief Target-independent base class for compile callback management. class JITCompileCallbackManager { public: - typedef std::function<JITTargetAddress()> CompileFtor; + using CompileFtor = std::function<JITTargetAddress()>; /// @brief Handle to a newly created compile callback. Can be used to get an /// IR constant representing the address of the trampoline, and to set @@ -125,7 +133,7 @@ public: protected: JITTargetAddress ErrorHandlerAddress; - typedef std::map<JITTargetAddress, CompileFtor> TrampolineMapT; + using TrampolineMapT = std::map<JITTargetAddress, CompileFtor>; TrampolineMapT ActiveTrampolines; std::vector<JITTargetAddress> AvailableTrampolines; @@ -155,7 +163,6 @@ public: /// process to be used if a compile callback fails. LocalJITCompileCallbackManager(JITTargetAddress ErrorHandlerAddress) : JITCompileCallbackManager(ErrorHandlerAddress) { - /// Set up the resolver block. std::error_code EC; ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( @@ -220,7 +227,7 @@ private: class IndirectStubsManager { public: /// @brief Map type for initializing the manager. See init. - typedef StringMap<std::pair<JITTargetAddress, JITSymbolFlags>> StubInitsMap; + using StubInitsMap = StringMap<std::pair<JITTargetAddress, JITSymbolFlags>>; virtual ~IndirectStubsManager() = default; @@ -336,7 +343,7 @@ private: } std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos; - typedef std::pair<uint16_t, uint16_t> StubKey; + using StubKey = std::pair<uint16_t, uint16_t>; std::vector<StubKey> FreeStubs; StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes; }; @@ -432,6 +439,7 @@ void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, ValueToValueMapTy &VMap); } // end namespace orc + } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H diff --git a/include/llvm/ExecutionEngine/Orc/LambdaResolver.h b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h index cbe2a80edf1c1..6868640d38e80 100644 --- a/include/llvm/ExecutionEngine/Orc/LambdaResolver.h +++ b/include/llvm/ExecutionEngine/Orc/LambdaResolver.h @@ -1,4 +1,4 @@ -//===-- LambdaResolverMM - Redirect symbol lookup via a functor -*- C++ -*-===// +//===- LambdaResolverMM - Redirect symbol lookup via a functor --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,7 +16,7 @@ #define LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H #include "llvm/ADT/STLExtras.h" -#include "llvm/ExecutionEngine/RuntimeDyld.h" +#include "llvm/ExecutionEngine/JITSymbol.h" #include <memory> namespace llvm { @@ -25,7 +25,6 @@ namespace orc { template <typename DylibLookupFtorT, typename ExternalLookupFtorT> class LambdaResolver : public JITSymbolResolver { public: - LambdaResolver(DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor) : DylibLookupFtor(DylibLookupFtor), @@ -49,12 +48,12 @@ template <typename DylibLookupFtorT, std::unique_ptr<LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>> createLambdaResolver(DylibLookupFtorT DylibLookupFtor, ExternalLookupFtorT ExternalLookupFtor) { - typedef LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT> LR; + using LR = LambdaResolver<DylibLookupFtorT, ExternalLookupFtorT>; return make_unique<LR>(std::move(DylibLookupFtor), std::move(ExternalLookupFtor)); } -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_LAMBDARESOLVER_H diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 53d4c0cfe5d4d..38769aac12afe 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -34,19 +34,20 @@ namespace orc { /// @brief Lazy-emitting IR layer. /// -/// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does -/// not immediately emit them the layer below. Instead, emissing to the base -/// layer is deferred until the first time the client requests the address -/// (via JITSymbol::getAddress) for a symbol contained in this layer. +/// This layer accepts LLVM IR Modules (via addModule), but does not +/// immediately emit them the layer below. Instead, emissing to the base layer +/// is deferred until the first time the client requests the address (via +/// JITSymbol::getAddress) for a symbol contained in this layer. template <typename BaseLayerT> class LazyEmittingLayer { public: - typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT; + + using BaseLayerHandleT = typename BaseLayerT::ModuleHandleT; private: - class EmissionDeferredSet { + class EmissionDeferredModule { public: - EmissionDeferredSet() = default; - virtual ~EmissionDeferredSet() = default; + EmissionDeferredModule() = default; + virtual ~EmissionDeferredModule() = default; JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { @@ -84,9 +85,9 @@ private: llvm_unreachable("Invalid emit-state."); } - void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) { + void removeModuleFromBaseLayer(BaseLayerT &BaseLayer) { if (EmitState != NotEmitted) - BaseLayer.removeModuleSet(Handle); + BaseLayer.removeModule(Handle); } void emitAndFinalize(BaseLayerT &BaseLayer) { @@ -100,10 +101,9 @@ private: BaseLayer.emitAndFinalize(Handle); } - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - static std::unique_ptr<EmissionDeferredSet> - create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr, + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + static std::unique_ptr<EmissionDeferredModule> + create(BaseLayerT &B, std::shared_ptr<Module> M, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver); protected: @@ -116,14 +116,13 @@ private: BaseLayerHandleT Handle; }; - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - class EmissionDeferredSetImpl : public EmissionDeferredSet { + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + class EmissionDeferredModuleImpl : public EmissionDeferredModule { public: - EmissionDeferredSetImpl(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) - : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)), + EmissionDeferredModuleImpl(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) + : M(std::move(M)), MemMgr(std::move(MemMgr)), Resolver(std::move(Resolver)) {} protected: @@ -154,8 +153,8 @@ private: // We don't need the mangled names set any more: Once we've emitted this // to the base layer we'll just look for symbols there. MangledSymbols.reset(); - return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr), - std::move(Resolver)); + return BaseLayer.addModule(std::move(M), std::move(MemMgr), + std::move(Resolver)); } private: @@ -197,56 +196,54 @@ private: auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>(); - for (const auto &M : Ms) { - Mangler Mang; + Mangler Mang; - for (const auto &GO : M->global_objects()) + for (const auto &GO : M->global_objects()) if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName, ExportedSymbolsOnly)) return GV; - } MangledSymbols = std::move(Symbols); return nullptr; } - ModuleSetT Ms; + std::shared_ptr<Module> M; MemoryManagerPtrT MemMgr; SymbolResolverPtrT Resolver; mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols; }; - typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT; + using ModuleListT = std::list<std::unique_ptr<EmissionDeferredModule>>; BaseLayerT &BaseLayer; - ModuleSetListT ModuleSetList; + ModuleListT ModuleList; public: - /// @brief Handle to a set of loaded modules. - typedef typename ModuleSetListT::iterator ModuleSetHandleT; + /// @brief Handle to a loaded module. + using ModuleHandleT = typename ModuleListT::iterator; /// @brief Construct a lazy emitting layer. LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {} - /// @brief Add the given set of modules to the lazy emitting layer. - template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> - ModuleSetHandleT addModuleSet(ModuleSetT Ms, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - return ModuleSetList.insert( - ModuleSetList.end(), - EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr), - std::move(Resolver))); + /// @brief Add the given module to the lazy emitting layer. + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> + ModuleHandleT addModule(std::shared_ptr<Module> M, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return ModuleList.insert( + ModuleList.end(), + EmissionDeferredModule::create(BaseLayer, std::move(M), + std::move(MemMgr), + std::move(Resolver))); } - /// @brief Remove the module set represented by the given handle. + /// @brief Remove the module represented by the given handle. /// - /// This method will free the memory associated with the given module set, - /// both in this layer, and the base layer. - void removeModuleSet(ModuleSetHandleT H) { - (*H)->removeModulesFromBaseLayer(BaseLayer); - ModuleSetList.erase(H); + /// This method will free the memory associated with the given module, both + /// in this layer, and the base layer. + void removeModule(ModuleHandleT H) { + (*H)->removeModuleFromBaseLayer(BaseLayer); + ModuleList.erase(H); } /// @brief Search for the given named symbol. @@ -258,42 +255,40 @@ public: if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly)) return Symbol; - // If not found then search the deferred sets. If any of these contain a + // If not found then search the deferred modules. If any of these contain a // definition of 'Name' then they will return a JITSymbol that will emit // the corresponding module when the symbol address is requested. - for (auto &DeferredSet : ModuleSetList) - if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer)) + for (auto &DeferredMod : ModuleList) + if (auto Symbol = DeferredMod->find(Name, ExportedSymbolsOnly, BaseLayer)) return Symbol; // If no definition found anywhere return a null symbol. return nullptr; } - /// @brief Get the address of the given symbol in the context of the set of + /// @brief Get the address of the given symbol in the context of the of /// compiled modules represented by the handle H. - JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer); } - /// @brief Immediately emit and finalize the moduleOB set represented by the - /// given handle. - /// @param H Handle for module set to emit/finalize. - void emitAndFinalize(ModuleSetHandleT H) { + /// @brief Immediately emit and finalize the module represented by the given + /// handle. + /// @param H Handle for module to emit/finalize. + void emitAndFinalize(ModuleHandleT H) { (*H)->emitAndFinalize(BaseLayer); } }; template <typename BaseLayerT> -template <typename ModuleSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT> -std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet> -LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create( - BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr, +template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> +std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredModule> +LazyEmittingLayer<BaseLayerT>::EmissionDeferredModule::create( + BaseLayerT &B, std::shared_ptr<Module> M, MemoryManagerPtrT MemMgr, SymbolResolverPtrT Resolver) { - typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT> - EDS; - return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr), + using EDS = EmissionDeferredModuleImpl<MemoryManagerPtrT, SymbolResolverPtrT>; + return llvm::make_unique<EDS>(std::move(M), std::move(MemMgr), std::move(Resolver)); } diff --git a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h index 173c106cd3ec9..c41c1233c0d96 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectTransformLayer.h @@ -15,20 +15,22 @@ #define LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H #include "llvm/ExecutionEngine/JITSymbol.h" +#include <algorithm> +#include <string> namespace llvm { namespace orc { /// @brief Object mutating layer. /// -/// This layer accepts sets of ObjectFiles (via addObjectSet). It +/// This layer accepts sets of ObjectFiles (via addObject). It /// immediately applies the user supplied functor to each object, then adds /// the set of transformed objects to the layer below. template <typename BaseLayerT, typename TransformFtor> class ObjectTransformLayer { public: /// @brief Handle to a set of added objects. - typedef typename BaseLayerT::ObjSetHandleT ObjSetHandleT; + using ObjHandleT = typename BaseLayerT::ObjHandleT; /// @brief Construct an ObjectTransformLayer with the given BaseLayer ObjectTransformLayer(BaseLayerT &BaseLayer, @@ -40,20 +42,16 @@ public: /// memory manager and symbol resolver. /// /// @return A handle for the added objects. - template <typename ObjSetT, typename MemoryManagerPtrT, + template <typename ObjPtrT, typename MemoryManagerPtrT, typename SymbolResolverPtrT> - ObjSetHandleT addObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - - for (auto I = Objects.begin(), E = Objects.end(); I != E; ++I) - *I = Transform(std::move(*I)); - - return BaseLayer.addObjectSet(std::move(Objects), std::move(MemMgr), - std::move(Resolver)); + ObjHandleT addObject(ObjPtrT Obj, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { + return BaseLayer.addObject(Transform(std::move(Obj)), std::move(MemMgr), + std::move(Resolver)); } /// @brief Remove the object set associated with the handle H. - void removeObjectSet(ObjSetHandleT H) { BaseLayer.removeObjectSet(H); } + void removeObject(ObjHandleT H) { BaseLayer.removeObject(H); } /// @brief Search for the given named symbol. /// @param Name The name of the symbol to search for. @@ -71,7 +69,7 @@ public: /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the /// given object set. - JITSymbol findSymbolIn(ObjSetHandleT H, const std::string &Name, + JITSymbol findSymbolIn(ObjHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly); } @@ -79,10 +77,10 @@ public: /// @brief Immediately emit and finalize the object set represented by the /// given handle. /// @param H Handle for object set to emit/finalize. - void emitAndFinalize(ObjSetHandleT H) { BaseLayer.emitAndFinalize(H); } + void emitAndFinalize(ObjHandleT H) { BaseLayer.emitAndFinalize(H); } /// @brief Map section addresses for the objects associated with the handle H. - void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress, + void mapSectionAddress(ObjHandleT H, const void *LocalAddress, JITTargetAddress TargetAddr) { BaseLayer.mapSectionAddress(H, LocalAddress, TargetAddr); } @@ -98,7 +96,7 @@ private: TransformFtor Transform; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTTRANSFORMLAYER_H diff --git a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h index fa236b0de88a3..e1b55649b9f2c 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcABISupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcABISupport.h @@ -1,4 +1,4 @@ -//===-------------- OrcABISupport.h - ABI support code ---------*- C++ -*-===// +//===- OrcABISupport.h - ABI support code -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,9 +18,12 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H #define LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H -#include "IndirectionUtils.h" +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Memory.h" -#include "llvm/Support/Process.h" +#include <algorithm> +#include <cstdint> namespace llvm { namespace orc { @@ -37,8 +40,8 @@ public: static const unsigned TrampolineSize = 1; static const unsigned ResolverCodeSize = 1; - typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, + void *TrampolineId); static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry, void *CallbackMgr) { @@ -55,6 +58,7 @@ public: class IndirectStubsInfo { public: const static unsigned StubSize = 1; + unsigned getNumStubs() const { llvm_unreachable("Not supported"); } void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); } void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); } @@ -73,13 +77,14 @@ template <unsigned StubSizeVal> class GenericIndirectStubsInfo { public: const static unsigned StubSize = StubSizeVal; - GenericIndirectStubsInfo() : NumStubs(0) {} + GenericIndirectStubsInfo() = default; GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem) : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {} GenericIndirectStubsInfo(GenericIndirectStubsInfo &&Other) : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) { Other.NumStubs = 0; } + GenericIndirectStubsInfo &operator=(GenericIndirectStubsInfo &&Other) { NumStubs = Other.NumStubs; Other.NumStubs = 0; @@ -104,7 +109,7 @@ public: } private: - unsigned NumStubs; + unsigned NumStubs = 0; sys::OwningMemoryBlock StubsMem; }; @@ -114,10 +119,10 @@ public: static const unsigned TrampolineSize = 12; static const unsigned ResolverCodeSize = 0x120; - typedef GenericIndirectStubsInfo<8> IndirectStubsInfo; + using IndirectStubsInfo = GenericIndirectStubsInfo<8>; - typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, + void *TrampolineId); /// @brief Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. @@ -148,7 +153,7 @@ public: static const unsigned PointerSize = 8; static const unsigned TrampolineSize = 8; - typedef GenericIndirectStubsInfo<8> IndirectStubsInfo; + using IndirectStubsInfo = GenericIndirectStubsInfo<8>; /// @brief Write the requsted number of trampolines into the given memory, /// which must be big enough to hold 1 pointer, plus NumTrampolines @@ -172,8 +177,9 @@ public: class OrcX86_64_SysV : public OrcX86_64_Base { public: static const unsigned ResolverCodeSize = 0x6C; - typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + + using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, + void *TrampolineId); /// @brief Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. @@ -187,8 +193,9 @@ public: class OrcX86_64_Win32 : public OrcX86_64_Base { public: static const unsigned ResolverCodeSize = 0x74; - typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + + using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, + void *TrampolineId); /// @brief Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. @@ -205,10 +212,10 @@ public: static const unsigned TrampolineSize = 8; static const unsigned ResolverCodeSize = 0x4a; - typedef GenericIndirectStubsInfo<8> IndirectStubsInfo; + using IndirectStubsInfo = GenericIndirectStubsInfo<8>; - typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr, - void *TrampolineId); + using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr, + void *TrampolineId); /// @brief Write the resolver code into the given memory. The user is be /// responsible for allocating the memory and setting permissions. @@ -231,7 +238,7 @@ public: unsigned MinStubs, void *InitialPtrVal); }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h index a19c30631c573..da02250ba1692 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h @@ -1,4 +1,4 @@ -//===---- OrcRemoteTargetClient.h - Orc Remote-target Client ----*- C++ -*-===// +//===- OrcRemoteTargetClient.h - Orc Remote-target Client -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,10 +16,29 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETCLIENT_H -#include "IndirectionUtils.h" -#include "OrcRemoteTargetRPCAPI.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" +#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" -#include <system_error> +#include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/Memory.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <memory> +#include <string> +#include <tuple> +#include <utility> +#include <vector> #define DEBUG_TYPE "orc-remote" @@ -207,7 +226,6 @@ public: DEBUG(dbgs() << "Allocator " << Id << " finalizing:\n"); for (auto &ObjAllocs : Unfinalized) { - for (auto &Alloc : ObjAllocs.CodeAllocs) { DEBUG(dbgs() << " copying code: " << static_cast<void *>(Alloc.getLocalAddress()) << " -> " @@ -469,7 +487,7 @@ public: OrcRemoteTargetClient &Remote; ResourceIdMgr::ResourceId Id; std::vector<RemoteIndirectStubsInfo> RemoteIndirectStubsInfos; - typedef std::pair<uint16_t, uint16_t> StubKey; + using StubKey = std::pair<uint16_t, uint16_t>; std::vector<StubKey> FreeStubs; StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes; @@ -710,7 +728,6 @@ private: Expected<JITTargetAddress> reserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size, uint32_t Align) { - // Check for an 'out-of-band' error, e.g. from an MM destructor. if (ExistingError) return std::move(ExistingError); diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h index 3086ef0cdf803..07ae7f04d1a02 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h @@ -1,4 +1,4 @@ -//===--- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ----*- C++ -*-===// +//===- OrcRemoteTargetRPCAPI.h - Orc Remote-target RPC API ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,12 +16,13 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H -#include "RPCUtils.h" -#include "RawByteChannel.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/RPCUtils.h" +#include "llvm/ExecutionEngine/Orc/RawByteChannel.h" namespace llvm { namespace orc { + namespace remote { class DirectBufferWriter { @@ -72,7 +73,7 @@ public: return EC; char *Addr = reinterpret_cast<char *>(static_cast<uintptr_t>(Dst)); - DBW = remote::DirectBufferWriter(0, Dst, Size); + DBW = remote::DirectBufferWriter(nullptr, Dst, Size); return C.readBytes(Addr, Size); } @@ -87,7 +88,7 @@ class OrcRemoteTargetRPCAPI protected: class ResourceIdMgr { public: - typedef uint64_t ResourceId; + using ResourceId = uint64_t; static const ResourceId InvalidId = ~0U; ResourceId getNext() { @@ -98,6 +99,7 @@ protected: } return NextId++; } + void release(ResourceId I) { FreeIds.push_back(I); } private: @@ -261,7 +263,8 @@ public: }; } // end namespace remote + } // end namespace orc } // end namespace llvm -#endif +#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETRPCAPI_H diff --git a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h index a61ff102be0b0..e7b6d64931b6a 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h +++ b/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h @@ -1,4 +1,4 @@ -//===---- OrcRemoteTargetServer.h - Orc Remote-target Server ----*- C++ -*-===// +//===- OrcRemoteTargetServer.h - Orc Remote-target Server -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,10 +15,9 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H #define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H -#include "OrcRemoteTargetRPCAPI.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/OrcError.h" -#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" +#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" #include "llvm/Support/Format.h" @@ -48,20 +47,18 @@ namespace remote { template <typename ChannelT, typename TargetT> class OrcRemoteTargetServer : public OrcRemoteTargetRPCAPI { public: - typedef std::function<JITTargetAddress(const std::string &Name)> - SymbolLookupFtor; + using SymbolLookupFtor = + std::function<JITTargetAddress(const std::string &Name)>; - typedef std::function<void(uint8_t *Addr, uint32_t Size)> - EHFrameRegistrationFtor; + using EHFrameRegistrationFtor = + std::function<void(uint8_t *Addr, uint32_t Size)>; OrcRemoteTargetServer(ChannelT &Channel, SymbolLookupFtor SymbolLookup, EHFrameRegistrationFtor EHFramesRegister, EHFrameRegistrationFtor EHFramesDeregister) : OrcRemoteTargetRPCAPI(Channel), SymbolLookup(std::move(SymbolLookup)), EHFramesRegister(std::move(EHFramesRegister)), - EHFramesDeregister(std::move(EHFramesDeregister)), - TerminateFlag(false) { - + EHFramesDeregister(std::move(EHFramesDeregister)) { using ThisT = typename std::remove_reference<decltype(*this)>::type; addHandler<CallIntVoid>(*this, &ThisT::handleCallIntVoid); addHandler<CallMain>(*this, &ThisT::handleCallMain); @@ -106,6 +103,7 @@ private: struct Allocator { Allocator() = default; Allocator(Allocator &&Other) : Allocs(std::move(Other.Allocs)) {} + Allocator &operator=(Allocator &&Other) { Allocs = std::move(Other.Allocs); return *this; @@ -153,7 +151,8 @@ private: } Expected<int32_t> handleCallIntVoid(JITTargetAddress Addr) { - typedef int (*IntVoidFnTy)(); + using IntVoidFnTy = int (*)(); + IntVoidFnTy Fn = reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr)); @@ -166,7 +165,7 @@ private: Expected<int32_t> handleCallMain(JITTargetAddress Addr, std::vector<std::string> Args) { - typedef int (*MainFnTy)(int, const char *[]); + using MainFnTy = int (*)(int, const char *[]); MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr)); int ArgC = Args.size() + 1; @@ -175,6 +174,12 @@ private: ArgV[0] = "<jit process>"; for (auto &Arg : Args) ArgV[Idx++] = Arg.c_str(); + ArgV[ArgC] = 0; + DEBUG( + for (int Idx = 0; Idx < ArgC; ++Idx) { + llvm::dbgs() << "Arg " << Idx << ": " << ArgV[Idx] << "\n"; + } + ); DEBUG(dbgs() << " Calling " << format("0x%016x", Addr) << "\n"); int Result = Fn(ArgC, ArgV.get()); @@ -184,7 +189,8 @@ private: } Error handleCallVoidVoid(JITTargetAddress Addr) { - typedef void (*VoidVoidFnTy)(); + using VoidVoidFnTy = void (*)(); + VoidVoidFnTy Fn = reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr)); @@ -420,11 +426,11 @@ private: SymbolLookupFtor SymbolLookup; EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister; std::map<ResourceIdMgr::ResourceId, Allocator> Allocators; - typedef std::vector<typename TargetT::IndirectStubsInfo> ISBlockOwnerList; + using ISBlockOwnerList = std::vector<typename TargetT::IndirectStubsInfo>; std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners; sys::OwningMemoryBlock ResolverBlock; std::vector<sys::OwningMemoryBlock> TrampolineBlocks; - bool TerminateFlag; + bool TerminateFlag = false; }; } // end namespace remote @@ -433,4 +439,4 @@ private: #undef DEBUG_TYPE -#endif +#endif // LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H diff --git a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h index aabb44eef99dc..66ad36be01c8d 100644 --- a/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h @@ -1,4 +1,4 @@ -//===-- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking --*- C++ -*-===// +//===- RTDyldObjectLinkingLayer.h - RTDyld-based jit linking ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,10 +17,8 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Error.h" #include <algorithm> @@ -36,20 +34,26 @@ namespace llvm { namespace orc { class RTDyldObjectLinkingLayerBase { +public: + + using ObjectPtr = + std::shared_ptr<object::OwningBinary<object::ObjectFile>>; + protected: + /// @brief Holds a set of objects to be allocated/linked as a unit in the JIT. /// /// An instance of this class will be created for each set of objects added - /// via JITObjectLayer::addObjectSet. Deleting the instance (via - /// removeObjectSet) frees its memory, removing all symbol definitions that + /// via JITObjectLayer::addObject. Deleting the instance (via + /// removeObject) frees its memory, removing all symbol definitions that /// had been provided by this instance. Higher level layers are responsible /// for taking any action required to handle the missing symbols. - class LinkedObjectSet { + class LinkedObject { public: - LinkedObjectSet() = default; - LinkedObjectSet(const LinkedObjectSet&) = delete; - void operator=(const LinkedObjectSet&) = delete; - virtual ~LinkedObjectSet() = default; + LinkedObject() = default; + LinkedObject(const LinkedObject&) = delete; + void operator=(const LinkedObject&) = delete; + virtual ~LinkedObject() = default; virtual void finalize() = 0; @@ -76,19 +80,11 @@ protected: bool Finalized = false; }; - typedef std::list<std::unique_ptr<LinkedObjectSet>> LinkedObjectSetListT; + using LinkedObjectListT = std::list<std::unique_ptr<LinkedObject>>; public: /// @brief Handle to a set of loaded objects. - typedef LinkedObjectSetListT::iterator ObjSetHandleT; -}; - -/// @brief Default (no-op) action to perform when loading objects. -class DoNothingOnNotifyLoaded { -public: - template <typename ObjSetT, typename LoadResult> - void operator()(RTDyldObjectLinkingLayerBase::ObjSetHandleT, const ObjSetT &, - const LoadResult &) {} + using ObjHandleT = LinkedObjectListT::iterator; }; /// @brief Bare bones object linking layer. @@ -97,46 +93,54 @@ public: /// object files to be loaded into memory, linked, and the addresses of their /// symbols queried. All objects added to this layer can see each other's /// symbols. -template <typename NotifyLoadedFtor = DoNothingOnNotifyLoaded> class RTDyldObjectLinkingLayer : public RTDyldObjectLinkingLayerBase { public: + + using RTDyldObjectLinkingLayerBase::ObjectPtr; + + /// @brief Functor for receiving object-loaded notifications. + using NotifyLoadedFtor = std::function<void(ObjHandleT, const ObjectPtr &Obj, + const LoadedObjectInfo &)>; + /// @brief Functor for receiving finalization notifications. - typedef std::function<void(ObjSetHandleT)> NotifyFinalizedFtor; + using NotifyFinalizedFtor = std::function<void(ObjHandleT)>; private: - template <typename ObjSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT, typename FinalizerFtor> - class ConcreteLinkedObjectSet : public LinkedObjectSet { + + + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT, + typename FinalizerFtor> + class ConcreteLinkedObject : public LinkedObject { public: - ConcreteLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) + ConcreteLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver, + FinalizerFtor Finalizer, + bool ProcessAllSections) : MemMgr(std::move(MemMgr)), - PFC(llvm::make_unique<PreFinalizeContents>(std::move(Objects), + PFC(llvm::make_unique<PreFinalizeContents>(std::move(Obj), std::move(Resolver), std::move(Finalizer), ProcessAllSections)) { - buildInitialSymbolTable(PFC->Objects); + buildInitialSymbolTable(PFC->Obj); } - ~ConcreteLinkedObjectSet() override { + ~ConcreteLinkedObject() override { MemMgr->deregisterEHFrames(); } - - void setHandle(ObjSetHandleT H) { + + void setHandle(ObjHandleT H) { PFC->Handle = H; } void finalize() override { - assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet"); + assert(PFC && "mapSectionAddress called on finalized LinkedObject"); RuntimeDyld RTDyld(*MemMgr, *PFC->Resolver); RTDyld.setProcessAllSections(PFC->ProcessAllSections); PFC->RTDyld = &RTDyld; this->Finalized = true; - PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Objects), + PFC->Finalizer(PFC->Handle, RTDyld, std::move(PFC->Obj), [&]() { this->updateSymbolTable(RTDyld); }); @@ -158,27 +162,27 @@ private: void mapSectionAddress(const void *LocalAddress, JITTargetAddress TargetAddr) const override { - assert(PFC && "mapSectionAddress called on finalized LinkedObjectSet"); - assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObjectSet"); + assert(PFC && "mapSectionAddress called on finalized LinkedObject"); + assert(PFC->RTDyld && "mapSectionAddress called on raw LinkedObject"); PFC->RTDyld->mapSectionAddress(LocalAddress, TargetAddr); } private: - void buildInitialSymbolTable(const ObjSetT &Objects) { - for (const auto &Obj : Objects) - for (auto &Symbol : getObject(*Obj).symbols()) { - if (Symbol.getFlags() & object::SymbolRef::SF_Undefined) - continue; - Expected<StringRef> SymbolName = Symbol.getName(); - // FIXME: Raise an error for bad symbols. - if (!SymbolName) { - consumeError(SymbolName.takeError()); - continue; - } - auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol); - SymbolTable.insert( - std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags))); + + void buildInitialSymbolTable(const ObjectPtr &Obj) { + for (auto &Symbol : Obj->getBinary()->symbols()) { + if (Symbol.getFlags() & object::SymbolRef::SF_Undefined) + continue; + Expected<StringRef> SymbolName = Symbol.getName(); + // FIXME: Raise an error for bad symbols. + if (!SymbolName) { + consumeError(SymbolName.takeError()); + continue; } + auto Flags = JITSymbolFlags::fromObjectSymbol(Symbol); + SymbolTable.insert( + std::make_pair(*SymbolName, JITEvaluatedSymbol(0, Flags))); + } } void updateSymbolTable(const RuntimeDyld &RTDyld) { @@ -189,17 +193,17 @@ private: // Contains the information needed prior to finalization: the object files, // memory manager, resolver, and flags needed for RuntimeDyld. struct PreFinalizeContents { - PreFinalizeContents(ObjSetT Objects, SymbolResolverPtrT Resolver, + PreFinalizeContents(ObjectPtr Obj, SymbolResolverPtrT Resolver, FinalizerFtor Finalizer, bool ProcessAllSections) - : Objects(std::move(Objects)), Resolver(std::move(Resolver)), + : Obj(std::move(Obj)), Resolver(std::move(Resolver)), Finalizer(std::move(Finalizer)), ProcessAllSections(ProcessAllSections) {} - ObjSetT Objects; + ObjectPtr Obj; SymbolResolverPtrT Resolver; FinalizerFtor Finalizer; bool ProcessAllSections; - ObjSetHandleT Handle; + ObjHandleT Handle; RuntimeDyld *RTDyld; }; @@ -207,27 +211,22 @@ private: std::unique_ptr<PreFinalizeContents> PFC; }; - template <typename ObjSetT, typename MemoryManagerPtrT, - typename SymbolResolverPtrT, typename FinalizerFtor> + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT, + typename FinalizerFtor> std::unique_ptr< - ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT, - SymbolResolverPtrT, FinalizerFtor>> - createLinkedObjectSet(ObjSetT Objects, MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver, - FinalizerFtor Finalizer, - bool ProcessAllSections) { - typedef ConcreteLinkedObjectSet<ObjSetT, MemoryManagerPtrT, - SymbolResolverPtrT, FinalizerFtor> LOS; - return llvm::make_unique<LOS>(std::move(Objects), std::move(MemMgr), + ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, FinalizerFtor>> + createLinkedObject(ObjectPtr Obj, MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver, + FinalizerFtor Finalizer, + bool ProcessAllSections) { + using LOS = ConcreteLinkedObject<MemoryManagerPtrT, SymbolResolverPtrT, + FinalizerFtor>; + return llvm::make_unique<LOS>(std::move(Obj), std::move(MemMgr), std::move(Resolver), std::move(Finalizer), ProcessAllSections); } public: - /// @brief LoadedObjectInfo list. Contains a list of owning pointers to - /// RuntimeDyld::LoadedObjectInfo instances. - typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>> - LoadedObjInfoList; /// @brief Construct an ObjectLinkingLayer with the given NotifyLoaded, /// and NotifyFinalized functors. @@ -235,8 +234,7 @@ public: NotifyLoadedFtor NotifyLoaded = NotifyLoadedFtor(), NotifyFinalizedFtor NotifyFinalized = NotifyFinalizedFtor()) : NotifyLoaded(std::move(NotifyLoaded)), - NotifyFinalized(std::move(NotifyFinalized)), - ProcessAllSections(false) {} + NotifyFinalized(std::move(NotifyFinalized)) {} /// @brief Set the 'ProcessAllSections' flag. /// @@ -253,23 +251,22 @@ public: /// /// @return A handle that can be used to refer to the loaded objects (for /// symbol searching, finalization, freeing memory, etc.). - template <typename ObjSetT, - typename MemoryManagerPtrT, + template <typename MemoryManagerPtrT, typename SymbolResolverPtrT> - ObjSetHandleT addObjectSet(ObjSetT Objects, - MemoryManagerPtrT MemMgr, - SymbolResolverPtrT Resolver) { - auto Finalizer = [&](ObjSetHandleT H, RuntimeDyld &RTDyld, - const ObjSetT &Objs, - std::function<void()> LOSHandleLoad) { - LoadedObjInfoList LoadedObjInfos; + ObjHandleT addObject(ObjectPtr Obj, + MemoryManagerPtrT MemMgr, + SymbolResolverPtrT Resolver) { - for (auto &Obj : Objs) - LoadedObjInfos.push_back(RTDyld.loadObject(this->getObject(*Obj))); + auto Finalizer = [&](ObjHandleT H, RuntimeDyld &RTDyld, + const ObjectPtr &ObjToLoad, + std::function<void()> LOSHandleLoad) { + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> Info = + RTDyld.loadObject(*ObjToLoad->getBinary()); LOSHandleLoad(); - this->NotifyLoaded(H, Objs, LoadedObjInfos); + if (this->NotifyLoaded) + this->NotifyLoaded(H, ObjToLoad, *Info); RTDyld.finalizeWithMemoryManagerLocking(); @@ -277,17 +274,15 @@ public: this->NotifyFinalized(H); }; - auto LOS = - createLinkedObjectSet(std::move(Objects), std::move(MemMgr), - std::move(Resolver), std::move(Finalizer), - ProcessAllSections); + auto LO = + createLinkedObject(std::move(Obj), std::move(MemMgr), std::move(Resolver), + std::move(Finalizer), ProcessAllSections); // LOS is an owning-ptr. Keep a non-owning one so that we can set the handle // below. - auto *LOSPtr = LOS.get(); + auto *LOPtr = LO.get(); - ObjSetHandleT Handle = LinkedObjSetList.insert(LinkedObjSetList.end(), - std::move(LOS)); - LOSPtr->setHandle(Handle); + ObjHandleT Handle = LinkedObjList.insert(LinkedObjList.end(), std::move(LO)); + LOPtr->setHandle(Handle); return Handle; } @@ -300,9 +295,9 @@ public: /// indirectly) will result in undefined behavior. If dependence tracking is /// required to detect or resolve such issues it should be added at a higher /// layer. - void removeObjectSet(ObjSetHandleT H) { + void removeObject(ObjHandleT H) { // How do we invalidate the symbols in H? - LinkedObjSetList.erase(H); + LinkedObjList.erase(H); } /// @brief Search for the given named symbol. @@ -310,7 +305,7 @@ public: /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it exists. JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) { - for (auto I = LinkedObjSetList.begin(), E = LinkedObjSetList.end(); I != E; + for (auto I = LinkedObjList.begin(), E = LinkedObjList.end(); I != E; ++I) if (auto Symbol = findSymbolIn(I, Name, ExportedSymbolsOnly)) return Symbol; @@ -325,13 +320,13 @@ public: /// @param ExportedSymbolsOnly If true, search only for exported symbols. /// @return A handle for the given named symbol, if it is found in the /// given object set. - JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name, + JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) { return (*H)->getSymbol(Name, ExportedSymbolsOnly); } /// @brief Map section addresses for the objects associated with the handle H. - void mapSectionAddress(ObjSetHandleT H, const void *LocalAddress, + void mapSectionAddress(ObjHandleT H, const void *LocalAddress, JITTargetAddress TargetAddr) { (*H)->mapSectionAddress(LocalAddress, TargetAddr); } @@ -339,25 +334,16 @@ public: /// @brief Immediately emit and finalize the object set represented by the /// given handle. /// @param H Handle for object set to emit/finalize. - void emitAndFinalize(ObjSetHandleT H) { + void emitAndFinalize(ObjHandleT H) { (*H)->finalize(); } private: - static const object::ObjectFile& getObject(const object::ObjectFile &Obj) { - return Obj; - } - - template <typename ObjT> - static const object::ObjectFile& - getObject(const object::OwningBinary<ObjT> &Obj) { - return *Obj.getBinary(); - } - LinkedObjectSetListT LinkedObjSetList; + LinkedObjectListT LinkedObjList; NotifyLoadedFtor NotifyLoaded; NotifyFinalizedFtor NotifyFinalized; - bool ProcessAllSections; + bool ProcessAllSections = false; }; } // end namespace orc diff --git a/include/llvm/ExecutionEngine/Orc/RawByteChannel.h b/include/llvm/ExecutionEngine/Orc/RawByteChannel.h index 52a546f7c6eb9..db810f4ef2e53 100644 --- a/include/llvm/ExecutionEngine/Orc/RawByteChannel.h +++ b/include/llvm/ExecutionEngine/Orc/RawByteChannel.h @@ -10,20 +10,14 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H #define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H -#include "OrcError.h" -#include "RPCSerialization.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/Orc/RPCSerialization.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" -#include <cstddef> #include <cstdint> #include <mutex> #include <string> -#include <tuple> #include <type_traits> -#include <vector> namespace llvm { namespace orc { @@ -32,7 +26,7 @@ namespace rpc { /// Interface for byte-streams to be used with RPC. class RawByteChannel { public: - virtual ~RawByteChannel() {} + virtual ~RawByteChannel() = default; /// Read Size bytes from the stream into *Dst. virtual Error readBytes(char *Dst, unsigned Size) = 0; diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index 9470866dc0d6f..1925489f79528 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -1,4 +1,4 @@ -//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===// +//===- RuntimeDyld.h - Run-time dynamic linker for MC-JIT -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -32,7 +32,9 @@ namespace llvm { namespace object { - template <typename T> class OwningBinary; + +template <typename T> class OwningBinary; + } // end namespace object /// Base class for errors originating in RuntimeDyld, e.g. missing relocation @@ -51,8 +53,8 @@ private: std::string ErrMsg; }; -class RuntimeDyldImpl; class RuntimeDyldCheckerImpl; +class RuntimeDyldImpl; class RuntimeDyld { friend class RuntimeDyldCheckerImpl; @@ -68,7 +70,7 @@ public: friend class RuntimeDyldImpl; public: - typedef std::map<object::SectionRef, unsigned> ObjSectionToIDMap; + using ObjSectionToIDMap = std::map<object::SectionRef, unsigned>; LoadedObjectInfo(RuntimeDyldImpl &RTDyld, ObjSectionToIDMap ObjSecToIDMap) : RTDyld(RTDyld), ObjSecToIDMap(std::move(ObjSecToIDMap)) {} @@ -186,7 +188,7 @@ public: /// \brief Construct a RuntimeDyld instance. RuntimeDyld(MemoryManager &MemMgr, JITSymbolResolver &Resolver); RuntimeDyld(const RuntimeDyld &) = delete; - void operator=(const RuntimeDyld &) = delete; + RuntimeDyld &operator=(const RuntimeDyld &) = delete; ~RuntimeDyld(); /// Add the referenced object file to the list of objects to be loaded and diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 0e8adda82cbe7..0cab8bbb8eade 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -622,7 +622,8 @@ public: // AttributeList Introspection //===--------------------------------------------------------------------===// - typedef const AttributeSet *iterator; + using iterator = const AttributeSet *; + iterator begin() const; iterator end() const; @@ -830,8 +831,8 @@ bool areInlineCompatible(const Function &Caller, const Function &Callee); /// \brief Merge caller's and callee's attributes. void mergeAttributesForInlining(Function &Caller, const Function &Callee); -} // end AttributeFuncs namespace +} // end namespace AttributeFuncs -} // end llvm namespace +} // end namespace llvm #endif // LLVM_IR_ATTRIBUTES_H diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td index 75867a6e58335..616387816bf81 100644 --- a/include/llvm/IR/Attributes.td +++ b/include/llvm/IR/Attributes.td @@ -214,3 +214,5 @@ def : MergeRule<"setAND<UnsafeFPMathAttr>">; def : MergeRule<"setOR<NoImplicitFloatAttr>">; def : MergeRule<"setOR<NoJumpTablesAttr>">; def : MergeRule<"adjustCallerSSPLevel">; +def : MergeRule<"adjustCallerStackProbes">; +def : MergeRule<"adjustCallerStackProbeSize">; diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index 23f838b640e0b..7a35afcbafc3c 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -1,4 +1,4 @@ -//===-- llvm/BasicBlock.h - Represent a basic block in the VM ---*- C++ -*-===// +//===- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,13 +18,17 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Value.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include <cassert> #include <cstddef> +#include <iterator> namespace llvm { @@ -294,9 +298,9 @@ public: return *this; } }; - typedef phi_iterator_impl<> phi_iterator; - typedef phi_iterator_impl<const PHINode, BasicBlock::const_iterator> - const_phi_iterator; + using phi_iterator = phi_iterator_impl<>; + using const_phi_iterator = + phi_iterator_impl<const PHINode, BasicBlock::const_iterator>; /// Returns a range that iterates over the phis in the basic block. /// @@ -391,6 +395,9 @@ public: static_cast<const BasicBlock *>(this)->getLandingPadInst()); } + /// \brief Return true if it is legal to hoist instructions into this block. + bool isLegalToHoistInto() const; + private: /// \brief Increment the internal refcount of the number of BlockAddresses /// referencing this BasicBlock by \p Amt. diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index 6a50a8801f86f..ff6495e7f0757 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -34,11 +34,14 @@ #include "llvm/ADT/APInt.h" #include "llvm/IR/InstrTypes.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/Support/Compiler.h" +#include <cstdint> namespace llvm { class MDNode; +class raw_ostream; /// This class represents a range of values. class LLVM_NODISCARD ConstantRange { @@ -330,6 +333,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) { /// E.g. if RangeMD is !{i32 0, i32 10, i32 15, i32 20} then return [0, 20). ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD); -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_CONSTANTRANGE_H diff --git a/include/llvm/IR/DerivedUser.h b/include/llvm/IR/DerivedUser.h index 4d681e0db6111..67c483d3c4977 100644 --- a/include/llvm/IR/DerivedUser.h +++ b/include/llvm/IR/DerivedUser.h @@ -1,4 +1,4 @@ -//===-- DerivedUser.h - Base for non-IR Users -------------------*- C++ -*-===// +//===- DerivedUser.h - Base for non-IR Users --------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,6 +14,9 @@ namespace llvm { +class Type; +class Use; + /// Extension point for the Value hierarchy. All classes outside of lib/IR /// that wish to inherit from User should instead inherit from DerivedUser /// instead. Inheriting from this class is discouraged. @@ -24,10 +27,11 @@ namespace llvm { /// its use/def list machinery. class DerivedUser : public User { protected: - typedef void (*DeleteValueTy)(DerivedUser *); + using DeleteValueTy = void (*)(DerivedUser *); private: - friend Value; + friend class Value; + DeleteValueTy DeleteValue; public: @@ -36,6 +40,6 @@ public: : User(Ty, VK, U, NumOps), DeleteValue(DeleteValue) {} }; -} // namespace llvm +} // end namespace llvm #endif // LLVM_IR_DERIVEDUSER_H diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index b3c6644c7e811..76524b4124560 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -322,14 +322,14 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) //===----------------------------------------------------------------------===// class BinaryOperator : public Instruction { + void AssertOK(); + protected: BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); - void init(BinaryOps iType); - // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h index 00c431834e314..d8db29e158867 100644 --- a/include/llvm/IR/Instruction.h +++ b/include/llvm/IR/Instruction.h @@ -152,9 +152,14 @@ public: return getOpcode() == AShr; } + /// Determine if the Opcode is and/or/xor. + static inline bool isBitwiseLogicOp(unsigned Opcode) { + return Opcode == And || Opcode == Or || Opcode == Xor; + } + /// Return true if this is and/or/xor. inline bool isBitwiseLogicOp() const { - return getOpcode() == And || getOpcode() == Or || getOpcode() == Xor; + return isBitwiseLogicOp(getOpcode()); } /// Determine if the OpCode is one of the CastInst instructions. diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index b3032f54aa424..e1620b3e7df53 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1243,6 +1243,16 @@ public: /// vectors of floating point values. The operands must be identical types. /// Represents a floating point comparison operator. class FCmpInst: public CmpInst { + void AssertOK() { + assert(getPredicate() <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + assert(getOperand(0)->getType() == getOperand(1)->getType() && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(getOperand(0)->getType()->isFPOrFPVectorTy() && + "Invalid operand types for FCmp instruction"); + } + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -1261,13 +1271,7 @@ public: ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS, RHS, NameStr, InsertBefore) { - assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && - "Invalid FCmp predicate value"); - assert(getOperand(0)->getType() == getOperand(1)->getType() && - "Both operands to FCmp instruction are not of the same type!"); - // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVectorTy() && - "Invalid operand types for FCmp instruction"); + AssertOK(); } /// Constructor with insert-at-end semantics. @@ -1280,13 +1284,7 @@ public: ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS, RHS, NameStr, &InsertAtEnd) { - assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && - "Invalid FCmp predicate value"); - assert(getOperand(0)->getType() == getOperand(1)->getType() && - "Both operands to FCmp instruction are not of the same type!"); - // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVectorTy() && - "Invalid operand types for FCmp instruction"); + AssertOK(); } /// Constructor with no-insertion semantics @@ -1297,13 +1295,7 @@ public: const Twine &NameStr = "" ///< Name of the instruction ) : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS, RHS, NameStr) { - assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && - "Invalid FCmp predicate value"); - assert(getOperand(0)->getType() == getOperand(1)->getType() && - "Both operands to FCmp instruction are not of the same type!"); - // Check that the operands are the right type - assert(getOperand(0)->getType()->isFPOrFPVectorTy() && - "Invalid operand types for FCmp instruction"); + AssertOK(); } /// @returns true if the predicate of this instruction is EQ or NE. diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 8017223c4ab00..4e0529a32d29d 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -475,6 +475,33 @@ class AMDGPUBufferStore : Intrinsic < def int_amdgcn_buffer_store_format : AMDGPUBufferStore; def int_amdgcn_buffer_store : AMDGPUBufferStore; +def int_amdgcn_tbuffer_load : Intrinsic < + [llvm_any_ty], // overloaded for types f32/i32, v2f32/v2i32, v4f32/v4i32 + [llvm_v4i32_ty, // rsrc(SGPR) + llvm_i32_ty, // vindex(VGPR) + llvm_i32_ty, // voffset(VGPR) + llvm_i32_ty, // soffset(SGPR) + llvm_i32_ty, // offset(imm) + llvm_i32_ty, // dfmt(imm) + llvm_i32_ty, // nfmt(imm) + llvm_i1_ty, // glc(imm) + llvm_i1_ty], // slc(imm) + []>; + +def int_amdgcn_tbuffer_store : Intrinsic < + [], + [llvm_any_ty, // vdata(VGPR), overloaded for types f32/i32, v2f32/v2i32, v4f32/v4i32 + llvm_v4i32_ty, // rsrc(SGPR) + llvm_i32_ty, // vindex(VGPR) + llvm_i32_ty, // voffset(VGPR) + llvm_i32_ty, // soffset(SGPR) + llvm_i32_ty, // offset(imm) + llvm_i32_ty, // dfmt(imm) + llvm_i32_ty, // nfmt(imm) + llvm_i1_ty, // glc(imm) + llvm_i1_ty], // slc(imm) + []>; + class AMDGPUBufferAtomic : Intrinsic < [llvm_i32_ty], [llvm_i32_ty, // vdata(VGPR) diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td index 1c466e73eb1bb..80c528768dc7f 100644 --- a/include/llvm/IR/IntrinsicsX86.td +++ b/include/llvm/IR/IntrinsicsX86.td @@ -5420,86 +5420,6 @@ let TargetPrefix = "x86" in { def int_x86_avx512_vcomi_ss : GCCBuiltin<"__builtin_ia32_vcomiss">, Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_cmp_b_512: - Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty, - llvm_i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_w_512: - Intrinsic<[llvm_i32_ty], [llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_d_512: - Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem ]>; - def int_x86_avx512_mask_cmp_q_512: - Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_ucmp_b_512: - Intrinsic<[llvm_i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty, - llvm_i64_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_w_512: - Intrinsic<[llvm_i32_ty], [llvm_v32i16_ty, llvm_v32i16_ty, llvm_i32_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_d_512: - Intrinsic<[llvm_i16_ty], [llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_q_512: - Intrinsic<[llvm_i8_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - // 256-bit - def int_x86_avx512_mask_cmp_b_256: - Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_w_256: - Intrinsic<[llvm_i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_d_256: - Intrinsic<[llvm_i8_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_q_256: - Intrinsic<[llvm_i8_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_ucmp_b_256: - Intrinsic<[llvm_i32_ty], [llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty, - llvm_i32_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_w_256: - Intrinsic<[llvm_i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_d_256: - Intrinsic<[llvm_i8_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_q_256: - Intrinsic<[llvm_i8_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - // 128-bit - def int_x86_avx512_mask_cmp_b_128: - Intrinsic<[llvm_i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_w_128: - Intrinsic<[llvm_i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_d_128: - Intrinsic<[llvm_i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_cmp_q_128: - Intrinsic<[llvm_i8_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - - def int_x86_avx512_mask_ucmp_b_128: - Intrinsic<[llvm_i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i16_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_w_128: - Intrinsic<[llvm_i8_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_d_128: - Intrinsic<[llvm_i8_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx512_mask_ucmp_q_128: - Intrinsic<[llvm_i8_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty, - llvm_i8_ty], [IntrNoMem]>; } // Compress, Expand diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h index d538c2595393e..80ed44be43eba 100644 --- a/include/llvm/IR/Metadata.h +++ b/include/llvm/IR/Metadata.h @@ -45,6 +45,8 @@ namespace llvm { class Module; class ModuleSlotTracker; +class raw_ostream; +class Type; enum LLVMConstants : uint32_t { DEBUG_METADATA_VERSION = 3 // Current debug info version number. @@ -67,8 +69,8 @@ protected: unsigned char Storage; // TODO: expose remaining bits to subclasses. - unsigned short SubclassData16; - unsigned SubclassData32; + unsigned short SubclassData16 = 0; + unsigned SubclassData32 = 0; public: enum MetadataKind { @@ -78,7 +80,7 @@ public: protected: Metadata(unsigned ID, StorageType Storage) - : SubclassID(ID), Storage(Storage), SubclassData16(0), SubclassData32(0) { + : SubclassID(ID), Storage(Storage) { static_assert(sizeof(*this) == 8, "Metadata fields poorly packed"); } @@ -183,6 +185,7 @@ public: static MetadataAsValue *get(LLVMContext &Context, Metadata *MD); static MetadataAsValue *getIfExists(LLVMContext &Context, Metadata *MD); + Metadata *getMetadata() const { return MD; } static bool classof(const Value *V) { @@ -257,7 +260,7 @@ public: /// \brief Check whether metadata is replaceable. static bool isReplaceable(const Metadata &MD); - typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy; + using OwnerTy = PointerUnion<MetadataAsValue *, Metadata *>; private: /// \brief Track a reference to metadata for an owner. @@ -275,7 +278,7 @@ class ReplaceableMetadataImpl { friend class MetadataTracking; public: - typedef MetadataTracking::OwnerTy OwnerTy; + using OwnerTy = MetadataTracking::OwnerTy; private: LLVMContext &Context; @@ -352,17 +355,21 @@ protected: public: static ValueAsMetadata *get(Value *V); + static ConstantAsMetadata *getConstant(Value *C) { return cast<ConstantAsMetadata>(get(C)); } + static LocalAsMetadata *getLocal(Value *Local) { return cast<LocalAsMetadata>(get(Local)); } static ValueAsMetadata *getIfExists(Value *V); + static ConstantAsMetadata *getConstantIfExists(Value *C) { return cast_or_null<ConstantAsMetadata>(getIfExists(C)); } + static LocalAsMetadata *getLocalIfExists(Value *Local) { return cast_or_null<LocalAsMetadata>(getIfExists(Local)); } @@ -491,8 +498,8 @@ namespace detail { template <class T> T &make(); template <class T, class Result> struct HasDereference { - typedef char Yes[1]; - typedef char No[2]; + using Yes = char[1]; + using No = char[2]; template <size_t N> struct SFINAE {}; template <class U, class V> @@ -613,7 +620,7 @@ public: unsigned getLength() const { return (unsigned)getString().size(); } - typedef StringRef::iterator iterator; + using iterator = StringRef::iterator; /// \brief Pointer to the first byte of the string. iterator begin() const { return getString().begin(); } @@ -730,12 +737,14 @@ private: }; template <> struct simplify_type<MDOperand> { - typedef Metadata *SimpleType; + using SimpleType = Metadata *; + static SimpleType getSimplifiedValue(MDOperand &MD) { return MD.get(); } }; template <> struct simplify_type<const MDOperand> { - typedef Metadata *SimpleType; + using SimpleType = Metadata *; + static SimpleType getSimplifiedValue(const MDOperand &MD) { return MD.get(); } }; @@ -817,7 +826,7 @@ struct TempMDNodeDeleter { }; #define HANDLE_MDNODE_LEAF(CLASS) \ - typedef std::unique_ptr<CLASS, TempMDNodeDeleter> Temp##CLASS; + using Temp##CLASS = std::unique_ptr<CLASS, TempMDNodeDeleter>; #define HANDLE_MDNODE_BRANCH(CLASS) HANDLE_MDNODE_LEAF(CLASS) #include "llvm/IR/Metadata.def" @@ -847,6 +856,10 @@ class MDNode : public Metadata { ContextAndReplaceableUses Context; protected: + MDNode(LLVMContext &Context, unsigned ID, StorageType Storage, + ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None); + ~MDNode() = default; + void *operator new(size_t Size, unsigned NumOps); void operator delete(void *Mem); @@ -860,16 +873,13 @@ protected: llvm_unreachable("Constructor throws?"); } - MDNode(LLVMContext &Context, unsigned ID, StorageType Storage, - ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2 = None); - ~MDNode() = default; - void dropAllReferences(); MDOperand *mutable_begin() { return mutable_end() - NumOperands; } MDOperand *mutable_end() { return reinterpret_cast<MDOperand *>(this); } - typedef iterator_range<MDOperand *> mutable_op_range; + using mutable_op_range = iterator_range<MDOperand *>; + mutable_op_range mutable_operands() { return mutable_op_range(mutable_begin(), mutable_end()); } @@ -1028,8 +1038,8 @@ private: static void dispatchResetHash(NodeTy *, std::false_type) {} public: - typedef const MDOperand *op_iterator; - typedef iterator_range<op_iterator> op_range; + using op_iterator = const MDOperand *; + using op_range = iterator_range<op_iterator>; op_iterator op_begin() const { return const_cast<MDNode *>(this)->mutable_begin(); @@ -1227,13 +1237,14 @@ public: T *operator[](unsigned I) const { return cast_or_null<T>(N->getOperand(I)); } // FIXME: Fix callers and remove condition on N. - typedef TypedMDOperandIterator<T> iterator; + using iterator = TypedMDOperandIterator<T>; + iterator begin() const { return N ? iterator(N->op_begin()) : iterator(); } iterator end() const { return N ? iterator(N->op_end()) : iterator(); } }; #define HANDLE_METADATA(CLASS) \ - typedef MDTupleTypedArrayWrapper<CLASS> CLASS##Array; + using CLASS##Array = MDTupleTypedArrayWrapper<CLASS>; #include "llvm/IR/Metadata.def" /// Placeholder metadata for operands of distinct MDNodes. @@ -1304,12 +1315,12 @@ class NamedMDNode : public ilist_node<NamedMDNode> { template<class T1, class T2> class op_iterator_impl : public std::iterator<std::bidirectional_iterator_tag, T2> { + friend class NamedMDNode; + const NamedMDNode *Node = nullptr; unsigned Idx = 0; - op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) { } - - friend class NamedMDNode; + op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) {} public: op_iterator_impl() = default; @@ -1371,11 +1382,13 @@ public: // --------------------------------------------------------------------------- // Operand Iterator interface... // - typedef op_iterator_impl<MDNode *, MDNode> op_iterator; + using op_iterator = op_iterator_impl<MDNode *, MDNode>; + op_iterator op_begin() { return op_iterator(this, 0); } op_iterator op_end() { return op_iterator(this, getNumOperands()); } - typedef op_iterator_impl<const MDNode *, MDNode> const_op_iterator; + using const_op_iterator = op_iterator_impl<const MDNode *, MDNode>; + const_op_iterator op_begin() const { return const_op_iterator(this, 0); } const_op_iterator op_end() const { return const_op_iterator(this, getNumOperands()); } diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h index 8950c527cc181..5d7b8b997d37b 100644 --- a/include/llvm/IR/ModuleSummaryIndexYAML.h +++ b/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -188,7 +188,7 @@ template <> struct MappingTraits<FunctionSummaryYaml> { LLVM_YAML_IS_STRING_MAP(TypeIdSummary) LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) -LLVM_YAML_IS_SEQUENCE_VECTOR(std::string) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string) namespace llvm { namespace yaml { diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 6eb5998478c65..c7f4697e93e74 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -328,8 +328,15 @@ public: return I->getType()->isFPOrFPVectorTy() || I->getOpcode() == Instruction::FCmp; } + + static inline bool classof(const ConstantExpr *CE) { + return CE->getType()->isFPOrFPVectorTy() || + CE->getOpcode() == Instruction::FCmp; + } + static inline bool classof(const Value *V) { - return isa<Instruction>(V) && classof(cast<Instruction>(V)); + return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || + (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); } }; diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 015a17e8e7ca5..9e9c8ac75d2a8 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -167,10 +167,8 @@ inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() { struct match_nan { template <typename ITy> bool match(ITy *V) { - if (const auto *C = dyn_cast<ConstantFP>(V)) { - const APFloat &APF = C->getValueAPF(); - return APF.isNaN(); - } + if (const auto *C = dyn_cast<ConstantFP>(V)) + return C->isNaN(); return false; } }; @@ -419,7 +417,8 @@ inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } //===----------------------------------------------------------------------===// // Matcher for any binary operator. // -template <typename LHS_t, typename RHS_t> struct AnyBinaryOp_match { +template <typename LHS_t, typename RHS_t, bool Commutable = false> +struct AnyBinaryOp_match { LHS_t L; RHS_t R; @@ -427,7 +426,9 @@ template <typename LHS_t, typename RHS_t> struct AnyBinaryOp_match { template <typename OpTy> bool match(OpTy *V) { if (auto *I = dyn_cast<BinaryOperator>(V)) - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || + (Commutable && R.match(I->getOperand(0)) && + L.match(I->getOperand(1))); return false; } }; @@ -441,7 +442,8 @@ inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) { // Matchers for specific binary operators. // -template <typename LHS_t, typename RHS_t, unsigned Opcode> +template <typename LHS_t, typename RHS_t, unsigned Opcode, + bool Commutable = false> struct BinaryOp_match { LHS_t L; RHS_t R; @@ -451,11 +453,15 @@ struct BinaryOp_match { template <typename OpTy> bool match(OpTy *V) { if (V->getValueID() == Value::InstructionVal + Opcode) { auto *I = cast<BinaryOperator>(V); - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); + return (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || + (Commutable && R.match(I->getOperand(0)) && + L.match(I->getOperand(1))); } if (auto *CE = dyn_cast<ConstantExpr>(V)) - return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && - R.match(CE->getOperand(1)); + return CE->getOpcode() == Opcode && + ((L.match(CE->getOperand(0)) && R.match(CE->getOperand(1))) || + (Commutable && R.match(CE->getOperand(0)) && + L.match(CE->getOperand(1)))); return false; } }; @@ -660,47 +666,87 @@ m_NUWShl(const LHS &L, const RHS &R) { } //===----------------------------------------------------------------------===// -// Class that matches two different binary ops. +// Class that matches a group of binary opcodes. // -template <typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2> -struct BinOp2_match { +template <typename LHS_t, typename RHS_t, typename Predicate> +struct BinOpPred_match : Predicate { LHS_t L; RHS_t R; - BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} + BinOpPred_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} template <typename OpTy> bool match(OpTy *V) { - if (V->getValueID() == Value::InstructionVal + Opc1 || - V->getValueID() == Value::InstructionVal + Opc2) { - auto *I = cast<BinaryOperator>(V); - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); - } + if (auto *I = dyn_cast<Instruction>(V)) + return this->isOpType(I->getOpcode()) && L.match(I->getOperand(0)) && + R.match(I->getOperand(1)); if (auto *CE = dyn_cast<ConstantExpr>(V)) - return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) && - L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); + return this->isOpType(CE->getOpcode()) && L.match(CE->getOperand(0)) && + R.match(CE->getOperand(1)); return false; } }; -/// \brief Matches LShr or AShr. +struct is_shift_op { + bool isOpType(unsigned Opcode) { return Instruction::isShift(Opcode); } +}; + +struct is_right_shift_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::LShr || Opcode == Instruction::AShr; + } +}; + +struct is_logical_shift_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::LShr || Opcode == Instruction::Shl; + } +}; + +struct is_bitwiselogic_op { + bool isOpType(unsigned Opcode) { + return Instruction::isBitwiseLogicOp(Opcode); + } +}; + +struct is_idiv_op { + bool isOpType(unsigned Opcode) { + return Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; + } +}; + +/// \brief Matches shift operations. template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr> -m_Shr(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R); +inline BinOpPred_match<LHS, RHS, is_shift_op> m_Shift(const LHS &L, + const RHS &R) { + return BinOpPred_match<LHS, RHS, is_shift_op>(L, R); } -/// \brief Matches LShr or Shl. +/// \brief Matches logical shift operations. template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl> +inline BinOpPred_match<LHS, RHS, is_right_shift_op> m_Shr(const LHS &L, + const RHS &R) { + return BinOpPred_match<LHS, RHS, is_right_shift_op>(L, R); +} + +/// \brief Matches logical shift operations. +template <typename LHS, typename RHS> +inline BinOpPred_match<LHS, RHS, is_logical_shift_op> m_LogicalShift(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R); + return BinOpPred_match<LHS, RHS, is_logical_shift_op>(L, R); } -/// \brief Matches UDiv and SDiv. +/// \brief Matches bitwise logic operations. template <typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv> -m_IDiv(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R); +inline BinOpPred_match<LHS, RHS, is_bitwiselogic_op> +m_BitwiseLogic(const LHS &L, const RHS &R) { + return BinOpPred_match<LHS, RHS, is_bitwiselogic_op>(L, R); +} + +/// \brief Matches integer division operations. +template <typename LHS, typename RHS> +inline BinOpPred_match<LHS, RHS, is_idiv_op> m_IDiv(const LHS &L, + const RHS &R) { + return BinOpPred_match<LHS, RHS, is_idiv_op>(L, R); } //===----------------------------------------------------------------------===// @@ -726,7 +772,8 @@ template <typename T> inline Exact_match<T> m_Exact(const T &SubPattern) { // Matchers for CmpInst classes // -template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy> +template <typename LHS_t, typename RHS_t, typename Class, typename PredicateTy, + bool Commutable = false> struct CmpClass_match { PredicateTy &Predicate; LHS_t L; @@ -737,7 +784,9 @@ struct CmpClass_match { template <typename OpTy> bool match(OpTy *V) { if (auto *I = dyn_cast<Class>(V)) - if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { + if ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) || + (Commutable && R.match(I->getOperand(0)) && + L.match(I->getOperand(1)))) { Predicate = I->getPredicate(); return true; } @@ -897,10 +946,7 @@ template <typename LHS_t> struct not_match { private: bool isAllOnes(Value *V) { - return (isa<ConstantInt>(V) || isa<ConstantDataVector>(V) || - // FIXME: Remove CV. - isa<ConstantVector>(V)) && - cast<Constant>(V)->isAllOnesValue(); + return isa<Constant>(V) && cast<Constant>(V)->isAllOnesValue(); } }; @@ -1002,7 +1048,8 @@ inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) { // Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). // -template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t> +template <typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t, + bool Commutable = false> struct MaxMin_match { LHS_t L; RHS_t R; @@ -1032,7 +1079,8 @@ struct MaxMin_match { if (!Pred_t::match(Pred)) return false; // It does! Bind the operands. - return L.match(LHS) && R.match(RHS); + return (L.match(LHS) && R.match(RHS)) || + (Commutable && R.match(LHS) && L.match(RHS)); } }; @@ -1376,89 +1424,78 @@ template <typename Val_t> inline Signum_match<Val_t> m_Signum(const Val_t &V) { // /// \brief Matches a BinaryOperator with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<AnyBinaryOp_match<LHS, RHS>, - AnyBinaryOp_match<RHS, LHS>> -m_c_BinOp(const LHS &L, const RHS &R) { - return m_CombineOr(m_BinOp(L, R), m_BinOp(R, L)); +template <typename LHS, typename RHS> +inline AnyBinaryOp_match<LHS, RHS, true> m_c_BinOp(const LHS &L, const RHS &R) { + return AnyBinaryOp_match<LHS, RHS, true>(L, R); } /// \brief Matches an ICmp with a predicate over LHS and RHS in either order. /// Does not swap the predicate. -template<typename LHS, typename RHS> -inline match_combine_or<CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>, - CmpClass_match<RHS, LHS, ICmpInst, ICmpInst::Predicate>> +template <typename LHS, typename RHS> +inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true> m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) { - return m_CombineOr(m_ICmp(Pred, L, R), m_ICmp(Pred, R, L)); + return CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>(Pred, L, + R); } /// \brief Matches a Add with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Add>, - BinaryOp_match<RHS, LHS, Instruction::Add>> -m_c_Add(const LHS &L, const RHS &R) { - return m_CombineOr(m_Add(L, R), m_Add(R, L)); +template <typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::Add, true> m_c_Add(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::Add, true>(L, R); } /// \brief Matches a Mul with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Mul>, - BinaryOp_match<RHS, LHS, Instruction::Mul>> -m_c_Mul(const LHS &L, const RHS &R) { - return m_CombineOr(m_Mul(L, R), m_Mul(R, L)); +template <typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::Mul, true> m_c_Mul(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::Mul, true>(L, R); } /// \brief Matches an And with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::And>, - BinaryOp_match<RHS, LHS, Instruction::And>> -m_c_And(const LHS &L, const RHS &R) { - return m_CombineOr(m_And(L, R), m_And(R, L)); +template <typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::And, true> m_c_And(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::And, true>(L, R); } /// \brief Matches an Or with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Or>, - BinaryOp_match<RHS, LHS, Instruction::Or>> -m_c_Or(const LHS &L, const RHS &R) { - return m_CombineOr(m_Or(L, R), m_Or(R, L)); +template <typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::Or, true> m_c_Or(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::Or, true>(L, R); } /// \brief Matches an Xor with LHS and RHS in either order. -template<typename LHS, typename RHS> -inline match_combine_or<BinaryOp_match<LHS, RHS, Instruction::Xor>, - BinaryOp_match<RHS, LHS, Instruction::Xor>> -m_c_Xor(const LHS &L, const RHS &R) { - return m_CombineOr(m_Xor(L, R), m_Xor(R, L)); +template <typename LHS, typename RHS> +inline BinaryOp_match<LHS, RHS, Instruction::Xor, true> m_c_Xor(const LHS &L, + const RHS &R) { + return BinaryOp_match<LHS, RHS, Instruction::Xor, true>(L, R); } /// Matches an SMin with LHS and RHS in either order. template <typename LHS, typename RHS> -inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>, - MaxMin_match<ICmpInst, RHS, LHS, smin_pred_ty>> +inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true> m_c_SMin(const LHS &L, const RHS &R) { - return m_CombineOr(m_SMin(L, R), m_SMin(R, L)); + return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty, true>(L, R); } /// Matches an SMax with LHS and RHS in either order. template <typename LHS, typename RHS> -inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>, - MaxMin_match<ICmpInst, RHS, LHS, smax_pred_ty>> +inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true> m_c_SMax(const LHS &L, const RHS &R) { - return m_CombineOr(m_SMax(L, R), m_SMax(R, L)); + return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty, true>(L, R); } /// Matches a UMin with LHS and RHS in either order. template <typename LHS, typename RHS> -inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>, - MaxMin_match<ICmpInst, RHS, LHS, umin_pred_ty>> +inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true> m_c_UMin(const LHS &L, const RHS &R) { - return m_CombineOr(m_UMin(L, R), m_UMin(R, L)); + return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty, true>(L, R); } /// Matches a UMax with LHS and RHS in either order. template <typename LHS, typename RHS> -inline match_combine_or<MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>, - MaxMin_match<ICmpInst, RHS, LHS, umax_pred_ty>> +inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true> m_c_UMax(const LHS &L, const RHS &R) { - return m_CombineOr(m_UMax(L, R), m_UMax(R, L)); + return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty, true>(L, R); } } // end namespace PatternMatch diff --git a/include/llvm/IR/Statepoint.h b/include/llvm/IR/Statepoint.h index 265e7eb348bfb..630f30667272a 100644 --- a/include/llvm/IR/Statepoint.h +++ b/include/llvm/IR/Statepoint.h @@ -62,7 +62,10 @@ bool isStatepoint(const Value *V); bool isStatepoint(const Value &V); bool isGCRelocate(ImmutableCallSite CS); +bool isGCRelocate(const Value *V); + bool isGCResult(ImmutableCallSite CS); +bool isGCResult(const Value *V); /// Analogous to CallSiteBase, this provides most of the actual /// functionality for Statepoint and ImmutableStatepoint. It is diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index ccd40e5765841..9e4914973edf9 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -49,8 +49,9 @@ template<typename ValueTy> class StringMapEntry; class StringRef; class Twine; class Type; +class User; -using ValueName = StringMapEntry<Value*>; +using ValueName = StringMapEntry<Value *>; //===----------------------------------------------------------------------===// // Value Class @@ -212,7 +213,7 @@ protected: public: Value(const Value &) = delete; - void operator=(const Value &) = delete; + Value &operator=(const Value &) = delete; /// Delete a pointer to a generic Value. void deleteValue(); @@ -660,7 +661,7 @@ struct ValueDeleter { void operator()(Value *V) { V->deleteValue(); } }; /// Use this instead of std::unique_ptr<Value> or std::unique_ptr<Instruction>. /// Those don't work because Value and Instruction's destructors are protected, /// aren't virtual, and won't destroy the complete object. -typedef std::unique_ptr<Value, ValueDeleter> unique_value; +using unique_value = std::unique_ptr<Value, ValueDeleter>; inline raw_ostream &operator<<(raw_ostream &OS, const Value &V) { V.print(OS); diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index abb0aa3e3caf5..a52fa3b542a58 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -192,7 +192,6 @@ void initializeLiveRangeShrinkPass(PassRegistry&); void initializeLiveRegMatrixPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&); -void initializeLoadCombinePass(PassRegistry&); void initializeLoadStoreVectorizerPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&); void initializeLocalStackSlotPassPass(PassRegistry&); diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index f9545333aabdf..14f0c48266f0b 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -177,7 +177,7 @@ public: */ void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) { if (Percentage) - CacheOptions.Policy.PercentageOfAvailableSpace = Percentage; + CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage; } /**@}*/ diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h index fb21e195b1dfe..a270973204f29 100644 --- a/include/llvm/MC/MCAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -63,19 +63,16 @@ public: /// Target hook to adjust the literal value of a fixup if necessary. /// IsResolved signals whether the caller believes a relocation is needed; the /// target can modify the value. The default does nothing. - virtual void processFixupValue(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFixup &Fixup, const MCFragment *DF, - const MCValue &Target, uint64_t &Value, - bool &IsResolved) {} + virtual void processFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, bool &IsResolved) {} /// Apply the \p Value for given \p Fixup into the provided data fragment, at /// the offset specified by the fixup and following the fixup kind as /// appropriate. Errors (such as an out of range fixup value) should be /// reported via \p Ctx. - virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, - uint64_t Value, bool IsPCRel, - MCContext &Ctx) const = 0; + virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, + const MCValue &Target, MutableArrayRef<char> Data, + uint64_t Value, bool IsPCRel) const = 0; /// @} diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 63f7057a7076f..4f1b5a8b3d72e 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -195,8 +195,8 @@ private: /// finishLayout - Finalize a layout, including fragment lowering. void finishLayout(MCAsmLayout &Layout); - std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout, - MCFragment &F, const MCFixup &Fixup); + std::tuple<MCValue, uint64_t, bool> + handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup); public: /// Construct a new assembler instance. @@ -413,7 +413,7 @@ public: /// @} - void dump(); + void dump() const; }; /// \brief Compute the amount of padding required before the fragment \p F to diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index 0aca922e3cf58..284ca50e19d5b 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -130,7 +130,7 @@ public: /// \brief Return true if given frgment has FT_Dummy type. bool isDummy() const { return Kind == FT_Dummy; } - void dump(); + void dump() const; }; class MCDummyFragment : public MCFragment { diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index cc306d47250d4..2771b1e67eaba 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -167,7 +167,7 @@ public: MCSection::iterator getSubsectionInsertionPoint(unsigned Subsection); - void dump(); + void dump() const; virtual void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, raw_ostream &OS, diff --git a/include/llvm/MC/MCSymbolWasm.h b/include/llvm/MC/MCSymbolWasm.h index 1b87095552d6b..7ea89629efda6 100644 --- a/include/llvm/MC/MCSymbolWasm.h +++ b/include/llvm/MC/MCSymbolWasm.h @@ -17,6 +17,7 @@ namespace llvm { class MCSymbolWasm : public MCSymbol { private: bool IsFunction = false; + bool IsWeak = false; std::string ModuleName; SmallVector<wasm::ValType, 1> Returns; SmallVector<wasm::ValType, 4> Params; @@ -39,6 +40,9 @@ public: bool isFunction() const { return IsFunction; } void setIsFunction(bool isFunc) { IsFunction = isFunc; } + bool isWeak() const { return IsWeak; } + void setWeak(bool isWeak) { IsWeak = isWeak; } + const StringRef getModuleName() const { return ModuleName; } const SmallVector<wasm::ValType, 1> &getReturns() const { return Returns; } diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index ead08fd90ca06..aa1eaf022c555 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -42,7 +42,7 @@ class MCValue { int64_t Cst; uint32_t RefKind; public: - + MCValue() : SymA(nullptr), SymB(nullptr), Cst(0), RefKind(0) {} int64_t getConstant() const { return Cst; } const MCSymbolRefExpr *getSymA() const { return SymA; } const MCSymbolRefExpr *getSymB() const { return SymB; } diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h index 57bed213aad47..6e14cefaa0abc 100644 --- a/include/llvm/MC/MCWinCOFFObjectWriter.h +++ b/include/llvm/MC/MCWinCOFFObjectWriter.h @@ -30,8 +30,8 @@ class raw_pwrite_stream; virtual ~MCWinCOFFObjectTargetWriter() = default; unsigned getMachine() const { return Machine; } - virtual unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup, - bool IsCrossSection, + virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, + const MCFixup &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const = 0; virtual bool recordRelocation(const MCFixup &) const { return true; } }; diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index ae695a529597b..bf0172822d3fc 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -562,8 +562,26 @@ struct coff_tls_directory { using coff_tls_directory32 = coff_tls_directory<support::little32_t>; using coff_tls_directory64 = coff_tls_directory<support::little64_t>; +/// Bits in control flow guard flags as we understand them. +enum class coff_guard_flags : uint32_t { + CFInstrumented = 0x00000100, + HasFidTable = 0x00000400, + ProtectDelayLoadIAT = 0x00001000, + DelayLoadIATSection = 0x00002000, // Delay load in separate section + HasLongJmpTable = 0x00010000, + FidTableHasFlags = 0x10000000, // Indicates that fid tables are 5 bytes +}; + +struct coff_load_config_code_integrity { + support::ulittle16_t Flags; + support::ulittle16_t Catalog; + support::ulittle32_t CatalogOffset; + support::ulittle32_t Reserved; +}; + +/// 32-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY32) struct coff_load_configuration32 { - support::ulittle32_t Characteristics; + support::ulittle32_t Size; support::ulittle32_t TimeDateStamp; support::ulittle16_t MajorVersion; support::ulittle16_t MinorVersion; @@ -578,34 +596,81 @@ struct coff_load_configuration32 { support::ulittle32_t ProcessAffinityMask; support::ulittle32_t ProcessHeapFlags; support::ulittle16_t CSDVersion; - support::ulittle16_t Reserved; + support::ulittle16_t DependentLoadFlags; support::ulittle32_t EditList; support::ulittle32_t SecurityCookie; support::ulittle32_t SEHandlerTable; support::ulittle32_t SEHandlerCount; + + // Added in MSVC 2015 for /guard:cf. + support::ulittle32_t GuardCFCheckFunction; + support::ulittle32_t GuardCFCheckDispatch; + support::ulittle32_t GuardCFFunctionTable; + support::ulittle32_t GuardCFFunctionCount; + support::ulittle32_t GuardFlags; // coff_guard_flags + + // Added in MSVC 2017 + coff_load_config_code_integrity CodeIntegrity; + support::ulittle32_t GuardAddressTakenIatEntryTable; + support::ulittle32_t GuardAddressTakenIatEntryCount; + support::ulittle32_t GuardLongJumpTargetTable; + support::ulittle32_t GuardLongJumpTargetCount; + support::ulittle32_t DynamicValueRelocTable; + support::ulittle32_t CHPEMetadataPointer; + support::ulittle32_t GuardRFFailureRoutine; + support::ulittle32_t GuardRFFailureRoutineFunctionPointer; + support::ulittle32_t DynamicValueRelocTableOffset; + support::ulittle16_t DynamicValueRelocTableSection; + support::ulittle16_t Reserved2; + support::ulittle32_t GuardRFVerifyStackPointerFunctionPointer; + support::ulittle32_t HotPatchTableOffset; }; +/// 64-bit load config (IMAGE_LOAD_CONFIG_DIRECTORY64) struct coff_load_configuration64 { - support::ulittle32_t Characteristics; + support::ulittle32_t Size; support::ulittle32_t TimeDateStamp; support::ulittle16_t MajorVersion; support::ulittle16_t MinorVersion; support::ulittle32_t GlobalFlagsClear; support::ulittle32_t GlobalFlagsSet; support::ulittle32_t CriticalSectionDefaultTimeout; - support::ulittle32_t DeCommitFreeBlockThreshold; - support::ulittle32_t DeCommitTotalFreeThreshold; - support::ulittle32_t LockPrefixTable; - support::ulittle32_t MaximumAllocationSize; - support::ulittle32_t VirtualMemoryThreshold; - support::ulittle32_t ProcessAffinityMask; + support::ulittle64_t DeCommitFreeBlockThreshold; + support::ulittle64_t DeCommitTotalFreeThreshold; + support::ulittle64_t LockPrefixTable; + support::ulittle64_t MaximumAllocationSize; + support::ulittle64_t VirtualMemoryThreshold; + support::ulittle64_t ProcessAffinityMask; support::ulittle32_t ProcessHeapFlags; support::ulittle16_t CSDVersion; - support::ulittle16_t Reserved; - support::ulittle32_t EditList; + support::ulittle16_t DependentLoadFlags; + support::ulittle64_t EditList; support::ulittle64_t SecurityCookie; support::ulittle64_t SEHandlerTable; support::ulittle64_t SEHandlerCount; + + // Added in MSVC 2015 for /guard:cf. + support::ulittle64_t GuardCFCheckFunction; + support::ulittle64_t GuardCFCheckDispatch; + support::ulittle64_t GuardCFFunctionTable; + support::ulittle64_t GuardCFFunctionCount; + support::ulittle32_t GuardFlags; + + // Added in MSVC 2017 + coff_load_config_code_integrity CodeIntegrity; + support::ulittle64_t GuardAddressTakenIatEntryTable; + support::ulittle64_t GuardAddressTakenIatEntryCount; + support::ulittle64_t GuardLongJumpTargetTable; + support::ulittle64_t GuardLongJumpTargetCount; + support::ulittle64_t DynamicValueRelocTable; + support::ulittle64_t CHPEMetadataPointer; + support::ulittle64_t GuardRFFailureRoutine; + support::ulittle64_t GuardRFFailureRoutineFunctionPointer; + support::ulittle32_t DynamicValueRelocTableOffset; + support::ulittle16_t DynamicValueRelocTableSection; + support::ulittle16_t Reserved2; + support::ulittle64_t GuardRFVerifyStackPointerFunctionPointer; + support::ulittle32_t HotPatchTableOffset; }; struct coff_runtime_function_x64 { @@ -684,6 +749,8 @@ private: const coff_base_reloc_block_header *BaseRelocEnd; const debug_directory *DebugDirectoryBegin; const debug_directory *DebugDirectoryEnd; + // Either coff_load_configuration32 or coff_load_configuration64. + const void *LoadConfig; std::error_code getString(uint32_t offset, StringRef &Res) const; @@ -698,6 +765,7 @@ private: std::error_code initExportTablePtr(); std::error_code initBaseRelocPtr(); std::error_code initDebugDirectoryPtr(); + std::error_code initLoadConfigPtr(); public: uintptr_t getSymbolTable() const { @@ -775,6 +843,16 @@ public: return getRawNumberOfSymbols(); } + const coff_load_configuration32 *getLoadConfig32() const { + assert(!is64()); + return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig); + } + + const coff_load_configuration64 *getLoadConfig64() const { + assert(is64()); + return reinterpret_cast<const coff_load_configuration64 *>(LoadConfig); + } + protected: void moveSymbolNext(DataRefImpl &Symb) const override; Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; diff --git a/include/llvm/Object/IRSymtab.h b/include/llvm/Object/IRSymtab.h index 5b832141a8651..502f133d307dd 100644 --- a/include/llvm/Object/IRSymtab.h +++ b/include/llvm/Object/IRSymtab.h @@ -38,6 +38,7 @@ namespace llvm { struct BitcodeFileContents; +class StringTableBuilder; namespace irsymtab { @@ -136,9 +137,10 @@ struct Header { } // end namespace storage -/// Fills in Symtab and Strtab with a valid symbol and string table for Mods. +/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for +/// Mods. Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab, - SmallVector<char, 0> &Strtab); + StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc); /// This represents a symbol that has been read from a storage::Symbol and /// possibly a storage::Uncommon. diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 3fc726f4ccb8e..2c3c89d10546f 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -304,6 +304,12 @@ public: relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; + relocation_iterator extrel_begin() const; + relocation_iterator extrel_end() const; + iterator_range<relocation_iterator> external_relocations() const { + return make_range(extrel_begin(), extrel_end()); + } + void moveRelocationNext(DataRefImpl &Rel) const override; uint64_t getRelocationOffset(DataRefImpl Rel) const override; symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 10edc461b9e9c..9d53131234f43 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -19,6 +19,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/Object/Binary.h" #include "llvm/Object/ObjectFile.h" @@ -48,7 +49,24 @@ public: StringRef Name; SymbolType Type; uint32_t Section; + uint32_t Flags = 0; + + // Index into the imports, exports or functions array of the object depending + // on the type uint32_t ElementIndex; + + bool isWeak() const { + return Flags & wasm::WASM_SYMBOL_FLAG_WEAK; + } + + void print(raw_ostream &Out) const { + Out << "Name=" << Name << ", Type=" << static_cast<int>(Type) + << ", Flags=" << Flags; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + LLVM_DUMP_METHOD void dump() const { print(dbgs()); } +#endif }; class WasmSection { @@ -63,6 +81,7 @@ public: }; class WasmObjectFile : public ObjectFile { + public: WasmObjectFile(MemoryBufferRef Object, Error &Err); @@ -176,6 +195,7 @@ private: // Custom section types Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); + Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End); Error parseRelocSection(StringRef Name, const uint8_t *Ptr, const uint8_t *End); @@ -190,13 +210,22 @@ private: std::vector<wasm::WasmExport> Exports; std::vector<wasm::WasmElemSegment> ElemSegments; std::vector<wasm::WasmDataSegment> DataSegments; - std::vector<WasmSymbol> Symbols; std::vector<wasm::WasmFunction> Functions; + std::vector<WasmSymbol> Symbols; ArrayRef<uint8_t> CodeSection; uint32_t StartFunction = -1; + + StringMap<uint32_t> SymbolMap; }; } // end namespace object + +inline raw_ostream &operator<<(raw_ostream &OS, + const object::WasmSymbol &Sym) { + Sym.print(OS); + return OS; +} + } // end namespace llvm #endif // LLVM_OBJECT_WASM_H diff --git a/include/llvm/Object/WindowsResource.h b/include/llvm/Object/WindowsResource.h index 4839013c8228c..3d32409fd4aca 100644 --- a/include/llvm/Object/WindowsResource.h +++ b/include/llvm/Object/WindowsResource.h @@ -30,7 +30,6 @@ #define LLVM_INCLUDE_LLVM_OBJECT_RESFILE_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/Object/Binary.h" #include "llvm/Object/Error.h" @@ -44,14 +43,47 @@ #include <map> namespace llvm { - -class FileOutputBuffer; - namespace object { class WindowsResource; -enum class Machine { UNKNOWN, ARM, X64, X86 }; +const size_t WIN_RES_MAGIC_SIZE = 16; +const size_t WIN_RES_NULL_ENTRY_SIZE = 16; +const uint32_t WIN_RES_HEADER_ALIGNMENT = 4; +const uint32_t WIN_RES_DATA_ALIGNMENT = 4; +const uint16_t WIN_RES_PURE_MOVEABLE = 0x0030; + +struct WinResHeaderPrefix { + support::ulittle32_t DataSize; + support::ulittle32_t HeaderSize; +}; + +// Type and Name may each either be an integer ID or a string. This struct is +// only used in the case where they are both IDs. +struct WinResIDs { + uint16_t TypeFlag; + support::ulittle16_t TypeID; + uint16_t NameFlag; + support::ulittle16_t NameID; + + void setType(uint16_t ID) { + TypeFlag = 0xffff; + TypeID = ID; + } + + void setName(uint16_t ID) { + NameFlag = 0xffff; + NameID = ID; + } +}; + +struct WinResHeaderSuffix { + support::ulittle32_t DataVersion; + support::ulittle16_t MemoryFlags; + support::ulittle16_t Language; + support::ulittle32_t Version; + support::ulittle32_t Characteristics; +}; class ResourceEntryRef { public: @@ -76,14 +108,6 @@ private: Error loadNext(); - struct HeaderSuffix { - support::ulittle32_t DataVersion; - support::ulittle16_t MemoryFlags; - support::ulittle16_t Language; - support::ulittle32_t Version; - support::ulittle32_t Characteristics; - }; - BinaryStreamReader Reader; bool IsStringType; ArrayRef<UTF16> Type; @@ -91,7 +115,7 @@ private: bool IsStringName; ArrayRef<UTF16> Name; uint16_t NameID; - const HeaderSuffix *Suffix = nullptr; + const WinResHeaderSuffix *Suffix = nullptr; ArrayRef<uint8_t> Data; const WindowsResource *OwningRes = nullptr; }; @@ -185,8 +209,9 @@ private: std::vector<std::vector<UTF16>> StringTable; }; -Error writeWindowsResourceCOFF(StringRef OutputFile, Machine MachineType, - const WindowsResourceParser &Parser); +Expected<std::unique_ptr<MemoryBuffer>> +writeWindowsResourceCOFF(llvm::COFF::MachineTypes MachineType, + const WindowsResourceParser &Parser); } // namespace object } // namespace llvm diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index 447dbd7a603da..74f5664c43ac7 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -112,8 +112,13 @@ struct Signature { ValueType ReturnType; }; +struct SymbolInfo { + StringRef Name; + uint32_t Flags; +}; + struct Section { - Section(SectionType SecType) : Type(SecType) {} + explicit Section(SectionType SecType) : Type(SecType) {} virtual ~Section(); SectionType Type; @@ -121,20 +126,36 @@ struct Section { }; struct CustomSection : Section { - CustomSection() : Section(wasm::WASM_SEC_CUSTOM) {} + explicit CustomSection(StringRef Name) + : Section(wasm::WASM_SEC_CUSTOM), Name(Name) {} static bool classof(const Section *S) { return S->Type == wasm::WASM_SEC_CUSTOM; } StringRef Name; yaml::BinaryRef Payload; +}; + +struct NameSection : CustomSection { + NameSection() : CustomSection("name") {} + static bool classof(const Section *S) { + auto C = dyn_cast<CustomSection>(S); + return C && C->Name == "name"; + } - // The follow is used by the "name" custom section. - // TODO(sbc): Add support for more then just functions names. The wasm - // name section can support multiple sub-sections. std::vector<NameEntry> FunctionNames; }; +struct LinkingSection : CustomSection { + LinkingSection() : CustomSection("linking") {} + static bool classof(const Section *S) { + auto C = dyn_cast<CustomSection>(S); + return C && C->Name == "linking"; + } + + std::vector<SymbolInfo> SymbolInfos; +}; + struct TypeSection : Section { TypeSection() : Section(wasm::WASM_SEC_TYPE) {} static bool classof(const Section *S) { @@ -256,6 +277,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo) LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t) namespace llvm { @@ -329,6 +351,10 @@ template <> struct MappingTraits<WasmYAML::ElemSegment> { static void mapping(IO &IO, WasmYAML::ElemSegment &Segment); }; +template <> struct MappingTraits<WasmYAML::SymbolInfo> { + static void mapping(IO &IO, WasmYAML::SymbolInfo &Info); +}; + template <> struct ScalarEnumerationTraits<WasmYAML::ValueType> { static void enumeration(IO &IO, WasmYAML::ValueType &Type); }; diff --git a/include/llvm/Option/OptParser.td b/include/llvm/Option/OptParser.td index 4da86f09750db..481223698719b 100644 --- a/include/llvm/Option/OptParser.td +++ b/include/llvm/Option/OptParser.td @@ -92,6 +92,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> { int NumArgs = 0; string HelpText = ?; string MetaVarName = ?; + string Values = ?; list<OptionFlag> Flags = []; OptionGroup Group = ?; Option Alias = ?; @@ -126,6 +127,7 @@ class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; } class Group<OptionGroup group> { OptionGroup Group = group; } class HelpText<string text> { string HelpText = text; } class MetaVarName<string name> { string MetaVarName = name; } +class Values<string value> { string Values = value; } // Predefined options. diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h index e0169b927319f..3e7b019a0d4ea 100644 --- a/include/llvm/Option/OptTable.h +++ b/include/llvm/Option/OptTable.h @@ -53,6 +53,7 @@ public: unsigned short GroupID; unsigned short AliasID; const char *AliasArgs; + const char *Values; }; private: @@ -120,6 +121,19 @@ public: return getInfo(id).MetaVar; } + /// Find possible value for given flags. This is used for shell + /// autocompletion. + /// + /// \param [in] Option - Key flag like "-stdlib=" when "-stdlib=l" + /// was passed to clang. + /// + /// \param [in] Arg - Value which we want to autocomplete like "l" + /// when "-stdlib=l" was passed to clang. + /// + /// \return The vector of possible values. + std::vector<std::string> suggestValueCompletions(StringRef Option, + StringRef Arg) const; + /// Find flags from OptTable which starts with Cur. /// /// \param [in] Cur - String prefix that all returned flags need diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h index c08834f90598a..d9aebd5b07570 100644 --- a/include/llvm/Option/Option.h +++ b/include/llvm/Option/Option.h @@ -57,6 +57,7 @@ public: UnknownClass, FlagClass, JoinedClass, + ValuesClass, SeparateClass, RemainingArgsClass, RemainingArgsJoinedClass, @@ -155,6 +156,7 @@ public: case CommaJoinedClass: return RenderCommaJoinedStyle; case FlagClass: + case ValuesClass: case SeparateClass: case MultiArgClass: case JoinedOrSeparateClass: diff --git a/include/llvm/ProfileData/Coverage/CoverageMapping.h b/include/llvm/ProfileData/Coverage/CoverageMapping.h index b2f73fda2bae6..0ba792e8dc43c 100644 --- a/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -411,9 +411,11 @@ public: std::vector<CoverageSegment>::const_iterator begin() const { return Segments.begin(); } + std::vector<CoverageSegment>::const_iterator end() const { return Segments.end(); } + bool empty() const { return Segments.empty(); } /// \brief Expansions that can be further processed. @@ -430,6 +432,7 @@ class CoverageMapping { unsigned MismatchedFunctionCount = 0; CoverageMapping() = default; + /// \brief Add a function record corresponding to \p Record. Error loadFunctionRecord(const CoverageMappingRecord &Record, IndexedInstrProfReader &ProfileReader); @@ -607,13 +610,13 @@ enum CovMapVersion { }; template <int CovMapVersion, class IntPtrT> struct CovMapTraits { - typedef CovMapFunctionRecord CovMapFuncRecordType; - typedef uint64_t NameRefType; + using CovMapFuncRecordType = CovMapFunctionRecord; + using NameRefType = uint64_t; }; template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> { - typedef CovMapFunctionRecordV1<IntPtrT> CovMapFuncRecordType; - typedef IntPtrT NameRefType; + using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>; + using NameRefType = IntPtrT; }; } // end namespace coverage @@ -622,6 +625,7 @@ template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> { template<> struct DenseMapInfo<coverage::CounterExpression> { static inline coverage::CounterExpression getEmptyKey() { using namespace coverage; + return CounterExpression(CounterExpression::ExprKind::Subtract, Counter::getCounter(~0U), Counter::getCounter(~0U)); @@ -629,6 +633,7 @@ template<> struct DenseMapInfo<coverage::CounterExpression> { static inline coverage::CounterExpression getTombstoneKey() { using namespace coverage; + return CounterExpression(CounterExpression::ExprKind::Add, Counter::getCounter(~0U), Counter::getCounter(~0U)); diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index 0dbb2cf9f2696..573ea90cfd00b 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -410,7 +410,7 @@ uint64_t ComputeHash(StringRef K); /// on how PGO name is formed. class InstrProfSymtab { public: - typedef std::vector<std::pair<uint64_t, uint64_t>> AddrHashMap; + using AddrHashMap = std::vector<std::pair<uint64_t, uint64_t>>; private: StringRef Data; @@ -450,11 +450,11 @@ public: /// decls from module \c M. This interface is used by transformation /// passes such as indirect function call promotion. Variable \c InLTO /// indicates if this is called from LTO optimization passes. - void create(Module &M, bool InLTO = false); + Error create(Module &M, bool InLTO = false); /// Create InstrProfSymtab from a set of names iteratable from /// \p IterRange. This interface is used by IndexedProfReader. - template <typename NameIterRange> void create(const NameIterRange &IterRange); + template <typename NameIterRange> Error create(const NameIterRange &IterRange); // If the symtab is created by a series of calls to \c addFuncName, \c // finalizeSymtab needs to be called before looking up function names. @@ -464,11 +464,14 @@ public: /// Update the symtab by adding \p FuncName to the table. This interface /// is used by the raw and text profile readers. - void addFuncName(StringRef FuncName) { + Error addFuncName(StringRef FuncName) { + if (FuncName.empty()) + return make_error<InstrProfError>(instrprof_error::malformed); auto Ins = NameTab.insert(FuncName); if (Ins.second) MD5NameMap.push_back(std::make_pair( IndexedInstrProf::ComputeHash(FuncName), Ins.first->getKey())); + return Error::success(); } /// Map a function address to its name's MD5 hash. This interface @@ -511,11 +514,13 @@ Error InstrProfSymtab::create(StringRef NameStrings) { } template <typename NameIterRange> -void InstrProfSymtab::create(const NameIterRange &IterRange) { +Error InstrProfSymtab::create(const NameIterRange &IterRange) { for (auto Name : IterRange) - addFuncName(Name); + if (Error E = addFuncName(Name)) + return E; finalizeSymtab(); + return Error::success(); } void InstrProfSymtab::finalizeSymtab() { @@ -594,7 +599,7 @@ struct InstrProfRecord { InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts) : Name(Name), Hash(Hash), Counts(std::move(Counts)) {} - typedef std::vector<std::pair<uint64_t, uint64_t>> ValueMapType; + using ValueMapType = std::vector<std::pair<uint64_t, uint64_t>>; /// Return the number of value profile kinds with non-zero number /// of profile sites. @@ -668,8 +673,8 @@ struct InstrProfRecord { private: std::vector<InstrProfValueSiteRecord> IndirectCallSites; std::vector<InstrProfValueSiteRecord> MemOPSizes; - const std::vector<InstrProfValueSiteRecord> & + const std::vector<InstrProfValueSiteRecord> & getValueSitesForKind(uint32_t ValueKind) const { switch (ValueKind) { case IPVK_IndirectCallTarget: @@ -873,6 +878,11 @@ struct Summary { // The number of Cutoff Entries (Summary::Entry) following summary fields. uint64_t NumCutoffEntries; + Summary() = delete; + Summary(uint32_t Size) { memset(this, 0, Size); } + + void operator delete(void *ptr) { ::operator delete(ptr); } + static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries) { return sizeof(Summary) + NumCutoffEntries * sizeof(Entry) + NumSumFields * sizeof(uint64_t); @@ -911,11 +921,6 @@ struct Summary { ER.MinBlockCount = E.MinCount; ER.NumBlocks = E.NumCounts; } - - Summary(uint32_t Size) { memset(this, 0, Size); } - void operator delete(void *ptr) { ::operator delete(ptr); } - - Summary() = delete; }; inline std::unique_ptr<Summary> allocSummary(uint32_t TotalSize) { diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h index 1d85a7149afc8..8163ca1592098 100644 --- a/include/llvm/ProfileData/InstrProfReader.h +++ b/include/llvm/ProfileData/InstrProfReader.h @@ -92,6 +92,7 @@ public: protected: std::unique_ptr<InstrProfSymtab> Symtab; + /// Set the current error and return same. Error error(instrprof_error Err) { LastError = Err; @@ -202,7 +203,7 @@ private: public: RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer) - : DataBuffer(std::move(DataBuffer)) { } + : DataBuffer(std::move(DataBuffer)) {} RawInstrProfReader(const RawInstrProfReader &) = delete; RawInstrProfReader &operator=(const RawInstrProfReader &) = delete; @@ -268,8 +269,8 @@ private: } }; -typedef RawInstrProfReader<uint32_t> RawInstrProfReader32; -typedef RawInstrProfReader<uint64_t> RawInstrProfReader64; +using RawInstrProfReader32 = RawInstrProfReader<uint32_t>; +using RawInstrProfReader64 = RawInstrProfReader<uint64_t>; namespace IndexedInstrProf { @@ -292,12 +293,12 @@ public: InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion) : HashType(HashType), FormatVersion(FormatVersion) {} - typedef ArrayRef<InstrProfRecord> data_type; + using data_type = ArrayRef<InstrProfRecord>; - typedef StringRef internal_key_type; - typedef StringRef external_key_type; - typedef uint64_t hash_value_type; - typedef uint64_t offset_type; + using internal_key_type = StringRef; + using external_key_type = StringRef; + using hash_value_type = uint64_t; + using offset_type = uint64_t; static bool EqualKey(StringRef A, StringRef B) { return A == B; } static StringRef GetInternalKey(StringRef K) { return K; } @@ -343,15 +344,14 @@ struct InstrProfReaderIndexBase { virtual void setValueProfDataEndianness(support::endianness Endianness) = 0; virtual uint64_t getVersion() const = 0; virtual bool isIRLevelProfile() const = 0; - virtual void populateSymtab(InstrProfSymtab &) = 0; + virtual Error populateSymtab(InstrProfSymtab &) = 0; }; -typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait> - OnDiskHashTableImplV3; +using OnDiskHashTableImplV3 = + OnDiskIterableChainedHashTable<InstrProfLookupTrait>; template <typename HashTableImpl> class InstrProfReaderIndex : public InstrProfReaderIndexBase { - private: std::unique_ptr<HashTableImpl> HashTable; typename HashTableImpl::data_iterator RecordIterator; @@ -383,8 +383,8 @@ public: return (FormatVersion & VARIANT_MASK_IR_PROF) != 0; } - void populateSymtab(InstrProfSymtab &Symtab) override { - Symtab.create(HashTable->keys()); + Error populateSymtab(InstrProfSymtab &Symtab) override { + return Symtab.create(HashTable->keys()); } }; diff --git a/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h index 10742c0228ebe..fff10af30295a 100644 --- a/include/llvm/ProfileData/InstrProfWriter.h +++ b/include/llvm/ProfileData/InstrProfWriter.h @@ -29,10 +29,11 @@ namespace llvm { /// Writer for instrumentation based profile data. class InstrProfRecordWriterTrait; class ProfOStream; +class raw_fd_ostream; class InstrProfWriter { public: - typedef SmallDenseMap<uint64_t, InstrProfRecord, 1> ProfilingData; + using ProfilingData = SmallDenseMap<uint64_t, InstrProfRecord, 1>; enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel }; private: @@ -58,7 +59,7 @@ public: void write(raw_fd_ostream &OS); /// Write the profile in text format to \c OS - void writeText(raw_fd_ostream &OS); + Error writeText(raw_fd_ostream &OS); /// Write \c Record in text format to \c OS static void writeRecordInText(const InstrProfRecord &Record, diff --git a/include/llvm/ProfileData/SampleProf.h b/include/llvm/ProfileData/SampleProf.h index 7a705ca5416da..7fc258831be88 100644 --- a/include/llvm/ProfileData/SampleProf.h +++ b/include/llvm/ProfileData/SampleProf.h @@ -125,7 +125,7 @@ raw_ostream &operator<<(raw_ostream &OS, const LineLocation &Loc); /// will be a list of one or more functions. class SampleRecord { public: - typedef StringMap<uint64_t> CallTargetMap; + using CallTargetMap = StringMap<uint64_t>; SampleRecord() = default; @@ -182,10 +182,11 @@ private: raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample); -typedef std::map<LineLocation, SampleRecord> BodySampleMap; class FunctionSamples; -typedef StringMap<FunctionSamples> FunctionSamplesMap; -typedef std::map<LineLocation, FunctionSamplesMap> CallsiteSampleMap; + +using BodySampleMap = std::map<LineLocation, SampleRecord>; +using FunctionSamplesMap = StringMap<FunctionSamples>; +using CallsiteSampleMap = std::map<LineLocation, FunctionSamplesMap>; /// Representation of the samples collected for a function. /// @@ -398,8 +399,8 @@ raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS); /// order of LocationT. template <class LocationT, class SampleT> class SampleSorter { public: - typedef std::pair<const LocationT, SampleT> SamplesWithLoc; - typedef SmallVector<const SamplesWithLoc *, 20> SamplesWithLocList; + using SamplesWithLoc = std::pair<const LocationT, SampleT>; + using SamplesWithLocList = SmallVector<const SamplesWithLoc *, 20>; SampleSorter(const std::map<LocationT, SampleT> &Samples) { for (const auto &I : Samples) diff --git a/include/llvm/ProfileData/SampleProfReader.h b/include/llvm/ProfileData/SampleProfReader.h index 29e3aba3e0e76..9c1f357cbbd16 100644 --- a/include/llvm/ProfileData/SampleProfReader.h +++ b/include/llvm/ProfileData/SampleProfReader.h @@ -350,7 +350,7 @@ public: class SampleProfileReaderBinary : public SampleProfileReader { public: SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C) - : SampleProfileReader(std::move(B), C), Data(nullptr), End(nullptr) {} + : SampleProfileReader(std::move(B), C) {} /// \brief Read and validate the file header. std::error_code readHeader() override; @@ -388,10 +388,10 @@ protected: std::error_code readProfile(FunctionSamples &FProfile); /// \brief Points to the current location in the buffer. - const uint8_t *Data; + const uint8_t *Data = nullptr; /// \brief Points to the end of the buffer. - const uint8_t *End; + const uint8_t *End = nullptr; /// Function name table. std::vector<StringRef> NameTable; @@ -403,7 +403,7 @@ private: std::error_code readSummary(); }; -typedef SmallVector<FunctionSamples *, 10> InlineCallStack; +using InlineCallStack = SmallVector<FunctionSamples *, 10>; // Supported histogram types in GCC. Currently, we only need support for // call target histograms. diff --git a/include/llvm/Support/BinaryStreamReader.h b/include/llvm/Support/BinaryStreamReader.h index 738c042add3e3..ae5ebb2c36286 100644 --- a/include/llvm/Support/BinaryStreamReader.h +++ b/include/llvm/Support/BinaryStreamReader.h @@ -137,6 +137,15 @@ public: /// returns an appropriate error code. Error readStreamRef(BinaryStreamRef &Ref, uint32_t Length); + /// Read \p Length bytes from the underlying stream into \p Stream. This is + /// equivalent to calling getUnderlyingStream().slice(Offset, Length). + /// Updates the stream's offset to point after the newly read object. Never + /// causes a copy. + /// + /// \returns a success error code if the data was successfully read, otherwise + /// returns an appropriate error code. + Error readSubstream(BinarySubstreamRef &Stream, uint32_t Size); + /// Get a pointer to an object of type T from the underlying stream, as if by /// memcpy, and store the result into \p Dest. It is up to the caller to /// ensure that objects of type T can be safely treated in this manner. diff --git a/include/llvm/Support/BinaryStreamRef.h b/include/llvm/Support/BinaryStreamRef.h index e3bd4bf0860e7..6d5135cb258dd 100644 --- a/include/llvm/Support/BinaryStreamRef.h +++ b/include/llvm/Support/BinaryStreamRef.h @@ -166,6 +166,28 @@ public: ArrayRef<uint8_t> &Buffer) const; }; +struct BinarySubstreamRef { + uint32_t Offset; // Offset in the parent stream + BinaryStreamRef StreamData; // Stream Data + + BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const { + BinaryStreamRef SubSub = StreamData.slice(Off, Size); + return {Off + Offset, SubSub}; + } + BinarySubstreamRef drop_front(uint32_t N) const { + return slice(N, size() - N); + } + BinarySubstreamRef keep_front(uint32_t N) const { return slice(0, N); } + + std::pair<BinarySubstreamRef, BinarySubstreamRef> + split(uint32_t Offset) const { + return std::make_pair(keep_front(Offset), drop_front(Offset)); + } + + uint32_t size() const { return StreamData.getLength(); } + bool empty() const { return size() == 0; } +}; + class WritableBinaryStreamRef : public BinaryStreamRefBase<WritableBinaryStreamRef, WritableBinaryStream> { diff --git a/include/llvm/Support/CachePruning.h b/include/llvm/Support/CachePruning.h index e826938878e50..46e34358573bf 100644 --- a/include/llvm/Support/CachePruning.h +++ b/include/llvm/Support/CachePruning.h @@ -39,8 +39,13 @@ struct CachePruningPolicy { /// available space on the the disk. Set to 100 to indicate no limit, 50 to /// indicate that the cache size will not be left over half the available disk /// space. A value over 100 will be reduced to 100. A value of 0 disables the - /// size-based pruning. - unsigned PercentageOfAvailableSpace = 75; + /// percentage size-based pruning. + unsigned MaxSizePercentageOfAvailableSpace = 75; + + /// The maximum size for the cache directory in bytes. A value over the amount + /// of available space on the disk will be reduced to the amount of available + /// space. A value of 0 disables the absolute size-based pruning. + uint64_t MaxSizeBytes = 0; }; /// Parse the given string as a cache pruning policy. Defaults are taken from a diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h index 380b628fd95ff..31447882a9196 100644 --- a/include/llvm/Support/DataExtractor.h +++ b/include/llvm/Support/DataExtractor.h @@ -14,6 +14,30 @@ #include "llvm/Support/DataTypes.h" namespace llvm { + +/// An auxiliary type to facilitate extraction of 3-byte entities. +struct Uint24 { + uint8_t Bytes[3]; + Uint24(uint8_t U) { + Bytes[0] = Bytes[1] = Bytes[2] = U; + } + Uint24(uint8_t U0, uint8_t U1, uint8_t U2) { + Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2; + } + uint32_t getAsUint32(bool IsLittleEndian) const { + int LoIx = IsLittleEndian ? 0 : 2; + return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16); + } +}; + +using uint24_t = Uint24; +static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3"); + +/// Needed by swapByteOrder(). +inline uint24_t getSwappedBytes(uint24_t C) { + return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]); +} + class DataExtractor { StringRef Data; uint8_t IsLittleEndian; @@ -236,6 +260,23 @@ public: /// NULL otherise. uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const; + /// Extract a 24-bit unsigned value from \a *offset_ptr and return it + /// in a uint32_t. + /// + /// Extract 3 bytes from the binary data at the offset pointed to by + /// \a offset_ptr, construct a uint32_t from them and update the offset + /// on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the 3 bytes if the value is extracted correctly. If the offset + /// is out of bounds or there are not enough bytes to extract this value, + /// the offset will be left unmodified. + /// + /// @return + /// The extracted 24-bit value represented in a uint32_t. + uint32_t getU24(uint32_t *offset_ptr) const; + /// Extract a uint32_t value from \a *offset_ptr. /// /// Extract a single uint32_t from the binary data at the offset diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h index 8e145c7b0b512..4ce65e7dc83c5 100644 --- a/include/llvm/Support/Errno.h +++ b/include/llvm/Support/Errno.h @@ -14,6 +14,7 @@ #ifndef LLVM_SUPPORT_ERRNO_H #define LLVM_SUPPORT_ERRNO_H +#include <cerrno> #include <string> namespace llvm { diff --git a/include/llvm/Support/Error.h b/include/llvm/Support/Error.h index 1e27e0b821f05..9a7fa0ae6356c 100644 --- a/include/llvm/Support/Error.h +++ b/include/llvm/Support/Error.h @@ -1076,6 +1076,27 @@ T cantFail(Expected<T> ValOrErr) { llvm_unreachable("Failure value returned from cantFail wrapped call"); } +/// Report a fatal error if ValOrErr is a failure value, otherwise unwraps and +/// returns the contained reference. +/// +/// This function can be used to wrap calls to fallible functions ONLY when it +/// is known that the Error will always be a success value. E.g. +/// +/// @code{.cpp} +/// // foo only attempts the fallible operation if DoFallibleOperation is +/// // true. If DoFallibleOperation is false then foo always returns a Bar&. +/// Expected<Bar&> foo(bool DoFallibleOperation); +/// +/// Bar &X = cantFail(foo(false)); +/// @endcode +template <typename T> +T& cantFail(Expected<T&> ValOrErr) { + if (ValOrErr) + return *ValOrErr; + else + llvm_unreachable("Failure value returned from cantFail wrapped call"); +} + } // end namespace llvm #endif // LLVM_SUPPORT_ERROR_H diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 268c53c50252f..02016e7dbd624 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -271,8 +271,8 @@ struct GCOVEdge { /// GCOVFunction - Collects function information. class GCOVFunction { public: - typedef pointee_iterator<SmallVectorImpl< - std::unique_ptr<GCOVBlock>>::const_iterator> BlockIterator; + using BlockIterator = pointee_iterator<SmallVectorImpl< + std::unique_ptr<GCOVBlock>>::const_iterator>; GCOVFunction(GCOVFile &P) : Parent(P) {} @@ -321,7 +321,7 @@ class GCOVBlock { }; public: - typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator; + using EdgeIterator = SmallVectorImpl<GCOVEdge *>::const_iterator; GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N) {} ~GCOVBlock(); @@ -381,10 +381,10 @@ class FileInfo { // Therefore this typedef allows LineData.Functions to store multiple // functions // per instance. This is rare, however, so optimize for the common case. - typedef SmallVector<const GCOVFunction *, 1> FunctionVector; - typedef DenseMap<uint32_t, FunctionVector> FunctionLines; - typedef SmallVector<const GCOVBlock *, 4> BlockVector; - typedef DenseMap<uint32_t, BlockVector> BlockLines; + using FunctionVector = SmallVector<const GCOVFunction *, 1>; + using FunctionLines = DenseMap<uint32_t, FunctionVector>; + using BlockVector = SmallVector<const GCOVBlock *, 4>; + using BlockLines = DenseMap<uint32_t, BlockVector>; struct LineData { LineData() = default; @@ -448,8 +448,8 @@ private: uint32_t RunCount = 0; uint32_t ProgramCount = 0; - typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> FileCoverageList; - typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap; + using FileCoverageList = SmallVector<std::pair<std::string, GCOVCoverage>, 4>; + using FuncCoverageMap = MapVector<const GCOVFunction *, GCOVCoverage>; FileCoverageList FileCoverages; FuncCoverageMap FuncCoverages; diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index 80a2dfcbad889..601633d41cff5 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -69,14 +69,13 @@ protected: : Roots(), IsPostDominators(isPostDom) {} DominatorBase(DominatorBase &&Arg) - : Roots(std::move(Arg.Roots)), - IsPostDominators(std::move(Arg.IsPostDominators)) { + : Roots(std::move(Arg.Roots)), IsPostDominators(Arg.IsPostDominators) { Arg.Roots.clear(); } DominatorBase &operator=(DominatorBase &&RHS) { Roots = std::move(RHS.Roots); - IsPostDominators = std::move(RHS.IsPostDominators); + IsPostDominators = RHS.IsPostDominators; RHS.Roots.clear(); return *this; } @@ -99,18 +98,17 @@ template <class NodeT> class DomTreeNodeBase { template <class N> friend class DominatorTreeBase; NodeT *TheBB; - DomTreeNodeBase<NodeT> *IDom; - std::vector<DomTreeNodeBase<NodeT> *> Children; - mutable int DFSNumIn = -1; - mutable int DFSNumOut = -1; + DomTreeNodeBase *IDom; + std::vector<DomTreeNodeBase *> Children; + mutable unsigned DFSNumIn = ~0; + mutable unsigned DFSNumOut = ~0; -public: - DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom) - : TheBB(BB), IDom(iDom) {} + public: + DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) : TheBB(BB), IDom(iDom) {} - typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator; - typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator - const_iterator; + using iterator = typename std::vector<DomTreeNodeBase *>::iterator; + using const_iterator = + typename std::vector<DomTreeNodeBase *>::const_iterator; iterator begin() { return Children.begin(); } iterator end() { return Children.end(); } @@ -118,14 +116,12 @@ public: const_iterator end() const { return Children.end(); } NodeT *getBlock() const { return TheBB; } - DomTreeNodeBase<NodeT> *getIDom() const { return IDom; } + DomTreeNodeBase *getIDom() const { return IDom; } - const std::vector<DomTreeNodeBase<NodeT> *> &getChildren() const { - return Children; - } + const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; } - std::unique_ptr<DomTreeNodeBase<NodeT>> - addChild(std::unique_ptr<DomTreeNodeBase<NodeT>> C) { + std::unique_ptr<DomTreeNodeBase> addChild( + std::unique_ptr<DomTreeNodeBase> C) { Children.push_back(C.get()); return C; } @@ -134,7 +130,7 @@ public: void clearAllChildren() { Children.clear(); } - bool compare(const DomTreeNodeBase<NodeT> *Other) const { + bool compare(const DomTreeNodeBase *Other) const { if (getNumChildren() != Other->getNumChildren()) return true; @@ -152,10 +148,10 @@ public: return false; } - void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { + void setIDom(DomTreeNodeBase *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { - typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I = + typename std::vector<DomTreeNodeBase *>::iterator I = find(IDom->Children, this); assert(I != IDom->Children.end() && "Not in immediate dominator children set!"); @@ -177,32 +173,32 @@ public: private: // Return true if this node is dominated by other. Use this only if DFS info // is valid. - bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const { + bool DominatedBy(const DomTreeNodeBase *other) const { return this->DFSNumIn >= other->DFSNumIn && this->DFSNumOut <= other->DFSNumOut; } }; template <class NodeT> -raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase<NodeT> *Node) { +raw_ostream &operator<<(raw_ostream &O, const DomTreeNodeBase<NodeT> *Node) { if (Node->getBlock()) - Node->getBlock()->printAsOperand(o, false); + Node->getBlock()->printAsOperand(O, false); else - o << " <<exit node>>"; + O << " <<exit node>>"; - o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; + O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; - return o << "\n"; + return O << "\n"; } template <class NodeT> -void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o, +void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &O, unsigned Lev) { - o.indent(2 * Lev) << "[" << Lev << "] " << N; + O.indent(2 * Lev) << "[" << Lev << "] " << N; for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(), E = N->end(); I != E; ++I) - PrintDomTree<NodeT>(*I, o, Lev + 1); + PrintDomTree<NodeT>(*I, O, Lev + 1); } // The calculate routine is provided in a separate header but referenced here. @@ -239,8 +235,8 @@ template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> { } protected: - typedef DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>> - DomTreeNodeMapType; + using DomTreeNodeMapType = + DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>; DomTreeNodeMapType DomTreeNodes; DomTreeNodeBase<NodeT> *RootNode; @@ -663,19 +659,18 @@ public: /// print - Convert to human readable form /// - void print(raw_ostream &o) const { - o << "=============================--------------------------------\n"; + void print(raw_ostream &O) const { + O << "=============================--------------------------------\n"; if (this->isPostDominator()) - o << "Inorder PostDominator Tree: "; + O << "Inorder PostDominator Tree: "; else - o << "Inorder Dominator Tree: "; + O << "Inorder Dominator Tree: "; if (!DFSInfoValid) - o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; - o << "\n"; + O << "DFSNumbers invalid: " << SlowQueries << " slow queries."; + O << "\n"; // The postdom tree can have a null root if there are no returns. - if (getRootNode()) - PrintDomTree<NodeT>(getRootNode(), o, 1); + if (getRootNode()) PrintDomTree<NodeT>(getRootNode(), O, 1); } protected: @@ -770,7 +765,7 @@ public: /// recalculate - compute a dominator tree for the given function template <class FT> void recalculate(FT &F) { - typedef GraphTraits<FT *> TraitsTy; + using TraitsTy = GraphTraits<FT *>; reset(); Vertex.push_back(nullptr); diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h index c1d757f3ab6a3..449c385bc86a0 100644 --- a/include/llvm/Support/GenericDomTreeConstruction.h +++ b/include/llvm/Support/GenericDomTreeConstruction.h @@ -35,10 +35,10 @@ namespace llvm { // converting the one argument insert calls. template <class NodeRef, class InfoType> struct df_iterator_dom_storage { public: - typedef DenseMap<NodeRef, InfoType> BaseSet; + using BaseSet = DenseMap<NodeRef, InfoType>; df_iterator_dom_storage(BaseSet &Storage) : Storage(Storage) {} - typedef typename BaseSet::iterator iterator; + using iterator = typename BaseSet::iterator; std::pair<iterator, bool> insert(NodeRef N) { return Storage.insert({N, InfoType()}); } @@ -101,20 +101,22 @@ template <class GraphT> typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef VIn, unsigned LastLinked) { + using NodePtr = typename GraphT::NodeRef; + auto &VInInfo = DT.Info[VIn]; if (VInInfo.DFSNum < LastLinked) return VIn; - SmallVector<typename GraphT::NodeRef, 32> Work; - SmallPtrSet<typename GraphT::NodeRef, 32> Visited; + SmallVector<NodePtr, 32> Work; + SmallPtrSet<NodePtr, 32> Visited; if (VInInfo.Parent >= LastLinked) Work.push_back(VIn); while (!Work.empty()) { - typename GraphT::NodeRef V = Work.back(); + NodePtr V = Work.back(); auto &VInfo = DT.Info[V]; - typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent]; + NodePtr VAncestor = DT.Vertex[VInfo.Parent]; // Process Ancestor first if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { @@ -128,8 +130,8 @@ typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, continue; auto &VAInfo = DT.Info[VAncestor]; - typename GraphT::NodeRef VAncestorLabel = VAInfo.Label; - typename GraphT::NodeRef VLabel = VInfo.Label; + NodePtr VAncestorLabel = VAInfo.Label; + NodePtr VLabel = VInfo.Label; if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) VInfo.Label = VAncestorLabel; VInfo.Parent = VAInfo.Parent; @@ -141,10 +143,11 @@ typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, template <class FuncT, class NodeT> void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, FuncT &F) { - typedef GraphTraits<NodeT> GraphT; - static_assert(std::is_pointer<typename GraphT::NodeRef>::value, + using GraphT = GraphTraits<NodeT>; + using NodePtr = typename GraphT::NodeRef; + static_assert(std::is_pointer<NodePtr>::value, "NodeRef should be pointer type"); - typedef typename std::remove_pointer<typename GraphT::NodeRef>::type NodeType; + using NodeType = typename std::remove_pointer<NodePtr>::type; unsigned N = 0; bool MultipleRoots = (DT.Roots.size() > 1); @@ -186,13 +189,13 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, Buckets[i] = i; for (unsigned i = N; i >= 2; --i) { - typename GraphT::NodeRef W = DT.Vertex[i]; + NodePtr W = DT.Vertex[i]; auto &WInfo = DT.Info[W]; // Step #2: Implicitly define the immediate dominator of vertices for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { - typename GraphT::NodeRef V = DT.Vertex[Buckets[j]]; - typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1); + NodePtr V = DT.Vertex[Buckets[j]]; + NodePtr U = Eval<GraphT>(DT, V, i + 1); DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; } @@ -219,17 +222,17 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, } if (N >= 1) { - typename GraphT::NodeRef Root = DT.Vertex[1]; + NodePtr Root = DT.Vertex[1]; for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { - typename GraphT::NodeRef V = DT.Vertex[Buckets[j]]; + NodePtr V = DT.Vertex[Buckets[j]]; DT.IDoms[V] = Root; } } // Step #4: Explicitly define the immediate dominator of each vertex for (unsigned i = 2; i <= N; ++i) { - typename GraphT::NodeRef W = DT.Vertex[i]; - typename GraphT::NodeRef &WIDom = DT.IDoms[W]; + NodePtr W = DT.Vertex[i]; + NodePtr &WIDom = DT.IDoms[W]; if (WIDom != DT.Vertex[DT.Info[W].Semi]) WIDom = DT.IDoms[WIDom]; } @@ -240,7 +243,7 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) // which postdominates all real exits if there are multiple exit blocks, or // an infinite loop. - typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr; + NodePtr Root = !MultipleRoots ? DT.Roots[0] : nullptr; DT.RootNode = (DT.DomTreeNodes[Root] = @@ -249,13 +252,13 @@ void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT, // Loop over all of the reachable blocks in the function... for (unsigned i = 2; i <= N; ++i) { - typename GraphT::NodeRef W = DT.Vertex[i]; + NodePtr W = DT.Vertex[i]; // Don't replace this with 'count', the insertion side effect is important if (DT.DomTreeNodes[W]) continue; // Haven't calculated this node yet? - typename GraphT::NodeRef ImmDom = DT.getIDom(W); + NodePtr ImmDom = DT.getIDom(W); assert(ImmDom || DT.DomTreeNodes[nullptr]); diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index c318fea536511..3df5c867f7d33 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -1,4 +1,4 @@ -//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===// +//===- llvm/Support/GraphWriter.h - Write graph to a .dot file --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -24,30 +24,40 @@ #define LLVM_SUPPORT_GRAPHWRITER_H #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/DOTGraphTraits.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstddef> +#include <iterator> +#include <string> +#include <type_traits> #include <vector> namespace llvm { namespace DOT { // Private functions... - std::string EscapeString(const std::string &Label); - /// \brief Get a color string for this node number. Simply round-robin selects - /// from a reasonable number of colors. - StringRef getColorString(unsigned NodeNumber); -} +std::string EscapeString(const std::string &Label); + +/// \brief Get a color string for this node number. Simply round-robin selects +/// from a reasonable number of colors. +StringRef getColorString(unsigned NodeNumber); + +} // end namespace DOT namespace GraphProgram { - enum Name { - DOT, - FDP, - NEATO, - TWOPI, - CIRCO - }; -} + +enum Name { + DOT, + FDP, + NEATO, + TWOPI, + CIRCO +}; + +} // end namespace GraphProgram bool DisplayGraph(StringRef Filename, bool wait = true, GraphProgram::Name program = GraphProgram::DOT); @@ -57,11 +67,11 @@ class GraphWriter { raw_ostream &O; const GraphType &G; - typedef DOTGraphTraits<GraphType> DOTTraits; - typedef GraphTraits<GraphType> GTraits; - typedef typename GTraits::NodeRef NodeRef; - typedef typename GTraits::nodes_iterator node_iterator; - typedef typename GTraits::ChildIteratorType child_iterator; + using DOTTraits = DOTGraphTraits<GraphType>; + using GTraits = GraphTraits<GraphType>; + using NodeRef = typename GTraits::NodeRef; + using node_iterator = typename GTraits::nodes_iterator; + using child_iterator = typename GTraits::ChildIteratorType; DOTTraits DTraits; static_assert(std::is_pointer<NodeRef>::value, @@ -346,6 +356,6 @@ void ViewGraph(const GraphType &G, const Twine &Name, DisplayGraph(Filename, false, Program); } -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_SUPPORT_GRAPHWRITER_H diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h index 89986fdae9713..be93dd99032e2 100644 --- a/include/llvm/Support/Host.h +++ b/include/llvm/Support/Host.h @@ -21,6 +21,16 @@ #include <endian.h> #elif defined(_AIX) #include <sys/machine.h> +#elif defined(__sun) +/* Solaris provides _BIG_ENDIAN/_LITTLE_ENDIAN selector in sys/types.h */ +#include <sys/types.h> +#define BIG_ENDIAN 4321 +#define LITTLE_ENDIAN 1234 +#if defined(_BIG_ENDIAN) +#define BYTE_ORDER BIG_ENDIAN +#else +#define BYTE_ORDER LITTLE_ENDIAN +#endif #else #if !defined(BYTE_ORDER) && !defined(LLVM_ON_WIN32) #include <machine/endian.h> diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h index 6ac51195519eb..e5979674cf1c7 100644 --- a/include/llvm/Support/Path.h +++ b/include/llvm/Support/Path.h @@ -17,6 +17,7 @@ #define LLVM_SUPPORT_PATH_H #include "llvm/ADT/Twine.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/DataTypes.h" #include <iterator> @@ -49,7 +50,8 @@ enum class Style { windows, posix, native }; /// C:\foo\bar => C:,/,foo,bar /// @endcode class const_iterator - : public std::iterator<std::input_iterator_tag, const StringRef> { + : public iterator_facade_base<const_iterator, std::input_iterator_tag, + const StringRef> { StringRef Path; ///< The entire path. StringRef Component; ///< The current component. Not necessarily in Path. size_t Position; ///< The iterators current position within Path. @@ -61,10 +63,8 @@ class const_iterator public: reference operator*() const { return Component; } - pointer operator->() const { return &Component; } const_iterator &operator++(); // preincrement bool operator==(const const_iterator &RHS) const; - bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); } /// @brief Difference in bytes between this and RHS. ptrdiff_t operator-(const const_iterator &RHS) const; @@ -76,7 +76,8 @@ public: /// \a path in reverse order. The traversal order is exactly reversed from that /// of \a const_iterator class reverse_iterator - : public std::iterator<std::input_iterator_tag, const StringRef> { + : public iterator_facade_base<reverse_iterator, std::input_iterator_tag, + const StringRef> { StringRef Path; ///< The entire path. StringRef Component; ///< The current component. Not necessarily in Path. size_t Position; ///< The iterators current position within Path. @@ -87,10 +88,8 @@ class reverse_iterator public: reference operator*() const { return Component; } - pointer operator->() const { return &Component; } reverse_iterator &operator++(); // preincrement bool operator==(const reverse_iterator &RHS) const; - bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); } /// @brief Difference in bytes between this and RHS. ptrdiff_t operator-(const reverse_iterator &RHS) const; diff --git a/include/llvm/Support/Solaris.h b/include/llvm/Support/Solaris/sys/regset.h index 88d83014c468b..6a69ebe718a19 100644 --- a/include/llvm/Support/Solaris.h +++ b/include/llvm/Support/Solaris/sys/regset.h @@ -1,4 +1,4 @@ -/*===- llvm/Support/Solaris.h ------------------------------------*- C++ -*-===* +/*===- llvm/Support/Solaris/sys/regset.h ------------------------*- C++ -*-===* * * The LLVM Compiler Infrastructure * @@ -7,24 +7,14 @@ * *===----------------------------------------------------------------------===* * - * This file contains portability fixes for Solaris hosts. + * This file works around excessive name space pollution from the system header + * on Solaris hosts. * *===----------------------------------------------------------------------===*/ -#ifndef LLVM_SUPPORT_SOLARIS_H -#define LLVM_SUPPORT_SOLARIS_H +#ifndef LLVM_SUPPORT_SOLARIS_SYS_REGSET_H -#include <sys/regset.h> -#include <sys/types.h> - -/* Solaris doesn't have endian.h. SPARC is the only supported big-endian ISA. */ -#define BIG_ENDIAN 4321 -#define LITTLE_ENDIAN 1234 -#if defined(__sparc) || defined(__sparc__) -#define BYTE_ORDER BIG_ENDIAN -#else -#define BYTE_ORDER LITTLE_ENDIAN -#endif +#include_next <sys/regset.h> #undef CS #undef DS diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 9e9a91b0abdab..90d6c084ee957 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -54,6 +54,7 @@ class MCSymbolizer; class MCTargetAsmParser; class MCTargetOptions; class MCTargetStreamer; +class raw_ostream; class raw_pwrite_stream; class TargetMachine; class TargetOptions; @@ -96,75 +97,75 @@ class Target { public: friend struct TargetRegistry; - typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch); + using ArchMatchFnTy = bool (*)(Triple::ArchType Arch); - typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, - const Triple &TT); - typedef void (*MCAdjustCodeGenOptsFnTy)(const Triple &TT, Reloc::Model RM, - CodeModel::Model &CM); + using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI, + const Triple &TT); + using MCAdjustCodeGenOptsFnTy = void (*)(const Triple &TT, Reloc::Model RM, + CodeModel::Model &CM); - typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); - typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo *Info); - typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(const Triple &TT); - typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(const Triple &TT, - StringRef CPU, - StringRef Features); - typedef TargetMachine *(*TargetMachineCtorTy)( + using MCInstrInfoCtorFnTy = MCInstrInfo *(*)(); + using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info); + using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT); + using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT, + StringRef CPU, + StringRef Features); + using TargetMachineCtorTy = TargetMachine *(*)( const Target &T, const Triple &TT, StringRef CPU, StringRef Features, const TargetOptions &Options, Optional<Reloc::Model> RM, CodeModel::Model CM, CodeGenOpt::Level OL); // If it weren't for layering issues (this header is in llvm/Support, but // depends on MC?) this should take the Streamer by value rather than rvalue // reference. - typedef AsmPrinter *(*AsmPrinterCtorTy)( + using AsmPrinterCtorTy = AsmPrinter *(*)( TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer); - typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, - const MCRegisterInfo &MRI, - const Triple &TT, StringRef CPU, - const MCTargetOptions &Options); - typedef MCTargetAsmParser *(*MCAsmParserCtorTy)( + using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T, + const MCRegisterInfo &MRI, + const Triple &TT, StringRef CPU, + const MCTargetOptions &Options); + using MCAsmParserCtorTy = MCTargetAsmParser *(*)( const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, const MCTargetOptions &Options); - typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, - const MCSubtargetInfo &STI, - MCContext &Ctx); - typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Triple &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI, - const MCInstrInfo &MII, - const MCRegisterInfo &MRI); - typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, - const MCRegisterInfo &MRI, - MCContext &Ctx); - typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx, - MCAsmBackend &TAB, - raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, - bool RelaxAll); - typedef MCStreamer *(*MachOStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB, - raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, - bool RelaxAll, - bool DWARFMustBeAtTheEnd); - typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB, - raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, - bool RelaxAll, - bool IncrementalLinkerCompatible); - typedef MCStreamer *(*WasmStreamerCtorTy)(const Triple &T, MCContext &Ctx, + using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T, + const MCSubtargetInfo &STI, + MCContext &Ctx); + using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI); + using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II, + const MCRegisterInfo &MRI, + MCContext &Ctx); + using ELFStreamerCtorTy = MCStreamer *(*)(const Triple &T, MCContext &Ctx, MCAsmBackend &TAB, raw_pwrite_stream &OS, MCCodeEmitter *Emitter, bool RelaxAll); - typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S); - typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)( + using MachOStreamerCtorTy = MCStreamer *(*)(MCContext &Ctx, MCAsmBackend &TAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll, + bool DWARFMustBeAtTheEnd); + using COFFStreamerCtorTy = MCStreamer *(*)(MCContext &Ctx, MCAsmBackend &TAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll, + bool IncrementalLinkerCompatible); + using WasmStreamerCtorTy = MCStreamer *(*)(const Triple &T, MCContext &Ctx, + MCAsmBackend &TAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll); + using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S); + using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)( MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, bool IsVerboseAsm); - typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)( + using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)( MCStreamer &S, const MCSubtargetInfo &STI); - typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(const Triple &TT, - MCContext &Ctx); - typedef MCSymbolizer *(*MCSymbolizerCtorTy)( + using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT, + MCContext &Ctx); + using MCSymbolizerCtorTy = MCSymbolizer *(*)( const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, std::unique_ptr<MCRelocationInfo> &&RelInfo); diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index b9e3fa47752ce..c196dd6c1ddc9 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -1,4 +1,4 @@ -//===--- YAMLParser.h - Simple YAML parser --------------------------------===// +//===- YAMLParser.h - Simple YAML parser ------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -41,20 +41,25 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/SMLoc.h" +#include <cassert> +#include <cstddef> +#include <iterator> #include <map> +#include <memory> +#include <string> #include <system_error> -#include <utility> namespace llvm { + class MemoryBufferRef; class SourceMgr; -class Twine; class raw_ostream; +class Twine; namespace yaml { -class document_iterator; class Document; +class document_iterator; class Node; class Scanner; struct Token; @@ -87,6 +92,7 @@ public: document_iterator end(); void skip(); bool failed(); + bool validate() { skip(); return !failed(); @@ -95,10 +101,10 @@ public: void printError(Node *N, const Twine &Msg); private: + friend class Document; + std::unique_ptr<Scanner> scanner; std::unique_ptr<Document> CurrentDoc; - - friend class Document; }; /// \brief Abstract base class for all Nodes. @@ -119,6 +125,18 @@ public: Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor, StringRef Tag); + void *operator new(size_t Size, BumpPtrAllocator &Alloc, + size_t Alignment = 16) noexcept { + return Alloc.Allocate(Size, Alignment); + } + + void operator delete(void *Ptr, BumpPtrAllocator &Alloc, + size_t Size) noexcept { + Alloc.Deallocate(Ptr, Size); + } + + void operator delete(void *) noexcept = delete; + /// \brief Get the value of the anchor attached to this node. If it does not /// have one, getAnchor().size() will be 0. StringRef getAnchor() const { return Anchor; } @@ -146,22 +164,10 @@ public: unsigned int getType() const { return TypeID; } - void *operator new(size_t Size, BumpPtrAllocator &Alloc, - size_t Alignment = 16) noexcept { - return Alloc.Allocate(Size, Alignment); - } - - void operator delete(void *Ptr, BumpPtrAllocator &Alloc, - size_t Size) noexcept { - Alloc.Deallocate(Ptr, Size); - } - protected: std::unique_ptr<Document> &Doc; SMRange SourceRange; - void operator delete(void *) noexcept = delete; - ~Node() = default; private: @@ -268,8 +274,7 @@ class KeyValueNode final : public Node { public: KeyValueNode(std::unique_ptr<Document> &D) - : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr), - Value(nullptr) {} + : Node(NK_KeyValue, D, StringRef(), StringRef()) {} /// \brief Parse and return the key. /// @@ -296,8 +301,8 @@ public: } private: - Node *Key; - Node *Value; + Node *Key = nullptr; + Node *Value = nullptr; }; /// \brief This is an iterator abstraction over YAML collections shared by both @@ -309,7 +314,7 @@ template <class BaseT, class ValueT> class basic_collection_iterator : public std::iterator<std::input_iterator_tag, ValueT> { public: - basic_collection_iterator() : Base(nullptr) {} + basic_collection_iterator() = default; basic_collection_iterator(BaseT *B) : Base(B) {} ValueT *operator->() const { @@ -358,7 +363,7 @@ public: } private: - BaseT *Base; + BaseT *Base = nullptr; }; // The following two templates are used for both MappingNode and Sequence Node. @@ -399,11 +404,12 @@ public: MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag, MappingType MT) - : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true), - IsAtEnd(false), CurrentEntry(nullptr) {} + : Node(NK_Mapping, D, Anchor, Tag), Type(MT) {} friend class basic_collection_iterator<MappingNode, KeyValueNode>; - typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator; + + using iterator = basic_collection_iterator<MappingNode, KeyValueNode>; + template <class T> friend typename T::iterator yaml::begin(T &); template <class T> friend void yaml::skip(T &); @@ -419,9 +425,9 @@ public: private: MappingType Type; - bool IsAtBeginning; - bool IsAtEnd; - KeyValueNode *CurrentEntry; + bool IsAtBeginning = true; + bool IsAtEnd = false; + KeyValueNode *CurrentEntry = nullptr; void increment(); }; @@ -453,13 +459,12 @@ public: SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag, SequenceType ST) - : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true), - IsAtEnd(false), - WasPreviousTokenFlowEntry(true), // Start with an imaginary ','. - CurrentEntry(nullptr) {} + : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST) {} friend class basic_collection_iterator<SequenceNode, Node>; - typedef basic_collection_iterator<SequenceNode, Node> iterator; + + using iterator = basic_collection_iterator<SequenceNode, Node>; + template <class T> friend typename T::iterator yaml::begin(T &); template <class T> friend void yaml::skip(T &); @@ -477,10 +482,10 @@ public: private: SequenceType SeqType; - bool IsAtBeginning; - bool IsAtEnd; - bool WasPreviousTokenFlowEntry; - Node *CurrentEntry; + bool IsAtBeginning = true; + bool IsAtEnd = false; + bool WasPreviousTokenFlowEntry = true; // Start with an imaginary ','. + Node *CurrentEntry = nullptr; }; /// \brief Represents an alias to a Node with an anchor. @@ -507,11 +512,11 @@ private: /// node. class Document { public: + Document(Stream &ParentStream); + /// \brief Root for parsing a node. Returns a single node. Node *parseBlockNode(); - Document(Stream &ParentStream); - /// \brief Finish parsing the current document and return true if there are /// more. Return false otherwise. bool skip(); @@ -564,7 +569,7 @@ private: /// \brief Iterator abstraction for Documents over a Stream. class document_iterator { public: - document_iterator() : Doc(nullptr) {} + document_iterator() = default; document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {} bool operator==(const document_iterator &Other) { @@ -593,11 +598,11 @@ public: private: bool isAtEnd() const { return !Doc || !*Doc; } - std::unique_ptr<Document> *Doc; + std::unique_ptr<Document> *Doc = nullptr; }; -} // End namespace yaml. +} // end namespace yaml -} // End namespace llvm. +} // end namespace llvm -#endif +#endif // LLVM_SUPPORT_YAMLPARSER_H diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 8949d69ce7245..53618a56f853e 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -26,6 +26,7 @@ #include <cctype> #include <cstddef> #include <cstdint> +#include <map> #include <memory> #include <new> #include <string> @@ -226,7 +227,7 @@ struct MissingTrait; template <class T> struct has_ScalarEnumerationTraits { - typedef void (*Signature_enumeration)(class IO&, T&); + using Signature_enumeration = void (*)(class IO&, T&); template <typename U> static char test(SameType<Signature_enumeration, &U::enumeration>*); @@ -243,7 +244,7 @@ public: template <class T> struct has_ScalarBitSetTraits { - typedef void (*Signature_bitset)(class IO&, T&); + using Signature_bitset = void (*)(class IO&, T&); template <typename U> static char test(SameType<Signature_bitset, &U::bitset>*); @@ -259,9 +260,9 @@ public: template <class T> struct has_ScalarTraits { - typedef StringRef (*Signature_input)(StringRef, void*, T&); - typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&); - typedef bool (*Signature_mustQuote)(StringRef); + using Signature_input = StringRef (*)(StringRef, void*, T&); + using Signature_output = void (*)(const T&, void*, raw_ostream&); + using Signature_mustQuote = bool (*)(StringRef); template <typename U> static char test(SameType<Signature_input, &U::input> *, @@ -280,8 +281,8 @@ public: template <class T> struct has_BlockScalarTraits { - typedef StringRef (*Signature_input)(StringRef, void *, T &); - typedef void (*Signature_output)(const T &, void *, llvm::raw_ostream &); + using Signature_input = StringRef (*)(StringRef, void *, T &); + using Signature_output = void (*)(const T &, void *, raw_ostream &); template <typename U> static char test(SameType<Signature_input, &U::input> *, @@ -297,7 +298,7 @@ public: // Test if MappingContextTraits<T> is defined on type T. template <class T, class Context> struct has_MappingTraits { - typedef void (*Signature_mapping)(class IO &, T &, Context &); + using Signature_mapping = void (*)(class IO &, T &, Context &); template <typename U> static char test(SameType<Signature_mapping, &U::mapping>*); @@ -312,7 +313,7 @@ public: // Test if MappingTraits<T> is defined on type T. template <class T> struct has_MappingTraits<T, EmptyContext> { - typedef void (*Signature_mapping)(class IO &, T &); + using Signature_mapping = void (*)(class IO &, T &); template <typename U> static char test(SameType<Signature_mapping, &U::mapping> *); @@ -325,7 +326,7 @@ public: // Test if MappingContextTraits<T>::validate() is defined on type T. template <class T, class Context> struct has_MappingValidateTraits { - typedef StringRef (*Signature_validate)(class IO &, T &, Context &); + using Signature_validate = StringRef (*)(class IO &, T &, Context &); template <typename U> static char test(SameType<Signature_validate, &U::validate>*); @@ -340,7 +341,7 @@ public: // Test if MappingTraits<T>::validate() is defined on type T. template <class T> struct has_MappingValidateTraits<T, EmptyContext> { - typedef StringRef (*Signature_validate)(class IO &, T &); + using Signature_validate = StringRef (*)(class IO &, T &); template <typename U> static char test(SameType<Signature_validate, &U::validate> *); @@ -355,7 +356,7 @@ public: template <class T> struct has_SequenceMethodTraits { - typedef size_t (*Signature_size)(class IO&, T&); + using Signature_size = size_t (*)(class IO&, T&); template <typename U> static char test(SameType<Signature_size, &U::size>*); @@ -371,7 +372,7 @@ public: template <class T> struct has_CustomMappingTraits { - typedef void (*Signature_input)(IO &io, StringRef key, T &v); + using Signature_input = void (*)(IO &io, StringRef key, T &v); template <typename U> static char test(SameType<Signature_input, &U::inputOne>*); @@ -422,7 +423,7 @@ struct has_SequenceTraits : public std::integral_constant<bool, template <class T> struct has_DocumentListTraits { - typedef size_t (*Signature_size)(class IO&, T&); + using Signature_size = size_t (*)(class IO &, T &); template <typename U> static char test(SameType<Signature_size, &U::size>*); @@ -537,7 +538,7 @@ struct unvalidatedMappingTraits // Base class for Input and Output. class IO { public: - IO(void *Ctxt=nullptr); + IO(void *Ctxt = nullptr); virtual ~IO(); virtual bool outputting() = 0; @@ -638,6 +639,7 @@ public: EmptyContext Ctx; this->processKey(Key, Val, true, Ctx); } + template <typename T, typename Context> void mapRequired(const char *Key, T &Val, Context &Ctx) { this->processKey(Key, Val, true, Ctx); @@ -773,7 +775,7 @@ typename std::enable_if<has_ScalarTraits<T>::value, void>::type yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) { if ( io.outputting() ) { std::string Storage; - llvm::raw_string_ostream Buffer(Storage); + raw_string_ostream Buffer(Storage); ScalarTraits<T>::output(Val, io.getContext(), Buffer); StringRef Str = Buffer.str(); io.scalarString(Str, ScalarTraits<T>::mustQuote(Str)); @@ -783,7 +785,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) { io.scalarString(Str, ScalarTraits<T>::mustQuote(Str)); StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val); if ( !Result.empty() ) { - io.setError(llvm::Twine(Result)); + io.setError(Twine(Result)); } } } @@ -793,7 +795,7 @@ typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) { if (YamlIO.outputting()) { std::string Storage; - llvm::raw_string_ostream Buffer(Storage); + raw_string_ostream Buffer(Storage); BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer); StringRef Str = Buffer.str(); YamlIO.blockScalarString(Str); @@ -803,7 +805,7 @@ yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) { StringRef Result = BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val); if (!Result.empty()) - YamlIO.setError(llvm::Twine(Result)); + YamlIO.setError(Twine(Result)); } } @@ -817,7 +819,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) { if (io.outputting()) { StringRef Err = MappingTraits<T>::validate(io, Val); if (!Err.empty()) { - llvm::errs() << Err << "\n"; + errs() << Err << "\n"; assert(Err.empty() && "invalid struct trying to be written as yaml"); } } @@ -871,7 +873,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) { template <typename T, typename Context> typename std::enable_if<has_SequenceTraits<T>::value, void>::type yamlize(IO &io, T &Seq, bool, Context &Ctx) { - if ( has_FlowTraits< SequenceTraits<T> >::value ) { + if ( has_FlowTraits< SequenceTraits<T>>::value ) { unsigned incnt = io.beginFlowSequence(); unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt; for(unsigned i=0; i < count; ++i) { @@ -899,92 +901,92 @@ yamlize(IO &io, T &Seq, bool, Context &Ctx) { template<> struct ScalarTraits<bool> { - static void output(const bool &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, bool &); + static void output(const bool &, void* , raw_ostream &); + static StringRef input(StringRef, void *, bool &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<StringRef> { - static void output(const StringRef &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, StringRef &); + static void output(const StringRef &, void *, raw_ostream &); + static StringRef input(StringRef, void *, StringRef &); static bool mustQuote(StringRef S) { return needsQuotes(S); } }; template<> struct ScalarTraits<std::string> { - static void output(const std::string &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, std::string &); + static void output(const std::string &, void *, raw_ostream &); + static StringRef input(StringRef, void *, std::string &); static bool mustQuote(StringRef S) { return needsQuotes(S); } }; template<> struct ScalarTraits<uint8_t> { - static void output(const uint8_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, uint8_t &); + static void output(const uint8_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, uint8_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<uint16_t> { - static void output(const uint16_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, uint16_t &); + static void output(const uint16_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, uint16_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<uint32_t> { - static void output(const uint32_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, uint32_t &); + static void output(const uint32_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, uint32_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<uint64_t> { - static void output(const uint64_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, uint64_t &); + static void output(const uint64_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, uint64_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<int8_t> { - static void output(const int8_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, int8_t &); + static void output(const int8_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, int8_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<int16_t> { - static void output(const int16_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, int16_t &); + static void output(const int16_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, int16_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<int32_t> { - static void output(const int32_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, int32_t &); + static void output(const int32_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, int32_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<int64_t> { - static void output(const int64_t &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, int64_t &); + static void output(const int64_t &, void *, raw_ostream &); + static StringRef input(StringRef, void *, int64_t &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<float> { - static void output(const float &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, float &); + static void output(const float &, void *, raw_ostream &); + static StringRef input(StringRef, void *, float &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<double> { - static void output(const double &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, double &); + static void output(const double &, void *, raw_ostream &); + static StringRef input(StringRef, void *, double &); static bool mustQuote(StringRef) { return false; } }; @@ -994,12 +996,11 @@ struct ScalarTraits<double> { template <typename value_type, support::endianness endian, size_t alignment> struct ScalarTraits<support::detail::packed_endian_specific_integral< value_type, endian, alignment>> { - typedef support::detail::packed_endian_specific_integral<value_type, endian, - alignment> - endian_type; + using endian_type = + support::detail::packed_endian_specific_integral<value_type, endian, + alignment>; - static void output(const endian_type &E, void *Ctx, - llvm::raw_ostream &Stream) { + static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) { ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream); } @@ -1039,7 +1040,7 @@ struct MappingNormalization { TNorm* operator->() { return BufPtr; } private: - typedef llvm::AlignedCharArrayUnion<TNorm> Storage; + using Storage = AlignedCharArrayUnion<TNorm>; Storage Buffer; IO &io; @@ -1051,9 +1052,8 @@ private: // to [de]normalize an object for use with YAML conversion. template <typename TNorm, typename TFinal> struct MappingNormalizationHeap { - MappingNormalizationHeap(IO &i_o, TFinal &Obj, - llvm::BumpPtrAllocator *allocator) - : io(i_o), BufPtr(nullptr), Result(Obj) { + MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator) + : io(i_o), Result(Obj) { if ( io.outputting() ) { BufPtr = new (&Buffer) TNorm(io, Obj); } @@ -1077,11 +1077,11 @@ struct MappingNormalizationHeap { TNorm* operator->() { return BufPtr; } private: - typedef llvm::AlignedCharArrayUnion<TNorm> Storage; + using Storage = AlignedCharArrayUnion<TNorm>; Storage Buffer; IO &io; - TNorm *BufPtr; + TNorm *BufPtr = nullptr; TFinal &Result; }; @@ -1197,10 +1197,10 @@ private: static inline bool classof(const MapHNode *) { return true; } - typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode; + using NameToNode = StringMap<std::unique_ptr<HNode>>; - NameToNode Mapping; - llvm::SmallVector<std::string, 6> ValidKeys; + NameToNode Mapping; + SmallVector<std::string, 6> ValidKeys; }; class SequenceHNode : public HNode { @@ -1232,14 +1232,14 @@ public: const Node *getCurrentNode() const; private: - llvm::SourceMgr SrcMgr; // must be before Strm + SourceMgr SrcMgr; // must be before Strm std::unique_ptr<llvm::yaml::Stream> Strm; std::unique_ptr<HNode> TopNode; std::error_code EC; - llvm::BumpPtrAllocator StringAllocator; - llvm::yaml::document_iterator DocIterator; + BumpPtrAllocator StringAllocator; + document_iterator DocIterator; std::vector<bool> BitValuesUsed; - HNode *CurrentNode; + HNode *CurrentNode = nullptr; bool ScalarMatchFound; }; @@ -1249,7 +1249,7 @@ private: /// class Output : public IO { public: - Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); + Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70); ~Output() override; /// \brief Set whether or not to output optional values which are equal @@ -1312,17 +1312,17 @@ private: inFlowMapOtherKey }; - llvm::raw_ostream &Out; - int WrapColumn; - SmallVector<InState, 8> StateStack; - int Column; - int ColumnAtFlowStart; - int ColumnAtMapFlowStart; - bool NeedBitValueComma; - bool NeedFlowSequenceComma; - bool EnumerationMatchFound; - bool NeedsNewLine; - bool WriteDefaultValues; + raw_ostream &Out; + int WrapColumn; + SmallVector<InState, 8> StateStack; + int Column = 0; + int ColumnAtFlowStart = 0; + int ColumnAtMapFlowStart = 0; + bool NeedBitValueComma = false; + bool NeedFlowSequenceComma = false; + bool EnumerationMatchFound = false; + bool NeedsNewLine = false; + bool WriteDefaultValues = false; }; /// YAML I/O does conversion based on types. But often native data types @@ -1345,7 +1345,7 @@ private: bool operator==(const _base &rhs) const { return value == rhs; } \ bool operator<(const _type &rhs) const { return value < rhs.value; } \ _base value; \ - typedef _base BaseType; \ + using BaseType = _base; \ }; /// @@ -1359,29 +1359,29 @@ LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64) template<> struct ScalarTraits<Hex8> { - static void output(const Hex8 &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, Hex8 &); + static void output(const Hex8 &, void *, raw_ostream &); + static StringRef input(StringRef, void *, Hex8 &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<Hex16> { - static void output(const Hex16 &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, Hex16 &); + static void output(const Hex16 &, void *, raw_ostream &); + static StringRef input(StringRef, void *, Hex16 &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<Hex32> { - static void output(const Hex32 &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, Hex32 &); + static void output(const Hex32 &, void *, raw_ostream &); + static StringRef input(StringRef, void *, Hex32 &); static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits<Hex64> { - static void output(const Hex64 &, void*, llvm::raw_ostream &); - static StringRef input(StringRef, void*, Hex64 &); + static void output(const Hex64 &, void *, raw_ostream &); + static StringRef input(StringRef, void *, Hex64 &); static bool mustQuote(StringRef) { return false; } }; @@ -1545,8 +1545,10 @@ operator<<(Output &yout, T &seq) { } template <typename T> struct SequenceTraitsImpl { - typedef typename T::value_type _type; + using _type = typename T::value_type; + static size_t size(IO &io, T &seq) { return seq.size(); } + static _type &element(IO &io, T &seq, size_t index) { if (index >= seq.size()) seq.resize(index + 1); @@ -1556,10 +1558,12 @@ template <typename T> struct SequenceTraitsImpl { /// Implementation of CustomMappingTraits for std::map<std::string, T>. template <typename T> struct StdMapStringCustomMappingTraitsImpl { - typedef std::map<std::string, T> map_type; + using map_type = std::map<std::string, T>; + static void inputOne(IO &io, StringRef key, map_type &v) { io.mapRequired(key.str().c_str(), v[key]); } + static void output(IO &io, map_type &v) { for (auto &p : v) io.mapRequired(p.first.c_str(), p.second); @@ -1637,7 +1641,7 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl { namespace llvm { \ namespace yaml { \ template <> struct ScalarTraits<Type> { \ - static void output(const Type &Value, void *ctx, llvm::raw_ostream &Out); \ + static void output(const Type &Value, void *ctx, raw_ostream &Out); \ static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \ static bool mustQuote(StringRef) { return MustQuote; } \ }; \ diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h index ca8c95cb6da2c..670572dc81034 100644 --- a/include/llvm/TableGen/Main.h +++ b/include/llvm/TableGen/Main.h @@ -19,8 +19,8 @@ namespace llvm { class raw_ostream; class RecordKeeper; -/// \brief Perform the action using Records, and write output to OS. -/// \returns true on error, false otherwise +/// Perform the action using Records, and write output to OS. +/// Returns true on error, false otherwise. using TableGenMainFn = bool (raw_ostream &OS, RecordKeeper &Records); int TableGenMain(char *argv0, TableGenMainFn *MainFn); diff --git a/include/llvm/Target/GenericOpcodes.td b/include/llvm/Target/GenericOpcodes.td index de3796cd4ee56..9593d8bd7edbd 100644 --- a/include/llvm/Target/GenericOpcodes.td +++ b/include/llvm/Target/GenericOpcodes.td @@ -386,6 +386,15 @@ def G_FMUL : Instruction { let isCommutable = 1; } +// Generic fused multiply-add instruction. +// Behaves like llvm fma intrinsic ie src1 * src2 + src3 +def G_FMA : Instruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3); + let hasSideEffects = 0; + let isCommutable = 0; +} + // Generic FP division. def G_FDIV : Instruction { let OutOperandList = (outs type0:$dst); @@ -456,15 +465,6 @@ def G_INSERT : Instruction { let hasSideEffects = 0; } -// Combine a sequence of generic vregs into a single larger value (starting at -// bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so -// important to legalization it probably deserves its own instruction. -def G_SEQUENCE : Instruction { - let OutOperandList = (outs type0:$dst); - let InOperandList = (ins variable_ops); - let hasSideEffects = 0; -} - def G_MERGE_VALUES : Instruction { let OutOperandList = (outs type0:$dst); let InOperandList = (ins variable_ops); diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 7595d43398109..2fc3ec996e7f6 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===// +//===- llvm/Target/TargetInstrInfo.h - Instruction Info ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,36 +14,46 @@ #ifndef LLVM_TARGET_TARGETINSTRINFO_H #define LLVM_TARGET_TARGETINSTRINFO_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/None.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineCombinerPattern.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/Support/BranchProbability.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <utility> +#include <vector> namespace llvm { +class DFAPacketizer; class InstrItineraryData; class LiveVariables; -class MCAsmInfo; class MachineMemOperand; class MachineRegisterInfo; -class MDNode; +class MCAsmInfo; class MCInst; struct MCSchedModel; -class MCSymbolRefExpr; -class SDNode; +class Module; +class ScheduleDAG; class ScheduleHazardRecognizer; +class SDNode; class SelectionDAG; -class ScheduleDAG; +class RegScavenger; class TargetRegisterClass; class TargetRegisterInfo; -class TargetSubtargetInfo; class TargetSchedModel; -class DFAPacketizer; +class TargetSubtargetInfo; template<class T> class SmallVectorImpl; @@ -52,8 +62,6 @@ template<class T> class SmallVectorImpl; /// TargetInstrInfo - Interface to description of machine instruction set /// class TargetInstrInfo : public MCInstrInfo { - TargetInstrInfo(const TargetInstrInfo &) = delete; - void operator=(const TargetInstrInfo &) = delete; public: TargetInstrInfo(unsigned CFSetupOpcode = ~0u, unsigned CFDestroyOpcode = ~0u, unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u) @@ -61,7 +69,8 @@ public: CallFrameDestroyOpcode(CFDestroyOpcode), CatchRetOpcode(CatchRetOpcode), ReturnOpcode(ReturnOpcode) {} - + TargetInstrInfo(const TargetInstrInfo &) = delete; + TargetInstrInfo &operator=(const TargetInstrInfo &) = delete; virtual ~TargetInstrInfo(); static bool isGenericOpcode(unsigned Opc) { @@ -396,14 +405,17 @@ public: struct RegSubRegPair { unsigned Reg; unsigned SubReg; + RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0) : Reg(Reg), SubReg(SubReg) {} }; + /// A pair composed of a pair of a register and a sub-register index, /// and another sub-register index. /// Used to give some type checking when modeling Reg:SubReg1, SubReg2. struct RegSubRegPairAndIdx : RegSubRegPair { unsigned SubIdx; + RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0, unsigned SubIdx = 0) : RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {} @@ -469,7 +481,6 @@ public: RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const; - /// Return true if two machine instructions would produce identical values. /// By default, this is only true when the two instructions /// are deemed identical except for defs. If this function is called when the @@ -551,23 +562,19 @@ public: PRED_INVALID // Sentinel value }; - ComparePredicate Predicate; - MachineOperand LHS; - MachineOperand RHS; - MachineBasicBlock *TrueDest; - MachineBasicBlock *FalseDest; - MachineInstr *ConditionDef; + ComparePredicate Predicate = PRED_INVALID; + MachineOperand LHS = MachineOperand::CreateImm(0); + MachineOperand RHS = MachineOperand::CreateImm(0); + MachineBasicBlock *TrueDest = nullptr; + MachineBasicBlock *FalseDest = nullptr; + MachineInstr *ConditionDef = nullptr; /// SingleUseCondition is true if ConditionDef is dead except for the /// branch(es) at the end of the basic block. /// - bool SingleUseCondition; + bool SingleUseCondition = false; - explicit MachineBranchPredicate() - : Predicate(PRED_INVALID), LHS(MachineOperand::CreateImm(0)), - RHS(MachineOperand::CreateImm(0)), TrueDest(nullptr), - FalseDest(nullptr), ConditionDef(nullptr), SingleUseCondition(false) { - } + explicit MachineBranchPredicate() = default; }; /// Analyze the branching code at the end of MBB and parse it into the @@ -1117,7 +1124,6 @@ public: virtual void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const; - /// Return the noop instruction to use for a noop. virtual void getNoop(MCInst &NopInst) const; @@ -1621,16 +1627,18 @@ private: /// \brief Provide DenseMapInfo for TargetInstrInfo::RegSubRegPair. template<> struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> { - typedef DenseMapInfo<unsigned> RegInfo; + using RegInfo = DenseMapInfo<unsigned>; static inline TargetInstrInfo::RegSubRegPair getEmptyKey() { return TargetInstrInfo::RegSubRegPair(RegInfo::getEmptyKey(), RegInfo::getEmptyKey()); } + static inline TargetInstrInfo::RegSubRegPair getTombstoneKey() { return TargetInstrInfo::RegSubRegPair(RegInfo::getTombstoneKey(), RegInfo::getTombstoneKey()); } + /// \brief Reuse getHashValue implementation from /// std::pair<unsigned, unsigned>. static unsigned getHashValue(const TargetInstrInfo::RegSubRegPair &Val) { @@ -1638,6 +1646,7 @@ struct DenseMapInfo<TargetInstrInfo::RegSubRegPair> { std::make_pair(Val.Reg, Val.SubReg); return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal); } + static bool isEqual(const TargetInstrInfo::RegSubRegPair &LHS, const TargetInstrInfo::RegSubRegPair &RHS) { return RegInfo::isEqual(LHS.Reg, RHS.Reg) && diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index a9d67228d2051..22dab2e828281 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetLowering.h - Target Lowering Info -----*- C++ -*-===// +//===- llvm/Target/TargetLowering.h - Target Lowering Info ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -23,6 +23,7 @@ #ifndef LLVM_TARGET_TARGETLOWERING_H #define LLVM_TARGET_TARGETLOWERING_H +#include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -40,6 +41,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instruction.h" @@ -66,10 +68,13 @@ namespace llvm { class BranchProbability; class CCState; class CCValAssign; +class Constant; class FastISel; class FunctionLoweringInfo; +class GlobalValue; class IntrinsicInst; struct KnownBits; +class LLVMContext; class MachineBasicBlock; class MachineFunction; class MachineInstr; @@ -78,6 +83,7 @@ class MachineLoop; class MachineRegisterInfo; class MCContext; class MCExpr; +class Module; class TargetRegisterClass; class TargetLibraryInfo; class TargetRegisterInfo; @@ -127,7 +133,7 @@ public: /// LegalizeKind holds the legalization kind that needs to happen to EVT /// in order to type-legalize it. - typedef std::pair<LegalizeTypeAction, EVT> LegalizeKind; + using LegalizeKind = std::pair<LegalizeTypeAction, EVT>; /// Enum that describes how the target represents true/false values. enum BooleanContent { @@ -189,7 +195,7 @@ public: void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx); }; - typedef std::vector<ArgListEntry> ArgListTy; + using ArgListTy = std::vector<ArgListEntry>; virtual void markLibCallAttributes(MachineFunction *MF, unsigned CC, ArgListTy &Args) const {}; @@ -211,8 +217,8 @@ public: /// NOTE: The TargetMachine owns TLOF. explicit TargetLoweringBase(const TargetMachine &TM); - TargetLoweringBase(const TargetLoweringBase&) = delete; - void operator=(const TargetLoweringBase&) = delete; + TargetLoweringBase(const TargetLoweringBase &) = delete; + TargetLoweringBase &operator=(const TargetLoweringBase &) = delete; virtual ~TargetLoweringBase() = default; protected: @@ -404,6 +410,10 @@ public: return false; } + /// Should we merge stores after Legalization (generally + /// better quality) or before (simpler) + virtual bool mergeStoresAfterLegalization() const { return false; } + /// Returns if it's reasonable to merge stores to MemVT size. virtual bool canMergeStoresTo(unsigned AddressSpace, EVT MemVT) const { return true; @@ -1364,6 +1374,12 @@ public: /// Returns the target-specific address of the unsafe stack pointer. virtual Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const; + /// Returns the name of the symbol used to emit stack probes or the empty + /// string if not applicable. + virtual StringRef getStackProbeSymbolName(MachineFunction &MF) const { + return ""; + } + /// Returns true if a cast between SrcAS and DestAS is a noop. virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const { return false; @@ -2455,8 +2471,8 @@ class TargetLowering : public TargetLoweringBase { public: struct DAGCombinerInfo; - TargetLowering(const TargetLowering&) = delete; - void operator=(const TargetLowering&) = delete; + TargetLowering(const TargetLowering &) = delete; + TargetLowering &operator=(const TargetLowering &) = delete; /// NOTE: The TargetMachine owns TLOF. explicit TargetLowering(const TargetMachine &TM); @@ -2772,7 +2788,6 @@ public: /// described by the Ins array, into the specified DAG. The implementation /// should fill in the InVals array with legal-type argument values, and /// return the resulting token chain value. - /// virtual SDValue LowerFormalArguments( SDValue /*Chain*/, CallingConv::ID /*CallConv*/, bool /*isVarArg*/, const SmallVectorImpl<ISD::InputArg> & /*Ins*/, const SDLoc & /*dl*/, @@ -2786,7 +2801,7 @@ public: /// implementation. struct CallLoweringInfo { SDValue Chain; - Type *RetTy; + Type *RetTy = nullptr; bool RetSExt : 1; bool RetZExt : 1; bool IsVarArg : 1; @@ -2794,30 +2809,28 @@ public: bool DoesNotReturn : 1; bool IsReturnValueUsed : 1; bool IsConvergent : 1; + bool IsPatchPoint : 1; // IsTailCall should be modified by implementations of // TargetLowering::LowerCall that perform tail call conversions. - bool IsTailCall; + bool IsTailCall = false; - unsigned NumFixedArgs; - CallingConv::ID CallConv; + unsigned NumFixedArgs = -1; + CallingConv::ID CallConv = CallingConv::C; SDValue Callee; ArgListTy Args; SelectionDAG &DAG; SDLoc DL; - ImmutableCallSite *CS; - bool IsPatchPoint; + ImmutableCallSite *CS = nullptr; SmallVector<ISD::OutputArg, 32> Outs; SmallVector<SDValue, 32> OutVals; SmallVector<ISD::InputArg, 32> Ins; SmallVector<SDValue, 4> InVals; CallLoweringInfo(SelectionDAG &DAG) - : RetTy(nullptr), RetSExt(false), RetZExt(false), IsVarArg(false), - IsInReg(false), DoesNotReturn(false), IsReturnValueUsed(true), - IsConvergent(false), IsTailCall(false), NumFixedArgs(-1), - CallConv(CallingConv::C), DAG(DAG), CS(nullptr), IsPatchPoint(false) { - } + : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false), + DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false), + IsPatchPoint(false), DAG(DAG) {} CallLoweringInfo &setDebugLoc(const SDLoc &dl) { DL = dl; @@ -3091,7 +3104,6 @@ public: return nullptr; } - bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const; @@ -3140,15 +3152,19 @@ public: /// Information about the constraint code, e.g. Register, RegisterClass, /// Memory, Other, Unknown. - TargetLowering::ConstraintType ConstraintType; + TargetLowering::ConstraintType ConstraintType = TargetLowering::C_Unknown; /// If this is the result output operand or a clobber, this is null, /// otherwise it is the incoming operand to the CallInst. This gets /// modified as the asm is processed. - Value *CallOperandVal; + Value *CallOperandVal = nullptr; /// The ValueType for the operand value. - MVT ConstraintVT; + MVT ConstraintVT = MVT::Other; + + /// Copy constructor for copying from a ConstraintInfo. + AsmOperandInfo(InlineAsm::ConstraintInfo Info) + : InlineAsm::ConstraintInfo(std::move(Info)) {} /// Return true of this is an input operand that is a matching constraint /// like "4". @@ -3157,15 +3173,9 @@ public: /// If this is an input matching constraint, this method returns the output /// operand it matches. unsigned getMatchedOperand() const; - - /// Copy constructor for copying from a ConstraintInfo. - AsmOperandInfo(InlineAsm::ConstraintInfo Info) - : InlineAsm::ConstraintInfo(std::move(Info)), - ConstraintType(TargetLowering::C_Unknown), CallOperandVal(nullptr), - ConstraintVT(MVT::Other) {} }; - typedef std::vector<AsmOperandInfo> AsmOperandInfoVector; + using AsmOperandInfoVector = std::vector<AsmOperandInfo>; /// Split up the constraint string from the inline assembly value into the /// specific constraints and their prefixes, and also tie in the associated diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 36764249632da..836b11cf89c68 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -241,8 +241,6 @@ HANDLE_TARGET_OPCODE(G_INSERT) /// Generic instruction to paste a variable number of components together into a /// larger register. -HANDLE_TARGET_OPCODE(G_SEQUENCE) - HANDLE_TARGET_OPCODE(G_MERGE_VALUES) /// Generic pointer to int conversion. @@ -359,6 +357,9 @@ HANDLE_TARGET_OPCODE(G_FSUB) /// Generic FP multiplication. HANDLE_TARGET_OPCODE(G_FMUL) +/// Generic FMA multiplication. Behaves like llvm fma intrinsic +HANDLE_TARGET_OPCODE(G_FMA) + /// Generic FP division. HANDLE_TARGET_OPCODE(G_FDIV) diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 86ad8ad530527..b6839dad106f1 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -1,4 +1,4 @@ -//=== Target/TargetRegisterInfo.h - Target Register Information -*- C++ -*-===// +//==- Target/TargetRegisterInfo.h - Target Register Information --*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -17,30 +17,35 @@ #define LLVM_TARGET_TARGETREGISTERINFO_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineValueType.h" #include "llvm/IR/CallingConv.h" +#include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCRegisterInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Printable.h" #include <cassert> +#include <cstdint> #include <functional> namespace llvm { class BitVector; +class LiveRegMatrix; class MachineFunction; +class MachineInstr; class RegScavenger; -template<class T> class SmallVectorImpl; class VirtRegMap; -class raw_ostream; -class LiveRegMatrix; class TargetRegisterClass { public: - typedef const MCPhysReg* iterator; - typedef const MCPhysReg* const_iterator; - typedef const TargetRegisterClass* const * sc_iterator; + using iterator = const MCPhysReg *; + using const_iterator = const MCPhysReg *; + using sc_iterator = const TargetRegisterClass* const *; // Instance variables filled by tablegen, do not use! const MCRegisterClass *MC; @@ -151,7 +156,6 @@ public: /// There exists SuperRC where: /// For all Reg in SuperRC: /// this->contains(Reg:Idx) - /// const uint16_t *getSuperRegIndices() const { return SuperRegIndices; } @@ -182,7 +186,6 @@ public: /// other criteria. /// /// By default, this method returns all registers in the class. - /// ArrayRef<MCPhysReg> getRawAllocationOrder(const MachineFunction &MF) const { return OrderFunc ? OrderFunc(MF) : makeArrayRef(begin(), getNumRegs()); } @@ -217,8 +220,9 @@ struct RegClassWeight { /// class TargetRegisterInfo : public MCRegisterInfo { public: - typedef const TargetRegisterClass * const * regclass_iterator; - typedef const MVT::SimpleValueType* vt_iterator; + using regclass_iterator = const TargetRegisterClass * const *; + using vt_iterator = const MVT::SimpleValueType *; + private: const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen const char *const *SubRegIndexNames; // Names of subreg indexes. @@ -236,8 +240,8 @@ protected: const LaneBitmask *SRILaneMasks, LaneBitmask CoveringLanes); virtual ~TargetRegisterInfo(); -public: +public: // Register numbers can represent physical registers, virtual registers, and // sometimes stack slots. The unsigned values are divided into these ranges: // @@ -510,7 +514,7 @@ public: /// Prior to adding the live-out mask to a stackmap or patchpoint /// instruction, provide the target the opportunity to adjust it (mainly to /// remove pseudo-registers that should be ignored). - virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const { } + virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const {} /// Return a super-register of the specified register /// Reg so its sub-register of index SubIdx is Reg. @@ -568,7 +572,6 @@ public: /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has /// ssub_0:S0 - ssub_3:S3 subregs. /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2. - /// unsigned composeSubRegIndices(unsigned a, unsigned b) const { if (!a) return b; if (!b) return a; @@ -643,7 +646,6 @@ public: /// corresponding argument register class. /// /// The function returns NULL if no register class can be found. - /// const TargetRegisterClass* getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, const TargetRegisterClass *RCB, unsigned SubB, @@ -654,7 +656,6 @@ public: // /// Register class iterators - /// regclass_iterator regclass_begin() const { return RegClassBegin; } regclass_iterator regclass_end() const { return RegClassEnd; } iterator_range<regclass_iterator> regclasses() const { @@ -909,7 +910,6 @@ public: /// Return true if the register was spilled, false otherwise. /// If this function does not spill the register, the scavenger /// will instead spill it to the emergency spill slot. - /// virtual bool saveScavengerRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock::iterator &UseMI, @@ -968,7 +968,6 @@ public: ArrayRef<MCPhysReg> Exceptions = ArrayRef<MCPhysReg>()) const; }; - //===----------------------------------------------------------------------===// // SuperRegClassIterator //===----------------------------------------------------------------------===// @@ -987,7 +986,7 @@ public: // class SuperRegClassIterator { const unsigned RCMaskWords; - unsigned SubReg; + unsigned SubReg = 0; const uint16_t *Idx; const uint32_t *Mask; @@ -998,9 +997,7 @@ public: const TargetRegisterInfo *TRI, bool IncludeSelf = false) : RCMaskWords((TRI->getNumRegClasses() + 31) / 32), - SubReg(0), - Idx(RC->getSuperRegIndices()), - Mask(RC->getSubClassMask()) { + Idx(RC->getSuperRegIndices()), Mask(RC->getSubClassMask()) { if (!IncludeSelf) ++*this; } @@ -1039,12 +1036,12 @@ class BitMaskClassIterator { /// Base index of CurrentChunk. /// In other words, the number of bit we read to get at the /// beginning of that chunck. - unsigned Base; + unsigned Base = 0; /// Adjust base index of CurrentChunk. /// Base index + how many bit we read within CurrentChunk. - unsigned Idx; + unsigned Idx = 0; /// Current register class ID. - unsigned ID; + unsigned ID = 0; /// Mask we are iterating over. const uint32_t *Mask; /// Current chunk of the Mask we are traversing. @@ -1098,8 +1095,7 @@ public: /// /// \pre \p Mask != nullptr BitMaskClassIterator(const uint32_t *Mask, const TargetRegisterInfo &TRI) - : NumRegClasses(TRI.getNumRegClasses()), Base(0), Idx(0), ID(0), - Mask(Mask), CurrentChunk(*Mask) { + : NumRegClasses(TRI.getNumRegClasses()), Mask(Mask), CurrentChunk(*Mask) { // Move to the first ID. moveToNextID(); } @@ -1151,6 +1147,6 @@ Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI); /// registers on a \ref raw_ostream. Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI); -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_TARGET_TARGETREGISTERINFO_H diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index 9cb07a5c6daea..9440c56dcf17e 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -1,4 +1,4 @@ -//==-- llvm/Target/TargetSubtargetInfo.h - Target Information ----*- C++ -*-==// +//===- llvm/Target/TargetSubtargetInfo.h - Target Information ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,21 +20,29 @@ #include "llvm/CodeGen/PBQPRAConstraint.h" #include "llvm/CodeGen/ScheduleDAGMutation.h" #include "llvm/CodeGen/SchedulerRegistry.h" -#include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CodeGen.h" #include <memory> #include <vector> + namespace llvm { class CallLowering; +class InstrItineraryData; +struct InstrStage; class InstructionSelector; class LegalizerInfo; class MachineInstr; +struct MachineSchedPolicy; +struct MCReadAdvanceEntry; +struct MCWriteLatencyEntry; +struct MCWriteProcResEntry; class RegisterBankInfo; class SDep; class SelectionDAGTargetInfo; +struct SubtargetFeatureKV; +struct SubtargetInfoKV; class SUnit; class TargetFrameLowering; class TargetInstrInfo; @@ -42,7 +50,7 @@ class TargetLowering; class TargetRegisterClass; class TargetRegisterInfo; class TargetSchedModel; -struct MachineSchedPolicy; +class Triple; //===----------------------------------------------------------------------===// /// @@ -64,13 +72,13 @@ protected: // Can only create subclasses... public: // AntiDepBreakMode - Type of anti-dependence breaking that should // be performed before post-RA scheduling. - typedef enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL } AntiDepBreakMode; - typedef SmallVectorImpl<const TargetRegisterClass *> RegClassVector; + using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL }; + using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>; TargetSubtargetInfo() = delete; TargetSubtargetInfo(const TargetSubtargetInfo &) = delete; - void operator=(const TargetSubtargetInfo &) = delete; - virtual ~TargetSubtargetInfo(); + TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete; + ~TargetSubtargetInfo() override; virtual bool isXRaySupported() const { return false; } @@ -112,7 +120,6 @@ public: /// getRegisterInfo - If register information is available, return it. If /// not, return null. - /// virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } /// If the information for the register banks is available, return it. @@ -121,7 +128,6 @@ public: /// getInstrItineraryData - Returns instruction itinerary data for the target /// or specific subtarget. - /// virtual const InstrItineraryData *getInstrItineraryData() const { return nullptr; } diff --git a/include/llvm/Testing/Support/Error.h b/include/llvm/Testing/Support/Error.h index d527529015933..f23d289266adc 100644 --- a/include/llvm/Testing/Support/Error.h +++ b/include/llvm/Testing/Support/Error.h @@ -30,8 +30,8 @@ template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) { return Result; } -template <typename T> ExpectedHolder<T> TakeExpected(const Expected<T> &Exp) { - return TakeExpected(const_cast<Expected<T> &>(Exp)); +template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) { + return TakeExpected(Exp); } } // namespace detail diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h index 247382c35eebf..db4bfb15f51d8 100644 --- a/include/llvm/Transforms/IPO/PassManagerBuilder.h +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -149,7 +149,6 @@ public: bool SLPVectorize; bool LoopVectorize; bool RerollLoops; - bool LoadCombine; bool NewGVN; bool DisableGVNLoadPRE; bool VerifyInput; diff --git a/include/llvm/Transforms/InstrProfiling.h b/include/llvm/Transforms/InstrProfiling.h index 65e69761baddd..0fe6ad5eeac7d 100644 --- a/include/llvm/Transforms/InstrProfiling.h +++ b/include/llvm/Transforms/InstrProfiling.h @@ -28,6 +28,7 @@ namespace llvm { class TargetLibraryInfo; +using LoadStorePair = std::pair<Instruction *, Instruction *>; /// Instrumentation based profiling lowering pass. This pass lowers /// the profile instrumented code generated by FE or the IR based @@ -60,11 +61,26 @@ private: GlobalVariable *NamesVar; size_t NamesSize; + // vector of counter load/store pairs to be register promoted. + std::vector<LoadStorePair> PromotionCandidates; + // The start value of precise value profile range for memory intrinsic sizes. int64_t MemOPSizeRangeStart; // The end value of precise value profile range for memory intrinsic sizes. int64_t MemOPSizeRangeLast; + int64_t TotalCountersPromoted = 0; + + /// Lower instrumentation intrinsics in the function. Returns true if there + /// any lowering. + bool lowerIntrinsics(Function *F); + + /// Register-promote counter loads and stores in loops. + void promoteCounterLoadStores(Function *F); + + /// Returns true if profile counter update register promotion is enabled. + bool isCounterPromotionEnabled() const; + /// Count the number of instrumented value sites for the function. void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index b6c6c091631d5..f2fc6dc8dad5e 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -116,6 +116,9 @@ struct InstrProfOptions { // Add the 'noredzone' attribute to added runtime library calls. bool NoRedZone = false; + // Do counter register promotion + bool DoCounterPromotion = false; + // Name of the profile file to use as output std::string InstrProfileOutput; diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 856c288a071f3..1913a9d5da027 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -487,12 +487,6 @@ FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass(); //===----------------------------------------------------------------------===// // -// LoadCombine - Combine loads into bigger loads. -// -BasicBlockPass *createLoadCombinePass(); - -//===----------------------------------------------------------------------===// -// // StraightLineStrengthReduce - This pass strength-reduces some certain // instruction patterns in straight-line code. // diff --git a/include/llvm/Transforms/Scalar/GVN.h b/include/llvm/Transforms/Scalar/GVN.h index 589aaaca02fe1..4c585a20021cd 100644 --- a/include/llvm/Transforms/Scalar/GVN.h +++ b/include/llvm/Transforms/Scalar/GVN.h @@ -68,6 +68,21 @@ public: class ValueTable { DenseMap<Value *, uint32_t> valueNumbering; DenseMap<Expression, uint32_t> expressionNumbering; + + // Expressions is the vector of Expression. ExprIdx is the mapping from + // value number to the index of Expression in Expressions. We use it + // instead of a DenseMap because filling such mapping is faster than + // filling a DenseMap and the compile time is a little better. + uint32_t nextExprNumber; + std::vector<Expression> Expressions; + std::vector<uint32_t> ExprIdx; + // Value number to PHINode mapping. Used for phi-translate in scalarpre. + DenseMap<uint32_t, PHINode *> NumberingPhi; + // Cache for phi-translate in scalarpre. + typedef DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t> + PhiTranslateMap; + PhiTranslateMap PhiTranslateTable; + AliasAnalysis *AA; MemoryDependenceResults *MD; DominatorTree *DT; @@ -79,6 +94,10 @@ public: Value *LHS, Value *RHS); Expression createExtractvalueExpr(ExtractValueInst *EI); uint32_t lookupOrAddCall(CallInst *C); + uint32_t phiTranslateImpl(const BasicBlock *BB, const BasicBlock *PhiBlock, + uint32_t Num, GVN &Gvn); + std::pair<uint32_t, bool> assignExpNewValueNum(Expression &exp); + bool areAllValsInBB(uint32_t num, const BasicBlock *BB, GVN &Gvn); public: ValueTable(); @@ -87,9 +106,11 @@ public: ~ValueTable(); uint32_t lookupOrAdd(Value *V); - uint32_t lookup(Value *V) const; + uint32_t lookup(Value *V, bool Verify = true) const; uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS); + uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock, + uint32_t Num, GVN &Gvn); bool exists(Value *V) const; void add(Value *V, uint32_t num); void clear(); @@ -131,6 +152,10 @@ private: SmallMapVector<llvm::Value *, llvm::Constant *, 4> ReplaceWithConstMap; SmallVector<Instruction *, 8> InstrsToErase; + // Map the block to reversed postorder traversal number. It is used to + // find back edge easily. + DenseMap<const BasicBlock *, uint32_t> BlockRPONumber; + typedef SmallVector<NonLocalDepResult, 64> LoadDepVect; typedef SmallVector<gvn::AvailableValueInBlock, 64> AvailValInBlkVect; typedef SmallVector<BasicBlock *, 64> UnavailBlkVect; @@ -209,12 +234,12 @@ private: // Other helper routines bool processInstruction(Instruction *I); bool processBlock(BasicBlock *BB); - void dump(DenseMap<uint32_t, Value *> &d); + void dump(DenseMap<uint32_t, Value *> &d) const; bool iterateOnFunction(Function &F); bool performPRE(Function &F); bool performScalarPRE(Instruction *I); bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred, - unsigned int ValNo); + BasicBlock *Curr, unsigned int ValNo); Value *findLeader(const BasicBlock *BB, uint32_t num); void cleanupGlobalSets(); void verifyRemoved(const Instruction *I) const; @@ -226,6 +251,7 @@ private: bool processFoldableCondBr(BranchInst *BI); void addDeadBlock(BasicBlock *BB); void assignValNumForDeadCode(); + void assignBlockRPONumber(Function &F); }; /// Create a legacy GVN pass. This also allows parameterizing whether or not diff --git a/include/llvm/Transforms/Scalar/Reassociate.h b/include/llvm/Transforms/Scalar/Reassociate.h index 7b68b44893063..a30a7176baa8b 100644 --- a/include/llvm/Transforms/Scalar/Reassociate.h +++ b/include/llvm/Transforms/Scalar/Reassociate.h @@ -82,8 +82,6 @@ private: bool CombineXorOpnd(Instruction *I, reassociate::XorOpnd *Opnd1, reassociate::XorOpnd *Opnd2, APInt &ConstOpnd, Value *&Res); - bool collectMultiplyFactors(SmallVectorImpl<reassociate::ValueEntry> &Ops, - SmallVectorImpl<reassociate::Factor> &Factors); Value *buildMinimalMultiplyDAG(IRBuilder<> &Builder, SmallVectorImpl<reassociate::Factor> &Factors); Value *OptimizeMul(BinaryOperator *I, diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 8fed292e77a37..30b27616cd982 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -380,6 +380,19 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, /// during lowering by the GC infrastructure. bool callsGCLeafFunction(ImmutableCallSite CS); +/// Copy a nonnull metadata node to a new load instruction. +/// +/// This handles mapping it to range metadata if the new load is an integer +/// load instead of a pointer load. +void copyNonnullMetadata(const LoadInst &OldLI, MDNode *N, LoadInst &NewLI); + +/// Copy a range metadata node to a new load instruction. +/// +/// This handles mapping it to nonnull metadata if the new load is a pointer +/// load instead of an integer load and the range doesn't cover null. +void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, MDNode *N, + LoadInst &NewLI); + //===----------------------------------------------------------------------===// // Intrinsic pattern matching // diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index 561f948806240..0397eb95e7632 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -362,6 +362,14 @@ private: BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, bool PreserveLCSSA); +/// Ensure that all exit blocks of the loop are dedicated exits. +/// +/// For any loop exit block with non-loop predecessors, we split the loop +/// predecessors to use a dedicated loop exit block. We update the dominator +/// tree and loop info if provided, and will preserve LCSSA if requested. +bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI, + bool PreserveLCSSA); + /// Ensures LCSSA form for every instruction from the Worklist in the scope of /// innermost containing loop. /// diff --git a/include/llvm/Transforms/Utils/OrderedInstructions.h b/include/llvm/Transforms/Utils/OrderedInstructions.h index e043ff39a998b..64c6bcb68b189 100644 --- a/include/llvm/Transforms/Utils/OrderedInstructions.h +++ b/include/llvm/Transforms/Utils/OrderedInstructions.h @@ -43,6 +43,9 @@ public: bool dominates(const Instruction *, const Instruction *) const; /// Invalidate the OrderedBasicBlock cache when its basic block changes. + /// i.e. If an instruction is deleted or added to the basic block, the user + /// should call this function to invalidate the OrderedBasicBlock cache for + /// this basic block. void invalidateBlock(BasicBlock *BB) { OBBMap.erase(BB); } }; diff --git a/include/llvm/Transforms/Vectorize/LoopVectorize.h b/include/llvm/Transforms/Vectorize/LoopVectorize.h index 73d1f264c37b5..57d10c4c74734 100644 --- a/include/llvm/Transforms/Vectorize/LoopVectorize.h +++ b/include/llvm/Transforms/Vectorize/LoopVectorize.h @@ -87,8 +87,6 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> { std::function<const LoopAccessInfo &(Loop &)> *GetLAA; OptimizationRemarkEmitter *ORE; - BlockFrequency ColdEntryFreq; - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); // Shim for old PM. diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap index d906b05f7aaa1..dd419e861316e 100644 --- a/include/llvm/module.modulemap +++ b/include/llvm/module.modulemap @@ -275,11 +275,9 @@ module LLVM_Utils { umbrella "Support" module * { export * } - // Exclude this; it's only included on Solaris. - exclude header "Support/Solaris.h" - - // Exclude this; it's fundamentally non-modular. + // Exclude these; they are fundamentally non-modular. exclude header "Support/PluginLoader.h" + exclude header "Support/Solaris/sys/regset.h" // These are intended for textual inclusion. textual header "Support/ARMTargetParser.def" |