diff options
Diffstat (limited to 'include/llvm')
60 files changed, 1201 insertions, 481 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 63c92c1a7fce..c3822e35906a 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -842,6 +842,7 @@ public: /// /// \returns *this APInt &operator*=(const APInt &RHS); + APInt &operator*=(uint64_t RHS); /// \brief Addition assignment operator. /// @@ -2043,6 +2044,16 @@ inline APInt operator-(uint64_t LHS, APInt b) { return b; } +inline APInt operator*(APInt a, uint64_t RHS) { + a *= RHS; + return a; +} + +inline APInt operator*(uint64_t LHS, APInt b) { + b *= LHS; + return b; +} + namespace APIntOps { diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 5aa101591e6e..e835f1516225 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -217,7 +217,7 @@ public: unsigned BitPos = Prev % BITWORD_SIZE; BitWord Copy = Bits[WordPos]; // Mask off previous bits. - Copy &= ~0UL << BitPos; + Copy &= maskTrailingZeros<BitWord>(BitPos); if (Copy != 0) return WordPos * BITWORD_SIZE + countTrailingZeros(Copy); @@ -229,7 +229,7 @@ public: return -1; } - /// find_next_unset - Returns the index of the next usnet bit following the + /// find_next_unset - Returns the index of the next unset bit following the /// "Prev" bit. Returns -1 if all remaining bits are set. int find_next_unset(unsigned Prev) const { ++Prev; @@ -253,7 +253,34 @@ public: return -1; } - /// clear - Clear all bits. + /// find_prev - Returns the index of the first set bit that precedes the + /// the bit at \p PriorTo. Returns -1 if all previous bits are unset. + int find_prev(unsigned PriorTo) { + if (PriorTo == 0) + return -1; + + --PriorTo; + + unsigned WordPos = PriorTo / BITWORD_SIZE; + unsigned BitPos = PriorTo % BITWORD_SIZE; + BitWord Copy = Bits[WordPos]; + // Mask off next bits. + Copy &= maskTrailingOnes<BitWord>(BitPos + 1); + + if (Copy != 0) + return (WordPos + 1) * BITWORD_SIZE - countLeadingZeros(Copy) - 1; + + // Check previous words. + for (unsigned i = 1; i <= WordPos; ++i) { + unsigned Index = WordPos - i; + if (Bits[Index] == 0) + continue; + return (Index + 1) * BITWORD_SIZE - countLeadingZeros(Bits[Index]) - 1; + } + return -1; + } + + /// clear - Removes all bits from the bitvector. Does not change capacity. void clear() { Size = 0; } diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index bf16af5933f0..0eeacc162543 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -278,6 +278,24 @@ public: return getPointer()->find_next_unset(Prev); } + /// find_prev - Returns the index of the first set bit that precedes the + /// the bit at \p PriorTo. Returns -1 if all previous bits are unset. + int find_prev(unsigned PriorTo) const { + if (isSmall()) { + if (PriorTo == 0) + return -1; + + --PriorTo; + uintptr_t Bits = getSmallBits(); + Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1); + if (Bits == 0) + return -1; + + return NumBaseBits - countLeadingZeros(Bits) - 1; + } + return getPointer()->find_prev(PriorTo); + } + /// Clear all bits. void clear() { if (!isSmall()) diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h index 66c9f68afc60..249fa572c024 100644 --- a/include/llvm/Analysis/LoopInfoImpl.h +++ b/include/llvm/Analysis/LoopInfoImpl.h @@ -220,8 +220,8 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { BI = df_ext_begin(getHeader(), VisitSet), BE = df_ext_end(getHeader(), VisitSet); - // Keep track of the number of BBs visited. - unsigned NumVisited = 0; + // Keep track of the BBs visited. + SmallPtrSet<BlockT*, 8> VisitedBBs; // Check the individual blocks. for ( ; BI != BE; ++BI) { @@ -259,10 +259,18 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const { assert(BB != &getHeader()->getParent()->front() && "Loop contains function entry block!"); - NumVisited++; + VisitedBBs.insert(BB); } - assert(NumVisited == getNumBlocks() && "Unreachable block in loop"); + if (VisitedBBs.size() != getNumBlocks()) { + dbgs() << "The following blocks are unreachable in the loop: "; + for (auto BB : Blocks) { + if (!VisitedBBs.count(BB)) { + dbgs() << *BB << "\n"; + } + } + assert(false && "Unreachable block in loop"); + } // Check the subloops. for (iterator I = begin(), E = end(); I != E; ++I) diff --git a/include/llvm/Analysis/ProfileSummaryInfo.h b/include/llvm/Analysis/ProfileSummaryInfo.h index 1aec35c3e677..75c4cbd03706 100644 --- a/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/include/llvm/Analysis/ProfileSummaryInfo.h @@ -54,6 +54,18 @@ public: ProfileSummaryInfo(Module &M) : M(M) {} ProfileSummaryInfo(ProfileSummaryInfo &&Arg) : M(Arg.M), Summary(std::move(Arg.Summary)) {} + + /// Handle the invalidation of this information. + /// + /// When used as a result of \c ProfileSummaryAnalysis this method will be + /// called when the module this was computed for changes. Since profile + /// summary is immutable after it is annotated on the module, we return false + /// here. + bool invalidate(Module &, const PreservedAnalyses &, + ModuleAnalysisManager::Invalidator &) { + return false; + } + /// Returns the profile count for \p CallInst. static Optional<uint64_t> getProfileCount(const Instruction *CallInst, BlockFrequencyInfo *BFI); diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 54bc4dcfd2cd..85350fa159d6 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -782,13 +782,13 @@ private: /// Set the memoized range for the given SCEV. const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint, - const ConstantRange &CR) { + ConstantRange &&CR) { DenseMap<const SCEV *, ConstantRange> &Cache = Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges; - auto Pair = Cache.insert({S, CR}); + auto Pair = Cache.try_emplace(S, std::move(CR)); if (!Pair.second) - Pair.first->second = CR; + Pair.first->second = std::move(CR); return Pair.first->second; } @@ -816,6 +816,10 @@ private: /// Helper function called from createNodeForPHI. const SCEV *createAddRecFromPHI(PHINode *PN); + /// A helper function for createAddRecFromPHI to handle simple cases. + const SCEV *createSimpleAffineAddRec(PHINode *PN, Value *BEValueV, + Value *StartValueV); + /// Helper function called from createNodeForPHI. const SCEV *createNodeFromSelectLikePHI(PHINode *PN); @@ -1565,7 +1569,7 @@ public: /// delinearization). void findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms, SmallVectorImpl<const SCEV *> &Sizes, - const SCEV *ElementSize) const; + const SCEV *ElementSize); void print(raw_ostream &OS) const; void verify() const; diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def index 637fc7ed30dd..099a3c7cf2ac 100644 --- a/include/llvm/Analysis/TargetLibraryInfo.def +++ b/include/llvm/Analysis/TargetLibraryInfo.def @@ -1115,6 +1115,9 @@ TLI_DEFINE_STRING_INTERNAL("vsprintf") /// int vsscanf(const char *s, const char *format, va_list arg); TLI_DEFINE_ENUM_INTERNAL(vsscanf) TLI_DEFINE_STRING_INTERNAL("vsscanf") +/// size_t wcslen (const wchar_t* wcs); +TLI_DEFINE_ENUM_INTERNAL(wcslen) +TLI_DEFINE_STRING_INTERNAL("wcslen") /// ssize_t write(int fildes, const void *buf, size_t nbyte); TLI_DEFINE_ENUM_INTERNAL(write) TLI_DEFINE_STRING_INTERNAL("write") diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index fb8c8408fc77..180c0b579248 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -226,6 +226,7 @@ public: FUNCTION_EXIT = 1, TAIL_CALL = 2, LOG_ARGS_ENTER = 3, + CUSTOM_EVENT = 4, }; // The table will contain these structs that point to the sled, the function @@ -242,7 +243,7 @@ public: }; // All the sleds to be emitted. - std::vector<XRayFunctionEntry> Sleds; + SmallVector<XRayFunctionEntry, 4> Sleds; // Helper function to record a given XRay sled. void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind); diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 2abe3bb11556..57fa0c73d272 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -506,6 +506,7 @@ protected: bool selectCast(const User *I, unsigned Opcode); bool selectExtractValue(const User *I); bool selectInsertValue(const User *I); + bool selectXRayCustomEvent(const CallInst *II); private: /// \brief Handle PHI nodes in successor blocks. diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 14ee5019ef2f..e7544bd7b70c 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -249,7 +249,7 @@ public: void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits, const KnownBits &Known) { // Only install this information if it tells us something. - if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0) + if (NumSignBits == 1 && Known.isUnknown()) return; LiveOutRegInfo.grow(Reg); diff --git a/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/include/llvm/CodeGen/GlobalISel/IRTranslator.h index 31ffdc0e2e78..e292e8913db0 100644 --- a/include/llvm/CodeGen/GlobalISel/IRTranslator.h +++ b/include/llvm/CodeGen/GlobalISel/IRTranslator.h @@ -78,7 +78,7 @@ private: /// this function. DenseMap<const AllocaInst *, int> FrameIndices; - /// Methods for translating form LLVM IR to MachineInstr. + /// \name Methods for translating form LLVM IR to MachineInstr. /// \see ::translate for general information on the translate methods. /// @{ diff --git a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 472f50576d96..6b662a7f7413 100644 --- a/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -45,7 +45,7 @@ class MachineIRBuilder { /// Debug location to be set to any instruction we create. DebugLoc DL; - /// Fields describing the insertion point. + /// \name Fields describing the insertion point. /// @{ MachineBasicBlock *MBB; MachineBasicBlock::iterator II; @@ -84,7 +84,7 @@ public: void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II); /// @} - /// Setters for the insertion point. + /// \name Setters for the insertion point. /// @{ /// Set the MachineFunction where to build instructions. void setMF(MachineFunction &); @@ -98,7 +98,7 @@ public: void setInstr(MachineInstr &MI); /// @} - /// Control where instructions we create are recorded (typically for + /// \name Control where instructions we create are recorded (typically for /// visiting again later during legalization). /// @{ void recordInsertions(std::function<void(MachineInstr *)> InsertedInstr); diff --git a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h index daa8dcf2061b..f610bc02b6f2 100644 --- a/include/llvm/CodeGen/GlobalISel/RegBankSelect.h +++ b/include/llvm/CodeGen/GlobalISel/RegBankSelect.h @@ -309,7 +309,7 @@ public: Impossible }; - /// Convenient types for a list of insertion points. + /// \name Convenient types for a list of insertion points. /// @{ typedef SmallVector<std::unique_ptr<InsertPoint>, 2> InsertionPoints; typedef InsertionPoints::iterator insertpt_iterator; @@ -341,7 +341,7 @@ public: const TargetRegisterInfo &TRI, Pass &P, RepairingKind Kind = RepairingKind::Insert); - /// Getters. + /// \name Getters. /// @{ RepairingKind getKind() const { return Kind; } unsigned getOpIdx() const { return OpIdx; } @@ -349,7 +349,7 @@ public: bool hasSplit() { return HasSplit; } /// @} - /// Overloaded methods to add an insertion point. + /// \name Overloaded methods to add an insertion point. /// @{ /// Add a MBBInsertionPoint to the list of InsertPoints. void addInsertPoint(MachineBasicBlock &MBB, bool Beginning); @@ -362,7 +362,7 @@ public: void addInsertPoint(InsertPoint &Point); /// @} - /// Accessors related to the insertion points. + /// \name Accessors related to the insertion points. /// @{ insertpt_iterator begin() { return InsertPoints.begin(); } insertpt_iterator end() { return InsertPoints.end(); } @@ -561,7 +561,7 @@ private: /// Find the best mapping for \p MI from \p PossibleMappings. /// \return a reference on the best mapping in \p PossibleMappings. - RegisterBankInfo::InstructionMapping & + const RegisterBankInfo::InstructionMapping & findBestMapping(MachineInstr &MI, RegisterBankInfo::InstructionMappings &PossibleMappings, SmallVectorImpl<RepairingPlacement> &RepairPts); diff --git a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h index 600733ac6a2d..f32233b3a9e4 100644 --- a/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ b/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -264,7 +264,7 @@ public: /// Convenient type to represent the alternatives for mapping an /// instruction. /// \todo When we move to TableGen this should be an array ref. - typedef SmallVector<InstructionMapping, 4> InstructionMappings; + typedef SmallVector<const InstructionMapping *, 4> InstructionMappings; /// Helper class used to get/create the virtual registers that will be used /// to replace the MachineOperand when applying a mapping. @@ -310,7 +310,7 @@ public: OperandsMapper(MachineInstr &MI, const InstructionMapping &InstrMapping, MachineRegisterInfo &MRI); - /// Getters. + /// \name Getters. /// @{ /// The MachineInstr being remapped. MachineInstr &getMI() const { return MI; } @@ -378,15 +378,23 @@ protected: /// Keep dynamically allocated PartialMapping in a separate map. /// This shouldn't be needed when everything gets TableGen'ed. - mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>> MapOfPartialMappings; + mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>> + MapOfPartialMappings; /// Keep dynamically allocated ValueMapping in a separate map. /// This shouldn't be needed when everything gets TableGen'ed. - mutable DenseMap<unsigned, std::unique_ptr<const ValueMapping> > MapOfValueMappings; + mutable DenseMap<unsigned, std::unique_ptr<const ValueMapping>> + MapOfValueMappings; /// Keep dynamically allocated array of ValueMapping in a separate map. /// This shouldn't be needed when everything gets TableGen'ed. - mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>> MapOfOperandsMappings; + mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>> + MapOfOperandsMappings; + + /// Keep dynamically allocated InstructionMapping in a separate map. + /// This shouldn't be needed when everything gets TableGen'ed. + mutable DenseMap<unsigned, std::unique_ptr<const InstructionMapping>> + MapOfInstructionMappings; /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks /// RegisterBank instances. @@ -425,14 +433,14 @@ protected: /// register, a register class, or a register bank. /// In other words, this method will likely fail to find a mapping for /// any generic opcode that has not been lowered by target specific code. - InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const; + const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const; /// Get the uniquely generated PartialMapping for the /// given arguments. const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length, const RegisterBank &RegBank) const; - /// Methods to get a uniquely generated ValueMapping. + /// \name Methods to get a uniquely generated ValueMapping. /// @{ /// The most common ValueMapping consists of a single PartialMapping. @@ -445,7 +453,7 @@ protected: unsigned NumBreakDowns) const; /// @} - /// Methods to get a uniquely generated array of ValueMapping. + /// \name Methods to get a uniquely generated array of ValueMapping. /// @{ /// Get the uniquely generated array of ValueMapping for the @@ -478,6 +486,33 @@ protected: std::initializer_list<const ValueMapping *> OpdsMapping) const; /// @} + /// \name Methods to get a uniquely generated InstructionMapping. + /// @{ + +private: + /// Method to get a uniquely generated InstructionMapping. + const InstructionMapping & + getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID, + unsigned Cost = 0, + const ValueMapping *OperandsMapping = nullptr, + unsigned NumOperands = 0) const; + +public: + /// Method to get a uniquely generated InstructionMapping. + const InstructionMapping & + getInstructionMapping(unsigned ID, unsigned Cost, + const ValueMapping *OperandsMapping, + unsigned NumOperands) const { + return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost, + OperandsMapping, NumOperands); + } + + /// Method to get a uniquely generated invalid InstructionMapping. + const InstructionMapping &getInvalidInstructionMapping() const { + return getInstructionMappingImpl(/*IsInvalid*/ true); + } + /// @} + /// Get the register bank for the \p OpIdx-th operand of \p MI form /// the encoding constraints, if any. /// @@ -603,7 +638,8 @@ public: /// /// \note If returnedVal does not verify MI, this would probably mean /// that the target does not support that instruction. - virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const; + virtual const InstructionMapping & + getInstrMapping(const MachineInstr &MI) const; /// Get the alternative mappings for \p MI. /// Alternative in the sense different from getInstrMapping. diff --git a/include/llvm/CodeGen/MIRPrinter.h b/include/llvm/CodeGen/MIRPrinter.h new file mode 100644 index 000000000000..c73adc3f2b11 --- /dev/null +++ b/include/llvm/CodeGen/MIRPrinter.h @@ -0,0 +1,46 @@ +//===- MIRPrinter.h - MIR serialization format printer --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the functions that print out the LLVM IR and the machine +// functions using the MIR serialization format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_MIRPRINTER_H +#define LLVM_LIB_CODEGEN_MIRPRINTER_H + +namespace llvm { + +class MachineBasicBlock; +class MachineFunction; +class Module; +class raw_ostream; +template <typename T> class SmallVectorImpl; + +/// Print LLVM IR using the MIR serialization format to the given output stream. +void printMIR(raw_ostream &OS, const Module &M); + +/// Print a machine function using the MIR serialization format to the given +/// output stream. +void printMIR(raw_ostream &OS, const MachineFunction &MF); + +/// Determine a possible list of successors of a basic block based on the +/// basic block machine operand being used inside the block. This should give +/// you the correct list of successor blocks in most cases except for things +/// like jump tables where the basic block references can't easily be found. +/// The MIRPRinter will skip printing successors if they match the result of +/// this funciton and the parser will use this function to construct a list if +/// it is missing. +void guessSuccessors(const MachineBasicBlock &MBB, + SmallVectorImpl<MachineBasicBlock*> &Successors, + bool &IsFallthrough); + +} // end namespace llvm + +#endif diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 61be9f775c97..689f3cd9fd12 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -520,6 +520,14 @@ public: bool hasTailCall() const { return HasTailCall; } void setHasTailCall() { HasTailCall = true; } + /// Computes the maximum size of a callframe and the AdjustsStack property. + /// This only works for targets defining + /// TargetInstrInfo::getCallFrameSetupOpcode(), getCallFrameDestroyOpcode(), + /// and getFrameSize(). + /// This is usually computed by the prologue epilogue inserter but some + /// targets may call this to compute it earlier. + void computeMaxCallFrameSize(const MachineFunction &MF); + /// Return the maximum size of a call frame that must be /// allocated for an outgoing function call. This is only available if /// CallFrameSetup/Destroy pseudo instructions are used by the target, and diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index 182d23ef3c90..f46ef41879d1 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -116,7 +116,7 @@ class MachineModuleInfo : public ImmutablePass { // TODO: Ideally, what we'd like is to have a switch that allows emitting // synchronous (precise at call-sites only) CFA into .eh_frame. However, - // even under this switch, we'd like .debug_frame to be precise when using. + // even under this switch, we'd like .debug_frame to be precise when using // -g. At this moment, there's no way to specify that some CFI directives // go into .eh_frame only, while others go into .debug_frame only. diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index 220de4bf0ee4..be7b19e7df0c 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -21,7 +21,7 @@ namespace llvm { namespace codeview { class TypeDatabase { public: - TypeDatabase() : TypeNameStorage(Allocator) {} + explicit TypeDatabase(uint32_t ExpectedSize); /// Gets the type index for the next type record. TypeIndex getNextTypeIndex() const; diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index b9f3425d5deb..3fae8b441439 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -310,6 +310,11 @@ class DWARFContextInMemory : public DWARFContext { StringRef *MapSectionToMember(StringRef Name); + /// If Sec is compressed section, decompresses and updates its contents + /// provided by Data. Otherwise leaves it unchanged. + Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, + StringRef &Data); + public: DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr); diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 36b27228f5c6..f3516ebdecba 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -39,20 +39,18 @@ public: private: struct ValueType { - ValueType() { - uval = 0; - } + ValueType() { uval = 0; } union { uint64_t uval; int64_t sval; - const char* cstr; + const char *cstr; }; - const uint8_t* data = nullptr; + const uint8_t *data = nullptr; }; - dwarf::Form Form; // Form for this value. - ValueType Value; // Contains all data for the form. + dwarf::Form Form; // Form for this value. + ValueType Value; // Contains all data for the form. const DWARFUnit *U = nullptr; // Remember the DWARFUnit at extract time. public: @@ -84,7 +82,7 @@ public: const DWARFUnit *U); bool isInlinedCStr() const { - return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr; + return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; } /// getAsFoo functions below return the extracted value as Foo if only @@ -135,45 +133,45 @@ public: uint8_t AddrSize, llvm::dwarf::DwarfFormat Format); - /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. + /// 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 debug_info_data the .debug_info data to use to skip the value. - /// \param offset_ptr a reference to the offset that will be updated. + /// \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. - bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, + bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr, const DWARFUnit *U) const; - /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. + /// 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 debug_info_data the .debug_info data to use to skip the value. - /// \param offset_ptr a reference to the offset that will be updated. + /// \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 debug_info_data, - uint32_t *offset_ptr, const DWARFUnit *U); + static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, + uint32_t *OffsetPtr, const DWARFUnit *U); - /// Skip a form in \p debug_info_data at offset specified by \p offset_ptr. + /// 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 debug_info_data the .debug_info data to use to skip the value. - /// \param offset_ptr a reference to the offset that will be updated. + /// \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. /// \returns true on success, false if the form was not skipped. - static bool skipValue(dwarf::Form form, DataExtractor debug_info_data, - uint32_t *offset_ptr, uint16_t Version, - uint8_t AddrSize, llvm::dwarf::DwarfFormat Format); + static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData, + uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize, + llvm::dwarf::DwarfFormat Format); private: void dumpString(raw_ostream &OS) const; @@ -181,149 +179,146 @@ private: namespace dwarf { - /// Take an optional DWARFFormValue and try to extract a string value from it. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and was a string. - inline Optional<const char*> toString(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsCString(); - return None; - } - - /// Take an optional DWARFFormValue and extract a string value from it. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the string value or Default if the V doesn't have a value or the - /// form value's encoding wasn't a string. - inline const char* - toString(const Optional<DWARFFormValue>& V, const char *Default) { - return toString(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract an unsigned constant. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a unsigned constant form. - inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsUnsignedConstant(); - return None; - } - - /// Take an optional DWARFFormValue and extract a unsigned constant. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the extracted unsigned value or Default if the V doesn't have a - /// value or the form value's encoding wasn't an unsigned constant form. - inline uint64_t - toUnsigned(const Optional<DWARFFormValue>& V, uint64_t Default) { - return toUnsigned(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract an reference. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a reference form. - inline Optional<uint64_t> toReference(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsReference(); - return None; - } - - /// Take an optional DWARFFormValue and extract a reference. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the extracted reference value or Default if the V doesn't have a - /// value or the form value's encoding wasn't a reference form. - inline uint64_t - toReference(const Optional<DWARFFormValue>& V, uint64_t Default) { - return toReference(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract an signed constant. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a signed constant form. - inline Optional<int64_t> toSigned(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsSignedConstant(); - return None; - } - - /// Take an optional DWARFFormValue and extract a signed integer. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the extracted signed integer value or Default if the V doesn't - /// have a value or the form value's encoding wasn't a signed integer form. - inline int64_t - toSigned(const Optional<DWARFFormValue>& V, int64_t Default) { - return toSigned(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract an address. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a address form. - inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsAddress(); - return None; - } - - /// Take an optional DWARFFormValue and extract a address. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the extracted address value or Default if the V doesn't have a - /// value or the form value's encoding wasn't an address form. - inline uint64_t - toAddress(const Optional<DWARFFormValue>& V, uint64_t Default) { - return toAddress(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract an section offset. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a section offset form. - inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsSectionOffset(); - return None; - } - - /// Take an optional DWARFFormValue and extract a section offset. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \param Default the default value to return in case of failure. - /// \returns the extracted section offset value or Default if the V doesn't - /// have a value or the form value's encoding wasn't a section offset form. - inline uint64_t - toSectionOffset(const Optional<DWARFFormValue>& V, uint64_t Default) { - return toSectionOffset(V).getValueOr(Default); - } - - /// Take an optional DWARFFormValue and try to extract block data. - /// - /// \param V and optional DWARFFormValue to attempt to extract the value from. - /// \returns an optional value that contains a value if the form value - /// was valid and has a block form. - inline Optional<ArrayRef<uint8_t>> - toBlock(const Optional<DWARFFormValue>& V) { - if (V) - return V->getAsBlock(); - return None; - } +/// Take an optional DWARFFormValue and try to extract a string value from it. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and was a string. +inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsCString(); + return None; +} + +/// Take an optional DWARFFormValue and extract a string value from it. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the string value or Default if the V doesn't have a value or the +/// form value's encoding wasn't a string. +inline const char *toString(const Optional<DWARFFormValue> &V, + const char *Default) { + return toString(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract an unsigned constant. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a unsigned constant form. +inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsUnsignedConstant(); + return None; +} + +/// Take an optional DWARFFormValue and extract a unsigned constant. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the extracted unsigned value or Default if the V doesn't have a +/// value or the form value's encoding wasn't an unsigned constant form. +inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V, + uint64_t Default) { + return toUnsigned(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract an reference. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a reference form. +inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsReference(); + return None; +} + +/// Take an optional DWARFFormValue and extract a reference. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the extracted reference value or Default if the V doesn't have a +/// value or the form value's encoding wasn't a reference form. +inline uint64_t toReference(const Optional<DWARFFormValue> &V, + uint64_t Default) { + return toReference(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract an signed constant. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a signed constant form. +inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsSignedConstant(); + return None; +} + +/// Take an optional DWARFFormValue and extract a signed integer. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the extracted signed integer value or Default if the V doesn't +/// have a value or the form value's encoding wasn't a signed integer form. +inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) { + return toSigned(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract an address. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a address form. +inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsAddress(); + return None; +} + +/// Take an optional DWARFFormValue and extract a address. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the extracted address value or Default if the V doesn't have a +/// value or the form value's encoding wasn't an address form. +inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) { + return toAddress(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract an section offset. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a section offset form. +inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsSectionOffset(); + return None; +} + +/// Take an optional DWARFFormValue and extract a section offset. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \param Default the default value to return in case of failure. +/// \returns the extracted section offset value or Default if the V doesn't +/// have a value or the form value's encoding wasn't a section offset form. +inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V, + uint64_t Default) { + return toSectionOffset(V).getValueOr(Default); +} + +/// Take an optional DWARFFormValue and try to extract block data. +/// +/// \param V and optional DWARFFormValue to attempt to extract the value from. +/// \returns an optional value that contains a value if the form value +/// was valid and has a block form. +inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsBlock(); + return None; +} } // end namespace dwarf diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h index d1f791b9daed..7e77f5a3eef9 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h @@ -53,14 +53,6 @@ private: const ModuleInfoHeader *Layout = nullptr; }; -struct ModuleInfoEx { - ModuleInfoEx(const DbiModuleDescriptor &Info) : Info(Info) {} - ModuleInfoEx(const ModuleInfoEx &Ex) = default; - - DbiModuleDescriptor Info; - std::vector<StringRef> SourceFiles; -}; - } // end namespace pdb template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> { diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h new file mode 100644 index 000000000000..bcf1cff8f6e5 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleList.h @@ -0,0 +1,114 @@ +//===- DbiModuleList.h - PDB module information list ------------*- 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_PDB_RAW_DBIMODULELIST_H +#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <vector> + +namespace llvm { +namespace pdb { + +class DbiModuleList; +struct FileInfoSubstreamHeader; + +class DbiModuleSourceFilesIterator + : public iterator_facade_base<DbiModuleSourceFilesIterator, + std::random_access_iterator_tag, StringRef> { + typedef iterator_facade_base<DbiModuleSourceFilesIterator, + std::random_access_iterator_tag, StringRef> + BaseType; + +public: + DbiModuleSourceFilesIterator(const DbiModuleList &Modules, uint32_t Modi, + uint16_t Filei); + DbiModuleSourceFilesIterator() = default; + DbiModuleSourceFilesIterator & + operator=(const DbiModuleSourceFilesIterator &R) = default; + + bool operator==(const DbiModuleSourceFilesIterator &R) const; + + const StringRef &operator*() const { return ThisValue; } + StringRef &operator*() { return ThisValue; } + + bool operator<(const DbiModuleSourceFilesIterator &RHS) const; + std::ptrdiff_t operator-(const DbiModuleSourceFilesIterator &R) const; + DbiModuleSourceFilesIterator &operator+=(std::ptrdiff_t N); + DbiModuleSourceFilesIterator &operator-=(std::ptrdiff_t N); + +private: + void setValue(); + + bool isEnd() const; + bool isCompatible(const DbiModuleSourceFilesIterator &R) const; + bool isUniversalEnd() const; + + StringRef ThisValue; + const DbiModuleList *Modules{nullptr}; + uint32_t Modi{0}; + uint16_t Filei{0}; +}; + +class DbiModuleList { + friend DbiModuleSourceFilesIterator; + +public: + Error initialize(BinaryStreamRef ModInfo, BinaryStreamRef FileInfo); + + Expected<StringRef> getFileName(uint32_t Index) const; + uint32_t getModuleCount() const; + uint32_t getSourceFileCount() const; + uint16_t getSourceFileCount(uint32_t Modi) const; + + iterator_range<DbiModuleSourceFilesIterator> + source_files(uint32_t Modi) const; + + DbiModuleDescriptor getModuleDescriptor(uint32_t Modi) const; + +private: + Error initializeModInfo(BinaryStreamRef ModInfo); + Error initializeFileInfo(BinaryStreamRef FileInfo); + + VarStreamArray<DbiModuleDescriptor> Descriptors; + + FixedStreamArray<support::little32_t> FileNameOffsets; + FixedStreamArray<support::ulittle16_t> ModFileCountArray; + + // For each module, there are multiple filenames, which can be obtained by + // knowing the index of the file. Given the index of the file, one can use + // that as an offset into the FileNameOffsets array, which contains the + // absolute offset of the file name in NamesBuffer. Thus, for each module + // we store the first index in the FileNameOffsets array for this module. + // The number of files for the corresponding module is stored in + // ModFileCountArray. + std::vector<uint32_t> ModuleInitialFileIndex; + + // In order to provide random access into the Descriptors array, we iterate it + // once up front to find the offsets of the individual items and store them in + // this array. + std::vector<uint32_t> ModuleDescriptorOffsets; + + const FileInfoSubstreamHeader *FileInfoHeader = nullptr; + + BinaryStreamRef ModInfoSubstream; + BinaryStreamRef FileInfoSubstream; + BinaryStreamRef NamesBuffer; +}; +} +} + +#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H
\ No newline at end of file diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index 08262e47f77f..8f95481f4152 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -13,6 +13,7 @@ #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" @@ -68,9 +69,7 @@ public: /// not present, returns InvalidStreamIndex. uint32_t getDebugStreamIndex(DbgHeaderType Type) const; - ArrayRef<ModuleInfoEx> modules() const; - - Expected<StringRef> getFileNameForIndex(uint32_t Index) const; + const DbiModuleList &modules() const; FixedStreamArray<object::coff_section> getSectionHeaders(); @@ -80,27 +79,22 @@ public: void visitSectionContributions(ISectionContribVisitor &Visitor) const; private: - Error initializeModInfoArray(); Error initializeSectionContributionData(); Error initializeSectionHeadersData(); Error initializeSectionMapData(); - Error initializeFileInfo(); Error initializeFpoRecords(); PDBFile &Pdb; std::unique_ptr<msf::MappedBlockStream> Stream; - std::vector<ModuleInfoEx> ModuleInfos; PDBStringTable ECNames; - BinaryStreamRef ModInfoSubstream; BinaryStreamRef SecContrSubstream; BinaryStreamRef SecMapSubstream; - BinaryStreamRef FileInfoSubstream; BinaryStreamRef TypeServerMapSubstream; BinaryStreamRef ECSubstream; - BinaryStreamRef NamesBuffer; + DbiModuleList Modules; FixedStreamArray<support::ulittle16_t> DbgStreams; @@ -108,7 +102,6 @@ private: FixedStreamArray<SectionContrib> SectionContribs; FixedStreamArray<SectionContrib2> SectionContribs2; FixedStreamArray<SecMapEntry> SectionMap; - FixedStreamArray<support::little32_t> FileNameOffsets; std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream; FixedStreamArray<object::coff_section> SectionHeaders; diff --git a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h index b1d980679a45..22ed61910d94 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h @@ -18,7 +18,7 @@ namespace pdb { class NativeCompilandSymbol : public NativeRawSymbol { public: - NativeCompilandSymbol(NativeSession &Session, const ModuleInfoEx &MI); + NativeCompilandSymbol(NativeSession &Session, DbiModuleDescriptor MI); PDB_SymType getSymTag() const override; bool isEditAndContinueEnabled() const override; uint32_t getLexicalParentId() const override; @@ -26,7 +26,7 @@ public: std::string getName() const override; private: - ModuleInfoEx Module; + DbiModuleDescriptor Module; }; } // namespace pdb diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h index 18022f599bba..6aa1460dbb4e 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h @@ -16,13 +16,13 @@ namespace llvm { namespace pdb { +class DbiModuleList; class NativeSession; class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> { public: - explicit NativeEnumModules(NativeSession &Session, - ArrayRef<ModuleInfoEx> Modules, - uint32_t Index = 0); + NativeEnumModules(NativeSession &Session, const DbiModuleList &Modules, + uint32_t Index = 0); uint32_t getChildCount() const override; std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override; @@ -32,7 +32,7 @@ public: private: NativeSession &Session; - ArrayRef<ModuleInfoEx> Modules; + const DbiModuleList &Modules; uint32_t Index; }; } diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 93622d0a4394..979b8454dd5e 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -211,7 +211,7 @@ struct ModInfoFlags { }; /// The header preceeding each entry in the Module Info substream of the DBI -/// stream. +/// stream. Corresponds to the type MODI in the reference implementation. struct ModuleInfoHeader { /// Currently opened module. This field is a pointer in the reference /// implementation, but that won't work on 64-bit systems, and anyway it @@ -243,9 +243,12 @@ struct ModuleInfoHeader { /// Padding so the next field is 4-byte aligned. char Padding1[2]; - /// Array of [0..NumFiles) DBI name buffer offsets. This field is a pointer - /// in the reference implementation, but as with `Mod`, we ignore it for now - /// since it is unused. + /// Array of [0..NumFiles) DBI name buffer offsets. In the reference + /// implementation this field is a pointer. But since you can't portably + /// serialize a pointer, on 64-bit platforms they copy all the values except + /// this one into the 32-bit version of the struct and use that for + /// serialization. Regardless, this field is unused, it is only there to + /// store a pointer that can be accessed at runtime. support::ulittle32_t FileNameOffs; /// Name Index for src file name diff --git a/include/llvm/DebugInfo/PDB/Native/TpiStream.h b/include/llvm/DebugInfo/PDB/Native/TpiStream.h index 62dde0ef08b7..9fef9bee5e1a 100644 --- a/include/llvm/DebugInfo/PDB/Native/TpiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/TpiStream.h @@ -40,12 +40,12 @@ public: uint32_t TypeIndexBegin() const; uint32_t TypeIndexEnd() const; - uint32_t NumTypeRecords() const; + uint32_t getNumTypeRecords() const; uint16_t getTypeHashStreamIndex() const; uint16_t getTypeHashStreamAuxIndex() const; uint32_t getHashKeySize() const; - uint32_t NumHashBuckets() const; + uint32_t getNumHashBuckets() const; FixedStreamArray<support::ulittle32_t> getHashValues() const; FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const; HashTable &getHashAdjusters(); @@ -55,8 +55,6 @@ public: Error commit(); private: - Error verifyHashValues(); - const PDBFile &Pdb; std::unique_ptr<msf::MappedBlockStream> Stream; diff --git a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h index a3be242b4457..1cb2448a3a44 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCSerialization.h +++ b/include/llvm/ExecutionEngine/Orc/RPCSerialization.h @@ -355,7 +355,7 @@ public: std::move(Deserialize))); KeyName = &I->first; } - + { assert(KeyName != nullptr && "No keyname pointer"); std::lock_guard<std::recursive_mutex> Lock(SerializersMutex); @@ -370,7 +370,7 @@ public: }; } } - + static Error serialize(ChannelT &C, Error &&Err) { std::lock_guard<std::recursive_mutex> Lock(SerializersMutex); diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h index f5f52b5d2f92..de89f405af4c 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h +++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h @@ -10,6 +10,8 @@ #ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H #define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H +#include "llvm/ADT/Optional.h" + #include <cstdint> #include <memory> #include <string> @@ -97,6 +99,10 @@ public: StringRef SectionName, bool LocalAddress); + /// \brief If there is a section at the given local address, return its load + /// address, otherwise return none. + Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const; + private: std::unique_ptr<RuntimeDyldCheckerImpl> Impl; }; diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index adcb7266073b..cbe681684a5c 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -244,7 +244,8 @@ public: std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; std::string getAsString(bool InAttrGrp = false) const; - typedef const Attribute *iterator; + using iterator = const Attribute *; + iterator begin() const; iterator end() const; }; @@ -479,7 +480,7 @@ public: /// \brief Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; - typedef ArrayRef<Attribute>::iterator iterator; + using iterator = ArrayRef<Attribute>::iterator; iterator begin(unsigned Slot) const; iterator end(unsigned Slot) const; @@ -662,11 +663,11 @@ public: bool empty() const { return Attrs.none(); } // Iterators for target-dependent attributes. - typedef std::pair<std::string, std::string> td_type; - typedef std::map<std::string, std::string>::iterator td_iterator; - typedef std::map<std::string, std::string>::const_iterator td_const_iterator; - typedef iterator_range<td_iterator> td_range; - typedef iterator_range<td_const_iterator> td_const_range; + using td_type = std::pair<std::string, std::string>; + using td_iterator = std::map<std::string, std::string>::iterator; + using td_const_iterator = std::map<std::string, std::string>::const_iterator; + using td_range = iterator_range<td_iterator>; + using td_const_range = iterator_range<td_const_iterator>; td_iterator td_begin() { return TargetDepAttrs.begin(); } td_iterator td_end() { return TargetDepAttrs.end(); } diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h index bd210e1abf31..97989cf5c652 100644 --- a/include/llvm/IR/BasicBlock.h +++ b/include/llvm/IR/BasicBlock.h @@ -21,6 +21,7 @@ #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Value.h" #include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/Compiler.h" #include "llvm-c/Types.h" #include <cassert> #include <cstddef> @@ -31,7 +32,9 @@ class CallInst; class Function; class LandingPadInst; class LLVMContext; +class Module; class TerminatorInst; +class ValueSymbolTable; /// \brief LLVM Basic Block Representation /// @@ -51,7 +54,7 @@ class TerminatorInst; class BasicBlock : public Value, // Basic blocks are data objects also public ilist_node_with_parent<BasicBlock, Function> { public: - typedef SymbolTableList<Instruction> InstListType; + using InstListType = SymbolTableList<Instruction>; private: friend class BlockAddress; @@ -80,10 +83,10 @@ public: LLVMContext &getContext() const; /// Instruction iterators... - typedef InstListType::iterator iterator; - typedef InstListType::const_iterator const_iterator; - typedef InstListType::reverse_iterator reverse_iterator; - typedef InstListType::const_reverse_iterator const_reverse_iterator; + using iterator = InstListType::iterator; + using const_iterator = InstListType::const_iterator; + using reverse_iterator = InstListType::reverse_iterator; + using const_reverse_iterator = InstListType::const_reverse_iterator; /// \brief Creates a new BasicBlock. /// diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h index 52de11a06baf..e259e42e1ce4 100644 --- a/include/llvm/IR/CFG.h +++ b/include/llvm/IR/CFG.h @@ -37,9 +37,9 @@ namespace llvm { template <class Ptr, class USE_iterator> // Predecessor Iterator class PredIterator : public std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, Ptr*> { - typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, - Ptr*> super; - typedef PredIterator<Ptr, USE_iterator> Self; + using super = + std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, Ptr*>; + using Self = PredIterator<Ptr, USE_iterator>; USE_iterator It; inline void advancePastNonTerminators() { @@ -49,8 +49,8 @@ class PredIterator : public std::iterator<std::forward_iterator_tag, } public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; + using pointer = typename super::pointer; + using reference = typename super::reference; PredIterator() = default; explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) { @@ -90,11 +90,11 @@ public: } }; -typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator; -typedef PredIterator<const BasicBlock, - Value::const_user_iterator> const_pred_iterator; -typedef iterator_range<pred_iterator> pred_range; -typedef iterator_range<const_pred_iterator> pred_const_range; +using pred_iterator = PredIterator<BasicBlock, Value::user_iterator>; +using const_pred_iterator = + PredIterator<const BasicBlock, Value::const_user_iterator>; +using pred_range = iterator_range<pred_iterator>; +using pred_const_range = iterator_range<const_pred_iterator>; inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); } inline const_pred_iterator pred_begin(const BasicBlock *BB) { @@ -118,12 +118,12 @@ inline pred_const_range predecessors(const BasicBlock *BB) { // BasicBlock succ_iterator helpers //===----------------------------------------------------------------------===// -typedef TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock> - succ_iterator; -typedef TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock> - succ_const_iterator; -typedef iterator_range<succ_iterator> succ_range; -typedef iterator_range<succ_const_iterator> succ_const_range; +using succ_iterator = + TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>; +using succ_const_iterator = + TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>; +using succ_range = iterator_range<succ_iterator>; +using succ_const_range = iterator_range<succ_const_iterator>; inline succ_iterator succ_begin(BasicBlock *BB) { return succ_iterator(BB->getTerminator()); @@ -160,8 +160,8 @@ struct isPodLike<TerminatorInst::SuccIterator<T, U>> { // graph of basic blocks... template <> struct GraphTraits<BasicBlock*> { - typedef BasicBlock *NodeRef; - typedef succ_iterator ChildIteratorType; + using NodeRef = BasicBlock *; + using ChildIteratorType = succ_iterator; static NodeRef getEntryNode(BasicBlock *BB) { return BB; } static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); } @@ -169,8 +169,8 @@ template <> struct GraphTraits<BasicBlock*> { }; template <> struct GraphTraits<const BasicBlock*> { - typedef const BasicBlock *NodeRef; - typedef succ_const_iterator ChildIteratorType; + using NodeRef = const BasicBlock *; + using ChildIteratorType = succ_const_iterator; static NodeRef getEntryNode(const BasicBlock *BB) { return BB; } @@ -184,16 +184,18 @@ template <> struct GraphTraits<const BasicBlock*> { // instead of the successor edges. // template <> struct GraphTraits<Inverse<BasicBlock*>> { - typedef BasicBlock *NodeRef; - typedef pred_iterator ChildIteratorType; + using NodeRef = BasicBlock *; + using ChildIteratorType = pred_iterator; + static NodeRef getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; } static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); } static ChildIteratorType child_end(NodeRef N) { return pred_end(N); } }; template <> struct GraphTraits<Inverse<const BasicBlock*>> { - typedef const BasicBlock *NodeRef; - typedef const_pred_iterator ChildIteratorType; + using NodeRef = const BasicBlock *; + using ChildIteratorType = const_pred_iterator; + static NodeRef getEntryNode(Inverse<const BasicBlock *> G) { return G.Graph; } static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); } static ChildIteratorType child_end(NodeRef N) { return pred_end(N); } @@ -211,7 +213,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> { static NodeRef getEntryNode(Function *F) { return &F->getEntryBlock(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef pointer_iterator<Function::iterator> nodes_iterator; + using nodes_iterator = pointer_iterator<Function::iterator>; static nodes_iterator nodes_begin(Function *F) { return nodes_iterator(F->begin()); @@ -228,7 +230,7 @@ template <> struct GraphTraits<const Function*> : static NodeRef getEntryNode(const Function *F) { return &F->getEntryBlock(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef pointer_iterator<Function::const_iterator> nodes_iterator; + using nodes_iterator = pointer_iterator<Function::const_iterator>; static nodes_iterator nodes_begin(const Function *F) { return nodes_iterator(F->begin()); diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index d61431a51a97..4a806ab501e5 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -207,7 +207,7 @@ public: /// The type of iterator to use when looping over actual arguments at this /// call site. - typedef IterTy arg_iterator; + using arg_iterator = IterTy; iterator_range<IterTy> args() const { return make_range(arg_begin(), arg_end()); @@ -231,7 +231,7 @@ public: /// Type of iterator to use when looping over data operands at this call site /// (see below). - typedef IterTy data_operand_iterator; + using data_operand_iterator = IterTy; /// data_operands_begin/data_operands_end - Return iterators iterating over /// the call / invoke argument list and bundle operands. For invokes, this is diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 604e99c8b52c..39fb3f1c791b 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -1,4 +1,4 @@ -//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- C++ -*-===// +//===- llvm/CallingConv.h - LLVM Calling Conventions ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,8 +20,9 @@ namespace llvm { /// the well-known calling conventions. /// namespace CallingConv { + /// LLVM IR allows to use arbitrary numbers as calling convention identifiers. - typedef unsigned ID; + using ID = unsigned; /// A set of enums which specify the assigned numeric values for known llvm /// calling conventions. @@ -203,8 +204,9 @@ namespace CallingConv { /// The highest possible calling convention ID. Must be some 2^k - 1. MaxID = 1023 }; -} // End CallingConv namespace -} // End llvm namespace +} // end namespace CallingConv + +} // end namespace llvm -#endif +#endif // LLVM_IR_CALLINGCONV_H diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h index fd7f96abb19e..6a50a8801f86 100644 --- a/include/llvm/IR/ConstantRange.h +++ b/include/llvm/IR/ConstantRange.h @@ -41,7 +41,7 @@ namespace llvm { class MDNode; /// This class represents a range of values. -class ConstantRange { +class LLVM_NODISCARD ConstantRange { APInt Lower, Upper; public: @@ -167,7 +167,10 @@ public: APInt getSetSize() const; /// Compare set size of this range with the range CR. - bool isSizeStrictlySmallerThanOf(const ConstantRange &CR) const; + bool isSizeStrictlySmallerThan(const ConstantRange &CR) const; + + // Compare set size of this range with Value. + bool isSizeLargerThan(uint64_t MaxSize) const; /// Return the largest unsigned value contained in the ConstantRange. APInt getUnsignedMax() const; diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h index 1930d48577d4..c1d398f17b59 100644 --- a/include/llvm/IR/DataLayout.h +++ b/include/llvm/IR/DataLayout.h @@ -1,4 +1,4 @@ -//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===// +//===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -20,27 +20,32 @@ #ifndef LLVM_IR_DATALAYOUT_H #define LLVM_IR_DATALAYOUT_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Type.h" #include "llvm/Pass.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include <cassert> +#include <cstdint> +#include <string> // This needs to be outside of the namespace, to avoid conflict with llvm-c // decl. -typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; +using LLVMTargetDataRef = struct LLVMOpaqueTargetData *; namespace llvm { -class Value; -class StructType; -class StructLayout; -class Triple; class GlobalVariable; class LLVMContext; -template<typename T> -class ArrayRef; +class Module; +class StructLayout; +class Triple; +class Value; /// Enum used to categorize the alignment types stored by LayoutAlignElem enum AlignTypeEnum { @@ -72,6 +77,7 @@ struct LayoutAlignElem { static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align, unsigned pref_align, uint32_t bit_width); + bool operator==(const LayoutAlignElem &rhs) const; }; @@ -90,6 +96,7 @@ struct PointerAlignElem { /// Initializer static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign, unsigned PrefAlign, uint32_t TypeByteWidth); + bool operator==(const PointerAlignElem &rhs) const; }; @@ -121,7 +128,7 @@ private: /// \brief Primitive type alignment data. This is sorted by type and bit /// width during construction. - typedef SmallVector<LayoutAlignElem, 16> AlignmentsTy; + using AlignmentsTy = SmallVector<LayoutAlignElem, 16>; AlignmentsTy Alignments; AlignmentsTy::const_iterator @@ -136,7 +143,7 @@ private: /// \brief The string representation used to create this DataLayout std::string StringRepresentation; - typedef SmallVector<PointerAlignElem, 8> PointersTy; + using PointersTy = SmallVector<PointerAlignElem, 8>; PointersTy Pointers; PointersTy::const_iterator @@ -147,7 +154,7 @@ private: PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace); // The StructType -> StructLayout map. - mutable void *LayoutMap; + mutable void *LayoutMap = nullptr; /// Pointers in these address spaces are non-integral, and don't have a /// well-defined bitwise representation. @@ -172,16 +179,16 @@ private: public: /// Constructs a DataLayout from a specification string. See reset(). - explicit DataLayout(StringRef LayoutDescription) : LayoutMap(nullptr) { + explicit DataLayout(StringRef LayoutDescription) { reset(LayoutDescription); } /// Initialize target data from properties stored in the module. explicit DataLayout(const Module *M); - void init(const Module *M); + DataLayout(const DataLayout &DL) { *this = DL; } - DataLayout(const DataLayout &DL) : LayoutMap(nullptr) { *this = DL; } + ~DataLayout(); // Not virtual, do not subclass this class DataLayout &operator=(const DataLayout &DL) { clear(); @@ -200,7 +207,7 @@ public: bool operator==(const DataLayout &Other) const; bool operator!=(const DataLayout &Other) const { return !(*this == Other); } - ~DataLayout(); // Not virtual, do not subclass this class + void init(const Module *M); /// Parse a data layout string (with fallback to default values). void reset(StringRef LayoutDescription); @@ -489,6 +496,7 @@ class StructLayout { unsigned IsPadded : 1; unsigned NumElements : 31; uint64_t MemberOffsets[1]; // variable sized array! + public: uint64_t getSizeInBytes() const { return StructSize; } @@ -515,6 +523,7 @@ public: private: friend class DataLayout; // Only DataLayout can create this class + StructLayout(StructType *ST, const DataLayout &DL); }; @@ -560,6 +569,6 @@ inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const { } } -} // End llvm namespace +} // end namespace llvm -#endif +#endif // LLVM_IR_DATALAYOUT_H diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h index 04f46197b1c3..1d8e7e2855fd 100644 --- a/include/llvm/IR/DebugInfo.h +++ b/include/llvm/IR/DebugInfo.h @@ -21,17 +21,12 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/DebugInfoMetadata.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/Dwarf.h" -#include "llvm/Support/ErrorHandling.h" -#include <iterator> namespace llvm { -class Module; + class DbgDeclareInst; class DbgValueInst; -template <typename K, typename V, typename KeyInfoT, typename BucketT> -class DenseMap; +class Module; /// \brief Find subprogram that is enclosing this scope. DISubprogram *getDISubprogram(const MDNode *Scope); @@ -95,13 +90,13 @@ private: bool addScope(DIScope *Scope); public: - typedef SmallVectorImpl<DICompileUnit *>::const_iterator - compile_unit_iterator; - typedef SmallVectorImpl<DISubprogram *>::const_iterator subprogram_iterator; - typedef SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator - global_variable_expression_iterator; - typedef SmallVectorImpl<DIType *>::const_iterator type_iterator; - typedef SmallVectorImpl<DIScope *>::const_iterator scope_iterator; + using compile_unit_iterator = + SmallVectorImpl<DICompileUnit *>::const_iterator; + using subprogram_iterator = SmallVectorImpl<DISubprogram *>::const_iterator; + using global_variable_expression_iterator = + SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator; + using type_iterator = SmallVectorImpl<DIType *>::const_iterator; + using scope_iterator = SmallVectorImpl<DIScope *>::const_iterator; iterator_range<compile_unit_iterator> compile_units() const { return make_range(CUs.begin(), CUs.end()); @@ -140,4 +135,4 @@ private: } // end namespace llvm -#endif +#endif // LLVM_IR_DEBUGINFO_H diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 8f6c85f53efc..def91e73eb1d 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -42,7 +42,7 @@ extern template void Calculate<Function, Inverse<BasicBlock *>>( DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT, Function &F); -typedef DomTreeNodeBase<BasicBlock> DomTreeNode; +using DomTreeNode = DomTreeNodeBase<BasicBlock>; class BasicBlockEdge { const BasicBlock *Start; @@ -70,7 +70,7 @@ public: }; template <> struct DenseMapInfo<BasicBlockEdge> { - typedef DenseMapInfo<const BasicBlock *> BBInfo; + using BBInfo = DenseMapInfo<const BasicBlock *>; static unsigned getHashValue(const BasicBlockEdge *V); @@ -113,7 +113,7 @@ template <> struct DenseMapInfo<BasicBlockEdge> { /// preceding statements; this is stated only to assist human understanding. class DominatorTree : public DominatorTreeBase<BasicBlock> { public: - typedef DominatorTreeBase<BasicBlock> Base; + using Base = DominatorTreeBase<BasicBlock>; DominatorTree() : DominatorTreeBase<BasicBlock>(false) {} explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) { @@ -168,9 +168,9 @@ public: // iterable by generic graph iterators. template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase { - typedef Node *NodeRef; - typedef ChildIterator ChildIteratorType; - typedef df_iterator<Node *, df_iterator_default_set<Node*>> nodes_iterator; + using NodeRef = Node *; + using ChildIteratorType = ChildIterator; + using nodes_iterator = df_iterator<Node *, df_iterator_default_set<Node*>>; static NodeRef getEntryNode(NodeRef N) { return N; } static ChildIteratorType child_begin(NodeRef N) { return N->begin(); } @@ -212,7 +212,7 @@ class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> { public: /// \brief Provide the result typedef for this analysis pass. - typedef DominatorTree Result; + using Result = DominatorTree; /// \brief Run the analysis pass over a function and produce a dominator tree. DominatorTree run(Function &F, FunctionAnalysisManager &); diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index f9582f51ca8d..c12a125b6352 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -466,7 +466,6 @@ public: /// @brief Determine if the parameter or return value is marked with NoAlias /// attribute. - /// @param n The parameter to check. 1 is the first parameter, 0 is the return bool returnDoesNotAlias() const { return AttributeSets.hasAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h index 5d2f72d211ff..a57e7d63012b 100644 --- a/include/llvm/IR/InlineAsm.h +++ b/include/llvm/IR/InlineAsm.h @@ -95,7 +95,7 @@ public: isClobber // '~x' }; - typedef std::vector<std::string> ConstraintCodeVector; + using ConstraintCodeVector = std::vector<std::string>; struct SubConstraintInfo { /// MatchingInput - If this is not -1, this is an output constraint where an @@ -112,9 +112,9 @@ public: SubConstraintInfo() = default; }; - typedef std::vector<SubConstraintInfo> SubConstraintInfoVector; + using SubConstraintInfoVector = std::vector<SubConstraintInfo>; struct ConstraintInfo; - typedef std::vector<ConstraintInfo> ConstraintInfoVector; + using ConstraintInfoVector = std::vector<ConstraintInfo>; struct ConstraintInfo { /// Type - The basic type of the constraint: input/output/clobber diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h index 28fc473f1490..2988fc935dd5 100644 --- a/include/llvm/IR/InstIterator.h +++ b/include/llvm/IR/InstIterator.h @@ -31,20 +31,20 @@ namespace llvm { // inst_iterator and const_inst_iterator's. // template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator { - typedef BB_t BBty; - typedef BB_i_t BBIty; - typedef BI_t BIty; - typedef II_t IIty; + using BBty = BB_t; + using BBIty = BB_i_t; + using BIty = BI_t; + using IIty = II_t; BB_t *BBs; // BasicBlocksType BB_i_t BB; // BasicBlocksType::iterator BI_t BI; // BasicBlock::iterator public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef IIty value_type; - typedef signed difference_type; - typedef IIty* pointer; - typedef IIty& reference; + using iterator_category = std::bidirectional_iterator_tag; + using value_type = IIty; + using difference_type = signed; + using pointer = IIty *; + using reference = IIty &; // Default constructor InstIterator() = default; @@ -119,13 +119,15 @@ private: } }; -typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator, - BasicBlock::iterator, Instruction> inst_iterator; -typedef InstIterator<const SymbolTableList<BasicBlock>, - Function::const_iterator, BasicBlock::const_iterator, - const Instruction> const_inst_iterator; -typedef iterator_range<inst_iterator> inst_range; -typedef iterator_range<const_inst_iterator> const_inst_range; +using inst_iterator = + InstIterator<SymbolTableList<BasicBlock>, Function::iterator, + BasicBlock::iterator, Instruction>; +using const_inst_iterator = + InstIterator<const SymbolTableList<BasicBlock>, + Function::const_iterator, BasicBlock::const_iterator, + const Instruction>; +using inst_range = iterator_range<inst_iterator>; +using const_inst_range = iterator_range<const_inst_iterator>; inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); } inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); } diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 6795b029cce9..d16a5d318d78 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -1,4 +1,4 @@ -//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- C++ -*-===// +//===- llvm/InstrTypes.h - Important Instruction subclasses -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -29,7 +29,9 @@ #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OperandTraits.h" +#include "llvm/IR/Type.h" #include "llvm/IR/User.h" +#include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -114,17 +116,17 @@ public: template <class Term, class BB> // Successor Iterator class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *> { - typedef std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *> - super; + using super = + std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>; public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; + using pointer = typename super::pointer; + using reference = typename super::reference; private: Term TermInst; unsigned idx; - typedef SuccIterator<Term, BB> Self; + using Self = SuccIterator<Term, BB>; inline bool index_is_valid(unsigned idx) { return idx < TermInst->getNumSuccessors(); @@ -260,11 +262,11 @@ public: } }; - typedef SuccIterator<TerminatorInst *, BasicBlock> succ_iterator; - typedef SuccIterator<const TerminatorInst *, const BasicBlock> - succ_const_iterator; - typedef iterator_range<succ_iterator> succ_range; - typedef iterator_range<succ_const_iterator> succ_const_range; + using succ_iterator = SuccIterator<TerminatorInst *, BasicBlock>; + using succ_const_iterator = + SuccIterator<const TerminatorInst *, const BasicBlock>; + using succ_range = iterator_range<succ_iterator>; + using succ_const_range = iterator_range<succ_const_iterator>; private: inline succ_iterator succ_begin() { return succ_iterator(this); } @@ -341,14 +343,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) class BinaryOperator : public Instruction { protected: - void init(BinaryOps iType); 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; + BinaryOperator *cloneImpl() const; public: @@ -1125,8 +1129,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value) //===----------------------------------------------------------------------===// class FuncletPadInst : public Instruction { private: - void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr); - FuncletPadInst(const FuncletPadInst &CPI); explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, @@ -1136,11 +1138,14 @@ private: ArrayRef<Value *> Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); + void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr); + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; friend class CatchPadInst; friend class CleanupPadInst; + FuncletPadInst *cloneImpl() const; public: @@ -1261,7 +1266,8 @@ public: ArrayRef<InputTy> inputs() const { return Inputs; } - typedef typename std::vector<InputTy>::const_iterator input_iterator; + using input_iterator = typename std::vector<InputTy>::const_iterator; + size_t input_size() const { return Inputs.size(); } input_iterator input_begin() const { return Inputs.begin(); } input_iterator input_end() const { return Inputs.end(); } @@ -1269,8 +1275,8 @@ public: StringRef getTag() const { return Tag; } }; -typedef OperandBundleDefT<Value *> OperandBundleDef; -typedef OperandBundleDefT<const Value *> ConstOperandBundleDef; +using OperandBundleDef = OperandBundleDefT<Value *>; +using ConstOperandBundleDef = OperandBundleDefT<const Value *>; /// \brief A mixin to add operand bundle functionality to llvm instruction /// classes. @@ -1553,8 +1559,8 @@ protected: return OperandBundleUse(BOI.Tag, Inputs); } - typedef BundleOpInfo *bundle_op_iterator; - typedef const BundleOpInfo *const_bundle_op_iterator; + using bundle_op_iterator = BundleOpInfo *; + using const_bundle_op_iterator = const BundleOpInfo *; /// \brief Return the start of the list of BundleOpInfo instances associated /// with this OperandBundleUser. @@ -1654,6 +1660,6 @@ protected: } }; -} // end llvm namespace +} // end namespace llvm #endif // LLVM_IR_INSTRTYPES_H diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index cf7e5d8758a9..7b78d4d3d34a 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -795,6 +795,14 @@ def int_type_checked_load : Intrinsic<[llvm_ptr_ty, llvm_i1_ty], def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty], [IntrReadMem, IntrArgMemOnly]>; +// Xray intrinsics +//===----------------------------------------------------------------------===// +// Custom event logging for x-ray. +// Takes a pointer to a string and the length of the string. +def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], + [NoCapture<0>, ReadOnly<0>, IntrWriteMem]>; +//===----------------------------------------------------------------------===// + //===------ Memory intrinsics with element-wise atomicity guarantees ------===// // diff --git a/include/llvm/IR/IntrinsicsARM.td b/include/llvm/IR/IntrinsicsARM.td index 18ed24be56d4..fe3861301689 100644 --- a/include/llvm/IR/IntrinsicsARM.td +++ b/include/llvm/IR/IntrinsicsARM.td @@ -22,12 +22,26 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.". // and return value are essentially chains, used to force ordering during ISel. def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// 16-bit multiplications +def int_arm_smulbb : GCCBuiltin<"__builtin_arm_smulbb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smulbt : GCCBuiltin<"__builtin_arm_smulbt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smultb : GCCBuiltin<"__builtin_arm_smultb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smultt : GCCBuiltin<"__builtin_arm_smultt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smulwb : GCCBuiltin<"__builtin_arm_smulwb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smulwt : GCCBuiltin<"__builtin_arm_smulwt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + //===----------------------------------------------------------------------===// // Saturating Arithmetic def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], - [IntrNoMem, Commutative]>; + [Commutative, IntrNoMem]>; def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">, @@ -35,6 +49,176 @@ def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">, def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Accumulating multiplications +def int_arm_smlabb : GCCBuiltin<"__builtin_arm_smlabb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlabt : GCCBuiltin<"__builtin_arm_smlabt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlatb : GCCBuiltin<"__builtin_arm_smlatb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlatt : GCCBuiltin<"__builtin_arm_smlatt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlawb : GCCBuiltin<"__builtin_arm_smlawb">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlawt : GCCBuiltin<"__builtin_arm_smlawt">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + +// Parallel 16-bit saturation +def int_arm_ssat16 : GCCBuiltin<"__builtin_arm_ssat16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_usat16 : GCCBuiltin<"__builtin_arm_usat16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + +// Packing and unpacking +def int_arm_sxtab16 : GCCBuiltin<"__builtin_arm_sxtab16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_sxtb16 : GCCBuiltin<"__builtin_arm_sxtb16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; +def int_arm_uxtab16 : GCCBuiltin<"__builtin_arm_uxtab16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uxtb16 : GCCBuiltin<"__builtin_arm_uxtb16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>; + +// Parallel selection, reads the GE flags. +def int_arm_sel : GCCBuiltin<"__builtin_arm_sel">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>; + +// Parallel 8-bit addition and subtraction +def int_arm_qadd8 : GCCBuiltin<"__builtin_arm_qadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_qsub8 : GCCBuiltin<"__builtin_arm_qsub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_sadd8 : GCCBuiltin<"__builtin_arm_sadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_shadd8 : GCCBuiltin<"__builtin_arm_shadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_shsub8 : GCCBuiltin<"__builtin_arm_shsub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_ssub8 : GCCBuiltin<"__builtin_arm_ssub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_uadd8 : GCCBuiltin<"__builtin_arm_uadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_uhadd8 : GCCBuiltin<"__builtin_arm_uhadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uhsub8 : GCCBuiltin<"__builtin_arm_uhsub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqadd8 : GCCBuiltin<"__builtin_arm_uqadd8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqsub8 : GCCBuiltin<"__builtin_arm_uqsub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_usub8 : GCCBuiltin<"__builtin_arm_usub8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; + +// Sum of 8-bit absolute differences +def int_arm_usad8 : GCCBuiltin<"__builtin_arm_usad8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_usada8 : GCCBuiltin<"__builtin_arm_usada8">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + +// Parallel 16-bit addition and subtraction +def int_arm_qadd16 : GCCBuiltin<"__builtin_arm_qadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_qasx : GCCBuiltin<"__builtin_arm_qasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_qsax : GCCBuiltin<"__builtin_arm_qsax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_qsub16 : GCCBuiltin<"__builtin_arm_qsub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_sadd16 : GCCBuiltin<"__builtin_arm_sadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_sasx : GCCBuiltin<"__builtin_arm_sasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_shadd16 : GCCBuiltin<"__builtin_arm_shadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_shasx : GCCBuiltin<"__builtin_arm_shasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_shsax : GCCBuiltin<"__builtin_arm_shsax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_shsub16 : GCCBuiltin<"__builtin_arm_shsub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_ssax : GCCBuiltin<"__builtin_arm_ssax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_ssub16 : GCCBuiltin<"__builtin_arm_ssub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_uadd16 : GCCBuiltin<"__builtin_arm_uadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_uasx : GCCBuiltin<"__builtin_arm_uasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +def int_arm_uhadd16 : GCCBuiltin<"__builtin_arm_uhadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uhasx : GCCBuiltin<"__builtin_arm_uhasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uhsax : GCCBuiltin<"__builtin_arm_uhsax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uhsub16 : GCCBuiltin<"__builtin_arm_uhsub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqadd16 : GCCBuiltin<"__builtin_arm_uqadd16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqasx : GCCBuiltin<"__builtin_arm_uqasx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqsax : GCCBuiltin<"__builtin_arm_uqsax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_uqsub16 : GCCBuiltin<"__builtin_arm_uqsub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +// Writes to the GE bits. +def int_arm_usax : GCCBuiltin<"__builtin_arm_usax">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; +// Writes to the GE bits. +def int_arm_usub16 : GCCBuiltin<"__builtin_arm_usub16">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>; + +// Parallel 16-bit multiplication +def int_arm_smlad : GCCBuiltin<"__builtin_arm_smlad">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smladx : GCCBuiltin<"__builtin_arm_smladx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlald : GCCBuiltin<"__builtin_arm_smlald">, + Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_arm_smlaldx : GCCBuiltin<"__builtin_arm_smlaldx">, + Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_arm_smlsd : GCCBuiltin<"__builtin_arm_smlsd">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlsdx : GCCBuiltin<"__builtin_arm_smlsdx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; +def int_arm_smlsld : GCCBuiltin<"__builtin_arm_smlsld">, + Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_arm_smlsldx : GCCBuiltin<"__builtin_arm_smlsldx">, + Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem]>; +def int_arm_smuad : GCCBuiltin<"__builtin_arm_smuad">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smuadx : GCCBuiltin<"__builtin_arm_smuadx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smusd : GCCBuiltin<"__builtin_arm_smusd">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; +def int_arm_smusdx : GCCBuiltin<"__builtin_arm_smusdx">, + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + + //===----------------------------------------------------------------------===// // Load, Store and Clear exclusive diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index a7274fbfbced..53570bdf16f4 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -45,58 +45,54 @@ struct CalleeInfo { } }; -/// Struct to hold value either by GUID or GlobalValue*. Values in combined -/// indexes as well as indirect calls are GUIDs, all others are GlobalValues. -struct ValueInfo { - /// The value representation used in this instance. - enum ValueInfoKind { - VI_GUID, - VI_Value, - }; +class GlobalValueSummary; - /// Union of the two possible value types. - union ValueUnion { - GlobalValue::GUID Id; - const GlobalValue *GV; - ValueUnion(GlobalValue::GUID Id) : Id(Id) {} - ValueUnion(const GlobalValue *GV) : GV(GV) {} - }; +typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList; - /// The value being represented. - ValueUnion TheValue; - /// The value representation. - ValueInfoKind Kind; - /// Constructor for a GUID value - ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {} - /// Constructor for a GlobalValue* value - ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {} - /// Accessor for GUID value - GlobalValue::GUID getGUID() const { - assert(Kind == VI_GUID && "Not a GUID type"); - return TheValue.Id; - } - /// Accessor for GlobalValue* value - const GlobalValue *getValue() const { - assert(Kind == VI_Value && "Not a Value type"); - return TheValue.GV; - } - bool isGUID() const { return Kind == VI_GUID; } +struct GlobalValueSummaryInfo { + /// The GlobalValue corresponding to this summary. This is only used in + /// per-module summaries. + const GlobalValue *GV = nullptr; + + /// List of global value summary structures for a particular value held + /// in the GlobalValueMap. Requires a vector in the case of multiple + /// COMDAT values of the same name. + GlobalValueSummaryList SummaryList; }; -template <> struct DenseMapInfo<ValueInfo> { - static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); } - static inline ValueInfo getTombstoneKey() { - return ValueInfo((GlobalValue *)-2); +/// Map from global value GUID to corresponding summary structures. Use a +/// std::map rather than a DenseMap so that pointers to the map's value_type +/// (which are used by ValueInfo) are not invalidated by insertion. Also it will +/// likely incur less overhead, as the value type is not very small and the size +/// of the map is unknown, resulting in inefficiencies due to repeated +/// insertions and resizing. +typedef std::map<GlobalValue::GUID, GlobalValueSummaryInfo> + GlobalValueSummaryMapTy; + +/// Struct that holds a reference to a particular GUID in a global value +/// summary. +struct ValueInfo { + const GlobalValueSummaryMapTy::value_type *Ref = nullptr; + ValueInfo() = default; + ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {} + operator bool() const { return Ref; } + + GlobalValue::GUID getGUID() const { return Ref->first; } + const GlobalValue *getValue() const { return Ref->second.GV; } + ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const { + return Ref->second.SummaryList; } - static bool isEqual(ValueInfo L, ValueInfo R) { - if (L.isGUID() != R.isGUID()) - return false; - return L.isGUID() ? (L.getGUID() == R.getGUID()) - : (L.getValue() == R.getValue()); +}; + +template <> struct DenseMapInfo<ValueInfo> { + static inline ValueInfo getEmptyKey() { + return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1); } - static unsigned getHashValue(ValueInfo I) { - return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue(); + static inline ValueInfo getTombstoneKey() { + return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2); } + static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; } + static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; } }; /// \brief Function and variable summary information to aid decisions and @@ -483,19 +479,6 @@ struct TypeIdSummary { /// 160 bits SHA1 typedef std::array<uint32_t, 5> ModuleHash; -/// List of global value summary structures for a particular value held -/// in the GlobalValueMap. Requires a vector in the case of multiple -/// COMDAT values of the same name. -typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList; - -/// Map from global value GUID to corresponding summary structures. -/// Use a std::map rather than a DenseMap since it will likely incur -/// less overhead, as the value type is not very small and the size -/// of the map is unknown, resulting in inefficiencies due to repeated -/// insertions and resizing. -typedef std::map<GlobalValue::GUID, GlobalValueSummaryList> - GlobalValueSummaryMapTy; - /// Type used for iterating through the global value summary map. typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator; typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator; @@ -532,6 +515,11 @@ private: // YAML I/O support. friend yaml::MappingTraits<ModuleSummaryIndex>; + GlobalValueSummaryMapTy::value_type * + getOrInsertValuePtr(GlobalValue::GUID GUID) { + return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo{}).first; + } + public: gvsummary_iterator begin() { return GlobalValueMap.begin(); } const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); } @@ -539,21 +527,22 @@ public: const_gvsummary_iterator end() const { return GlobalValueMap.end(); } size_t size() const { return GlobalValueMap.size(); } - /// Get the list of global value summary objects for a given value name. - const GlobalValueSummaryList &getGlobalValueSummaryList(StringRef ValueName) { - return GlobalValueMap[GlobalValue::getGUID(ValueName)]; + /// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo(). + ValueInfo getValueInfo(GlobalValue::GUID GUID) const { + auto I = GlobalValueMap.find(GUID); + return ValueInfo(I == GlobalValueMap.end() ? nullptr : &*I); } - /// Get the list of global value summary objects for a given value name. - const const_gvsummary_iterator - findGlobalValueSummaryList(StringRef ValueName) const { - return GlobalValueMap.find(GlobalValue::getGUID(ValueName)); + /// Return a ValueInfo for \p GUID. + ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) { + return ValueInfo(getOrInsertValuePtr(GUID)); } - /// Get the list of global value summary objects for a given value GUID. - const const_gvsummary_iterator - findGlobalValueSummaryList(GlobalValue::GUID ValueGUID) const { - return GlobalValueMap.find(ValueGUID); + /// Return a ValueInfo for \p GV and mark it as belonging to GV. + ValueInfo getOrInsertValueInfo(const GlobalValue *GV) { + auto VP = getOrInsertValuePtr(GV->getGUID()); + VP->second.GV = GV; + return ValueInfo(VP); } /// Return the GUID for \p OriginalId in the OidGuidMap. @@ -565,17 +554,18 @@ public: /// Add a global value summary for a value of the given name. void addGlobalValueSummary(StringRef ValueName, std::unique_ptr<GlobalValueSummary> Summary) { - addOriginalName(GlobalValue::getGUID(ValueName), - Summary->getOriginalName()); - GlobalValueMap[GlobalValue::getGUID(ValueName)].push_back( - std::move(Summary)); + addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)), + std::move(Summary)); } - /// Add a global value summary for a value of the given GUID. - void addGlobalValueSummary(GlobalValue::GUID ValueGUID, + /// Add a global value summary for the given ValueInfo. + void addGlobalValueSummary(ValueInfo VI, std::unique_ptr<GlobalValueSummary> Summary) { - addOriginalName(ValueGUID, Summary->getOriginalName()); - GlobalValueMap[ValueGUID].push_back(std::move(Summary)); + addOriginalName(VI.getGUID(), Summary->getOriginalName()); + // Here we have a notionally const VI, but the value it points to is owned + // by the non-const *this. + const_cast<GlobalValueSummaryMapTy::value_type *>(VI.Ref) + ->second.SummaryList.push_back(std::move(Summary)); } /// Add an original name for the value of the given GUID. @@ -593,16 +583,16 @@ public: /// not found. GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID, StringRef ModuleId) const { - auto CalleeInfoList = findGlobalValueSummaryList(ValueGUID); - if (CalleeInfoList == end()) { + auto CalleeInfo = getValueInfo(ValueGUID); + if (!CalleeInfo) { return nullptr; // This function does not have a summary } auto Summary = - llvm::find_if(CalleeInfoList->second, + llvm::find_if(CalleeInfo.getSummaryList(), [&](const std::unique_ptr<GlobalValueSummary> &Summary) { return Summary->modulePath() == ModuleId; }); - if (Summary == CalleeInfoList->second.end()) + if (Summary == CalleeInfo.getSummaryList().end()) return nullptr; return Summary->get(); } diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h index 80719c696935..78fdb602027d 100644 --- a/include/llvm/IR/ModuleSummaryIndexYAML.h +++ b/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -201,7 +201,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { for (auto &FSum : FSums) { GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false, false); - Elem.push_back(llvm::make_unique<FunctionSummary>( + Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>( GVFlags, 0, ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests), std::move(FSum.TypeTestAssumeVCalls), @@ -213,7 +213,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> { static void output(IO &io, GlobalValueSummaryMapTy &V) { for (auto &P : V) { std::vector<FunctionSummaryYaml> FSums; - for (auto &Sum : P.second) { + for (auto &Sum : P.second.SummaryList) { if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) FSums.push_back(FunctionSummaryYaml{ FSum->type_tests(), FSum->type_test_assume_vcalls(), diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h index c34211c2bd12..5d4e32a672dd 100644 --- a/include/llvm/MC/ConstantPools.h +++ b/include/llvm/MC/ConstantPools.h @@ -63,6 +63,8 @@ public: // Return true if the constant pool is empty bool empty(); + + void clearCache(); }; class AssemblerConstantPools { @@ -86,6 +88,7 @@ class AssemblerConstantPools { public: void emitAll(MCStreamer &Streamer); void emitForCurrentSection(MCStreamer &Streamer); + void clearCacheForCurrentSection(MCStreamer &Streamer); const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr, unsigned Size, SMLoc Loc); diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 1b6aaf4be666..8b9b49737170 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -20,7 +20,9 @@ #include "llvm/Object/Binary.h" #include "llvm/Object/Error.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/BinaryByteStream.h" #include "llvm/Support/COFF.h" +#include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" @@ -40,6 +42,7 @@ class DelayImportDirectoryEntryRef; class ExportDirectoryEntryRef; class ImportDirectoryEntryRef; class ImportedSymbolRef; +class ResourceSectionRef; using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>; using delay_import_directory_iterator = @@ -623,6 +626,26 @@ struct coff_base_reloc_block_entry { int getOffset() const { return Data & ((1 << 12) - 1); } }; +struct coff_resource_dir_entry { + union { + support::ulittle32_t NameOffset; + support::ulittle32_t ID; + uint32_t getNameOffset() const { + return maskTrailingOnes<uint32_t>(31) & NameOffset; + } + } Identifier; + union { + support::ulittle32_t DataEntryOffset; + support::ulittle32_t SubdirOffset; + + bool isSubDir() const { return SubdirOffset >> 31; } + uint32_t value() const { + return maskTrailingOnes<uint32_t>(31) & SubdirOffset; + } + + } Offset; +}; + struct coff_resource_dir_table { support::ulittle32_t Characteristics; support::ulittle32_t TimeDateStamp; @@ -1047,6 +1070,23 @@ private: const COFFObjectFile *OwningObject = nullptr; }; +class ResourceSectionRef { +public: + ResourceSectionRef() = default; + explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {} + + ErrorOr<ArrayRef<UTF16>> getEntryNameString(const coff_resource_dir_entry &Entry); + ErrorOr<const coff_resource_dir_table &> + getEntrySubDir(const coff_resource_dir_entry &Entry); + ErrorOr<const coff_resource_dir_table &> getBaseTable(); + +private: + BinaryByteStream BBS; + + ErrorOr<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset); + ErrorOr<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset); +}; + // Corresponds to `_FPO_DATA` structure in the PE/COFF spec. struct FpoData { support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 6b6bbe252f65..4bc39d98b7af 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -41,10 +41,14 @@ public: DEBUG_FUNCTION_NAME, }; - WasmSymbol(StringRef Name, SymbolType Type) : Name(Name), Type(Type) {} + WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, + uint32_t ElementIndex) + : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {} StringRef Name; SymbolType Type; + uint32_t Section; + uint32_t ElementIndex; }; class WasmSection { diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index dfeeb8589f82..bd7d72be4dbc 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -97,6 +97,11 @@ struct DataSegment { yaml::BinaryRef Content; }; +struct NameEntry { + uint32_t Index; + StringRef Name; +}; + struct Signature { Signature() : Form(wasm::WASM_TYPE_FUNC) {} @@ -122,6 +127,11 @@ struct CustomSection : Section { StringRef Name; yaml::BinaryRef Payload; + + // 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 TypeSection : Section { @@ -244,6 +254,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global) 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_FLOW_SEQUENCE_VECTOR(uint32_t) namespace llvm { @@ -297,6 +308,10 @@ template <> struct MappingTraits<WasmYAML::Relocation> { static void mapping(IO &IO, WasmYAML::Relocation &Relocation); }; +template <> struct MappingTraits<WasmYAML::NameEntry> { + static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); +}; + template <> struct MappingTraits<WasmYAML::LocalDecl> { static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl); }; diff --git a/include/llvm/Support/AArch64TargetParser.def b/include/llvm/Support/AArch64TargetParser.def index 1700deadeaef..8eccebcd932a 100644 --- a/include/llvm/Support/AArch64TargetParser.def +++ b/include/llvm/Support/AArch64TargetParser.def @@ -20,8 +20,7 @@ AARCH64_ARCH("invalid", AK_INVALID, nullptr, nullptr, ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE) AARCH64_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, - (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | - AArch64::AEK_SIMD)) + (AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD)) AARCH64_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a", ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8, (AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | @@ -52,38 +51,37 @@ AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras") #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) #endif AARCH64_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true, - ( AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRYPTO)) + (AArch64::AEK_NONE)) AARCH64_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("exynos-m2", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("exynos-m3", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("falkor", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO)) + (AArch64::AEK_CRC)) AARCH64_CPU_NAME("thunderx2t99", AK_ARMV8_1A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_CRC | - AArch64::AEK_CRYPTO)) + (AArch64::AEK_NONE)) AARCH64_CPU_NAME("thunderx", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE)) + (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) AARCH64_CPU_NAME("thunderxt88", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE)) + (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) AARCH64_CPU_NAME("thunderxt81", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE)) + (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) AARCH64_CPU_NAME("thunderxt83", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, - (AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE)) + (AArch64::AEK_CRC | AArch64::AEK_PROFILE)) // Invalid CPU AARCH64_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AArch64::AEK_INVALID) #undef AARCH64_CPU_NAME diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h index f141c30f16c7..bad31cd38d6a 100644 --- a/include/llvm/Support/BinaryStreamArray.h +++ b/include/llvm/Support/BinaryStreamArray.h @@ -64,8 +64,10 @@ class VarStreamArrayIterator public: VarStreamArrayIterator() = default; VarStreamArrayIterator(const ArrayType &Array, const WrappedCtx &Ctx, - BinaryStreamRef Stream, bool *HadError = nullptr) - : IterRef(Stream), Ctx(&Ctx), Array(&Array), HadError(HadError) { + BinaryStreamRef Stream, bool *HadError = nullptr, + uint32_t Offset = 0) + : IterRef(Stream), Ctx(&Ctx), Array(&Array), AbsOffset(Offset), + HadError(HadError) { if (IterRef.getLength() == 0) moveToEnd(); else { @@ -115,6 +117,7 @@ public: for (unsigned I = 0; I < N; ++I) { // We are done with the current record, discard it so that we are // positioned at the next record. + AbsOffset += ThisLen; IterRef = IterRef.drop_front(ThisLen); if (IterRef.getLength() == 0) { // There is nothing after the current record, we must make this an end @@ -135,6 +138,8 @@ public: return *this; } + uint32_t offset() const { return AbsOffset; } + private: void moveToEnd() { Array = nullptr; @@ -152,6 +157,7 @@ private: const WrappedCtx *Ctx{nullptr}; const ArrayType *Array{nullptr}; uint32_t ThisLen{0}; + uint32_t AbsOffset{0}; bool HasError{false}; bool *HadError{nullptr}; }; @@ -234,7 +240,7 @@ public: /// since the behavior is undefined if \p Offset does not refer to the /// beginning of a valid record. Iterator at(uint32_t Offset) const { - return Iterator(*this, Ctx, Stream.drop_front(Offset), nullptr); + return Iterator(*this, Ctx, Stream.drop_front(Offset), nullptr, Offset); } BinaryStreamRef getUnderlyingStream() const { return Stream; } @@ -338,7 +344,7 @@ private: template <typename T> class FixedStreamArrayIterator : public iterator_facade_base<FixedStreamArrayIterator<T>, - std::random_access_iterator_tag, T> { + std::random_access_iterator_tag, const T> { public: FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index) @@ -352,6 +358,7 @@ public: } const T &operator*() const { return Array[Index]; } + const T &operator*() { return Array[Index]; } bool operator==(const FixedStreamArrayIterator<T> &R) const { assert(Array == R.Array); diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index 19223306bd07..bc2098e2b5cf 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -152,6 +152,30 @@ namespace COFF { IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 }; + enum ResourceTypeID { + RID_Cursor = 1, + RID_Bitmap = 2, + RID_Icon = 3, + RID_Menu = 4, + RID_Dialog = 5, + RID_String = 6, + RID_FontDir = 7, + RID_Font = 8, + RID_Accelerator = 9, + RID_RCData = 10, + RID_MessageTable = 11, + RID_Group_Cursor = 12, + RID_Group_Icon = 14, + RID_Version = 16, + RID_DLGInclude = 17, + RID_PlugPlay = 19, + RID_VXD = 20, + RID_AniCursor = 21, + RID_AniIcon = 22, + RID_HTML = 23, + RID_Manifest = 24, + }; + struct symbol { char Name[NameSize]; uint32_t Value; @@ -349,6 +373,26 @@ namespace COFF { IMAGE_REL_ARM_BLX23T = 0x0015 }; + enum RelocationTypesARM64 { + IMAGE_REL_ARM64_ABSOLUTE = 0x0000, + IMAGE_REL_ARM64_ADDR32 = 0x0001, + IMAGE_REL_ARM64_ADDR32NB = 0x0002, + IMAGE_REL_ARM64_BRANCH26 = 0x0003, + IMAGE_REL_ARM64_PAGEBASE_REL2 = 0x0004, + IMAGE_REL_ARM64_REL21 = 0x0005, + IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006, + IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007, + IMAGE_REL_ARM64_SECREL = 0x0008, + IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009, + IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A, + IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B, + IMAGE_REL_ARM64_TOKEN = 0x000C, + IMAGE_REL_ARM64_SECTION = 0x000D, + IMAGE_REL_ARM64_ADDR64 = 0x000E, + IMAGE_REL_ARM64_BRANCH19 = 0x000F, + IMAGE_REL_ARM64_BRANCH14 = 0x0010, + }; + enum COMDATType { IMAGE_COMDAT_SELECT_NODUPLICATES = 1, IMAGE_COMDAT_SELECT_ANY, diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h index 292ea9e4b717..3d38cf878538 100644 --- a/include/llvm/Support/KnownBits.h +++ b/include/llvm/Support/KnownBits.h @@ -24,6 +24,12 @@ struct KnownBits { APInt Zero; APInt One; +private: + // Internal constructor for creating a ConstantRange from two APInts. + KnownBits(APInt Zero, APInt One) + : Zero(std::move(Zero)), One(std::move(One)) {} + +public: // Default construct Zero and One. KnownBits() {} @@ -37,6 +43,55 @@ struct KnownBits { return Zero.getBitWidth(); } + /// Returns true if there is conflicting information. + bool hasConflict() const { return Zero.intersects(One); } + + /// Returns true if we know the value of all bits. + bool isConstant() const { + assert(!hasConflict() && "KnownBits conflict!"); + return Zero.countPopulation() + One.countPopulation() == getBitWidth(); + } + + /// Returns the value when all bits have a known value. This just returns One + /// with a protective assertion. + const APInt &getConstant() const { + assert(isConstant() && "Can only get value when all bits are known"); + return One; + } + + /// Returns true if we don't know any bits. + bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); } + + /// Resets the known state of all bits. + void resetAll() { + Zero.clearAllBits(); + One.clearAllBits(); + } + + /// Returns true if value is all zero. + bool isZero() const { + assert(!hasConflict() && "KnownBits conflict!"); + return Zero.isAllOnesValue(); + } + + /// Returns true if value is all one bits. + bool isAllOnes() const { + assert(!hasConflict() && "KnownBits conflict!"); + return One.isAllOnesValue(); + } + + /// Make all bits known to be zero and discard any previous information. + void setAllZero() { + Zero.setAllBits(); + One.clearAllBits(); + } + + /// Make all bits known to be one and discard any previous information. + void setAllOnes() { + Zero.clearAllBits(); + One.setAllBits(); + } + /// Returns true if this value is known to be negative. bool isNegative() const { return One.isSignBitSet(); } @@ -54,6 +109,30 @@ struct KnownBits { assert(!isNegative() && "Can't make a negative value non-negative"); Zero.setSignBit(); } + + /// Truncate the underlying known Zero and One bits. This is equivalent + /// to truncating the value we're tracking. + KnownBits trunc(unsigned BitWidth) { + return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth)); + } + + /// Zero extends the underlying known Zero and One bits. This is equivalent + /// to zero extending the value we're tracking. + KnownBits zext(unsigned BitWidth) { + return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth)); + } + + /// Sign extends the underlying known Zero and One bits. This is equivalent + /// to sign extending the value we're tracking. + KnownBits sext(unsigned BitWidth) { + return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth)); + } + + /// Zero extends or truncates the underlying known Zero and One bits. This is + /// equivalent to zero extending or truncating the value we're tracking. + KnownBits zextOrTrunc(unsigned BitWidth) { + return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth)); + } }; } // end namespace llvm diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 994456f9a681..7f07e8cc3a51 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -214,6 +214,18 @@ template <typename T> T maskLeadingOnes(unsigned N) { return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); } +/// \brief Create a bitmask with the N right-most bits set to 0, and all other +/// bits set to 1. Only unsigned types are allowed. +template <typename T> T maskTrailingZeros(unsigned N) { + return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N); +} + +/// \brief Create a bitmask with the N left-most bits set to 0, and all other +/// bits set to 1. Only unsigned types are allowed. +template <typename T> T maskLeadingZeros(unsigned N) { + return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N); +} + /// \brief Get the index of the last set bit starting from the least /// significant bit. /// diff --git a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index 9f034220815f..a06c67fe814c 100644 --- a/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -25,25 +25,43 @@ class GINodeEquiv<Instruction i, SDNode node> { SDNode Node = node; } -def : GINodeEquiv<G_ZEXT, zext>; +// These are defined in the same order as the G_* instructions. +def : GINodeEquiv<G_ANYEXT, anyext>; def : GINodeEquiv<G_SEXT, sext>; +def : GINodeEquiv<G_ZEXT, zext>; +def : GINodeEquiv<G_TRUNC, trunc>; +def : GINodeEquiv<G_BITCAST, bitconvert>; +// G_INTTOPTR - SelectionDAG has no equivalent. +// G_PTRTOINT - SelectionDAG has no equivalent. +// G_CONSTANT - Not needed since constants aren't operators. +// G_FCONSTANT - Not needed since constants aren't operators. def : GINodeEquiv<G_ADD, add>; def : GINodeEquiv<G_SUB, sub>; def : GINodeEquiv<G_MUL, mul>; - +def : GINodeEquiv<G_SDIV, sdiv>; +def : GINodeEquiv<G_UDIV, udiv>; +def : GINodeEquiv<G_SREM, srem>; +def : GINodeEquiv<G_UREM, urem>; +def : GINodeEquiv<G_AND, and>; def : GINodeEquiv<G_OR, or>; def : GINodeEquiv<G_XOR, xor>; -def : GINodeEquiv<G_AND, and>; - def : GINodeEquiv<G_SHL, shl>; def : GINodeEquiv<G_LSHR, srl>; def : GINodeEquiv<G_ASHR, sra>; - -def : GINodeEquiv<G_SDIV, sdiv>; -def : GINodeEquiv<G_UDIV, udiv>; -def : GINodeEquiv<G_SREM, srem>; -def : GINodeEquiv<G_UREM, urem>; - +def : GINodeEquiv<G_SELECT, select>; +def : GINodeEquiv<G_FNEG, fneg>; +def : GINodeEquiv<G_FPEXT, fpextend>; +def : GINodeEquiv<G_FPTRUNC, ftrunc>; +def : GINodeEquiv<G_FPTOSI, fp_to_sint>; +def : GINodeEquiv<G_FPTOUI, fp_to_uint>; +def : GINodeEquiv<G_SITOFP, sint_to_fp>; +def : GINodeEquiv<G_UITOFP, uint_to_fp>; +def : GINodeEquiv<G_FADD, fadd>; +def : GINodeEquiv<G_FSUB, fsub>; +def : GINodeEquiv<G_FMUL, fmul>; +def : GINodeEquiv<G_FDIV, fdiv>; +def : GINodeEquiv<G_FREM, frem>; +def : GINodeEquiv<G_FPOW, fpow>; def : GINodeEquiv<G_BR, br>; // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index d7fbca93f59b..fc35b4527bc3 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -1002,6 +1002,16 @@ def PATCHABLE_TAIL_CALL : Instruction { let hasSideEffects = 1; let isReturn = 1; } +def PATCHABLE_EVENT_CALL : Instruction { + let OutOperandList = (outs); + let InOperandList = (ins ptr_rc:$event, i8imm:$size); + let AsmString = "# XRay Custom Event Log."; + let usesCustomInserter = 1; + let isCall = 1; + let mayLoad = 1; + let mayStore = 1; + let hasSideEffects = 1; +} def FENTRY_CALL : Instruction { let OutOperandList = (outs unknown:$dst); let InOperandList = (ins variable_ops); diff --git a/include/llvm/Target/TargetOpcodes.def b/include/llvm/Target/TargetOpcodes.def index 96db6e0a9769..36764249632d 100644 --- a/include/llvm/Target/TargetOpcodes.def +++ b/include/llvm/Target/TargetOpcodes.def @@ -182,6 +182,10 @@ HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_EXIT) /// PATCHABLE_RET which specifically only works for return instructions. HANDLE_TARGET_OPCODE(PATCHABLE_TAIL_CALL) +/// Wraps a logging call and its arguments with nop sleds. At runtime, this can be +/// patched to insert instrumentation instructions. +HANDLE_TARGET_OPCODE(PATCHABLE_EVENT_CALL) + /// The following generic opcodes are not supposed to appear after ISel. /// This is something we might want to relax, but for now, this is convenient /// to produce diagnostics. diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index db6723da1e61..023d7af7f729 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -177,6 +177,7 @@ struct SanitizerCoverageOptions { bool Use8bitCounters = false; bool TracePC = false; bool TracePCGuard = false; + bool NoPrune = false; SanitizerCoverageOptions() = default; }; diff --git a/include/llvm/Transforms/Scalar/Float2Int.h b/include/llvm/Transforms/Scalar/Float2Int.h index a8042399fb08..206ee980109b 100644 --- a/include/llvm/Transforms/Scalar/Float2Int.h +++ b/include/llvm/Transforms/Scalar/Float2Int.h @@ -31,7 +31,7 @@ public: private: void findRoots(Function &F, SmallPtrSet<Instruction *, 8> &Roots); - ConstantRange seen(Instruction *I, ConstantRange R); + void seen(Instruction *I, ConstantRange R); ConstantRange badRange(); ConstantRange unknownRange(); ConstantRange validateRange(ConstantRange R); |