From c46e6a5940c50058e00c0c5f9123fd82e338d29a Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Mon, 8 May 2017 17:12:57 +0000 Subject: Vendor import of llvm trunk r302418: https://llvm.org/svn/llvm-project/llvm/trunk@302418 --- include/llvm/ADT/APInt.h | 11 + include/llvm/ADT/BitVector.h | 33 +- include/llvm/ADT/SmallBitVector.h | 18 ++ include/llvm/Analysis/LoopInfoImpl.h | 16 +- include/llvm/Analysis/ProfileSummaryInfo.h | 12 + include/llvm/Analysis/ScalarEvolution.h | 12 +- include/llvm/Analysis/TargetLibraryInfo.def | 3 + include/llvm/CodeGen/AsmPrinter.h | 3 +- include/llvm/CodeGen/FastISel.h | 1 + include/llvm/CodeGen/FunctionLoweringInfo.h | 2 +- include/llvm/CodeGen/GlobalISel/IRTranslator.h | 2 +- include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 6 +- include/llvm/CodeGen/GlobalISel/RegBankSelect.h | 10 +- include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h | 54 +++- include/llvm/CodeGen/MIRPrinter.h | 46 +++ include/llvm/CodeGen/MachineFrameInfo.h | 8 + include/llvm/CodeGen/MachineModuleInfo.h | 2 +- include/llvm/DebugInfo/CodeView/TypeDatabase.h | 2 +- include/llvm/DebugInfo/DWARF/DWARFContext.h | 5 + include/llvm/DebugInfo/DWARF/DWARFFormValue.h | 331 ++++++++++----------- .../DebugInfo/PDB/Native/DbiModuleDescriptor.h | 8 - include/llvm/DebugInfo/PDB/Native/DbiModuleList.h | 114 +++++++ include/llvm/DebugInfo/PDB/Native/DbiStream.h | 13 +- .../DebugInfo/PDB/Native/NativeCompilandSymbol.h | 4 +- .../llvm/DebugInfo/PDB/Native/NativeEnumModules.h | 8 +- include/llvm/DebugInfo/PDB/Native/RawTypes.h | 11 +- include/llvm/DebugInfo/PDB/Native/TpiStream.h | 6 +- .../llvm/ExecutionEngine/Orc/RPCSerialization.h | 4 +- include/llvm/ExecutionEngine/RuntimeDyldChecker.h | 6 + include/llvm/IR/Attributes.h | 15 +- include/llvm/IR/BasicBlock.h | 13 +- include/llvm/IR/CFG.h | 54 ++-- include/llvm/IR/CallSite.h | 4 +- include/llvm/IR/CallingConv.h | 12 +- include/llvm/IR/ConstantRange.h | 7 +- include/llvm/IR/DataLayout.h | 45 +-- include/llvm/IR/DebugInfo.h | 25 +- include/llvm/IR/Dominators.h | 14 +- include/llvm/IR/Function.h | 1 - include/llvm/IR/InlineAsm.h | 6 +- include/llvm/IR/InstIterator.h | 34 ++- include/llvm/IR/InstrTypes.h | 46 +-- include/llvm/IR/Intrinsics.td | 8 + include/llvm/IR/IntrinsicsARM.td | 186 +++++++++++- include/llvm/IR/ModuleSummaryIndex.h | 152 +++++----- include/llvm/IR/ModuleSummaryIndexYAML.h | 4 +- include/llvm/MC/ConstantPools.h | 3 + include/llvm/Object/COFF.h | 40 +++ include/llvm/Object/Wasm.h | 6 +- include/llvm/ObjectYAML/WasmYAML.h | 15 + include/llvm/Support/AArch64TargetParser.def | 36 ++- include/llvm/Support/BinaryStreamArray.h | 15 +- include/llvm/Support/COFF.h | 44 +++ include/llvm/Support/KnownBits.h | 79 +++++ include/llvm/Support/MathExtras.h | 12 + .../llvm/Target/GlobalISel/SelectionDAGCompat.td | 38 ++- include/llvm/Target/Target.td | 10 + include/llvm/Target/TargetOpcodes.def | 4 + include/llvm/Transforms/Instrumentation.h | 1 + include/llvm/Transforms/Scalar/Float2Int.h | 2 +- 60 files changed, 1201 insertions(+), 481 deletions(-) create mode 100644 include/llvm/CodeGen/MIRPrinter.h create mode 100644 include/llvm/DebugInfo/PDB/Native/DbiModuleList.h (limited to 'include') 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(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(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(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::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 VisitedBBs; // Check the individual blocks. for ( ; BI != BE; ++BI) { @@ -259,10 +259,18 @@ void LoopBase::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 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 &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 &Terms, SmallVectorImpl &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 Sleds; + SmallVector 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 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 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, 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 &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 InstructionMappings; + typedef SmallVector 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> MapOfPartialMappings; + mutable DenseMap> + MapOfPartialMappings; /// Keep dynamically allocated ValueMapping in a separate map. /// This shouldn't be needed when everything gets TableGen'ed. - mutable DenseMap > MapOfValueMappings; + mutable DenseMap> + MapOfValueMappings; /// Keep dynamically allocated array of ValueMapping in a separate map. /// This shouldn't be needed when everything gets TableGen'ed. - mutable DenseMap> MapOfOperandsMappings; + mutable DenseMap> + MapOfOperandsMappings; + + /// Keep dynamically allocated InstructionMapping in a separate map. + /// This shouldn't be needed when everything gets TableGen'ed. + mutable DenseMap> + 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 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 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 &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 toString(const Optional& 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& 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 toUnsigned(const Optional& 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& 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 toReference(const Optional& 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& 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 toSigned(const Optional& 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& 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 toAddress(const Optional& 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& 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 toSectionOffset(const Optional& 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& 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> - toBlock(const Optional& 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 toString(const Optional &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 &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 toUnsigned(const Optional &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 &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 toReference(const Optional &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 &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 toSigned(const Optional &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 &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 toAddress(const Optional &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 &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 toSectionOffset(const Optional &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 &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> toBlock(const Optional &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 SourceFiles; -}; - } // end namespace pdb template <> struct VarStreamArrayExtractor { 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 +#include + +namespace llvm { +namespace pdb { + +class DbiModuleList; +struct FileInfoSubstreamHeader; + +class DbiModuleSourceFilesIterator + : public iterator_facade_base { + typedef iterator_facade_base + 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 getFileName(uint32_t Index) const; + uint32_t getModuleCount() const; + uint32_t getSourceFileCount() const; + uint16_t getSourceFileCount(uint32_t Modi) const; + + iterator_range + source_files(uint32_t Modi) const; + + DbiModuleDescriptor getModuleDescriptor(uint32_t Modi) const; + +private: + Error initializeModInfo(BinaryStreamRef ModInfo); + Error initializeFileInfo(BinaryStreamRef FileInfo); + + VarStreamArray Descriptors; + + FixedStreamArray FileNameOffsets; + FixedStreamArray 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 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 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 modules() const; - - Expected getFileNameForIndex(uint32_t Index) const; + const DbiModuleList &modules() const; FixedStreamArray 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 Stream; - std::vector ModuleInfos; PDBStringTable ECNames; - BinaryStreamRef ModInfoSubstream; BinaryStreamRef SecContrSubstream; BinaryStreamRef SecMapSubstream; - BinaryStreamRef FileInfoSubstream; BinaryStreamRef TypeServerMapSubstream; BinaryStreamRef ECSubstream; - BinaryStreamRef NamesBuffer; + DbiModuleList Modules; FixedStreamArray DbgStreams; @@ -108,7 +102,6 @@ private: FixedStreamArray SectionContribs; FixedStreamArray SectionContribs2; FixedStreamArray SectionMap; - FixedStreamArray FileNameOffsets; std::unique_ptr SectionHeaderStream; FixedStreamArray 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 { public: - explicit NativeEnumModules(NativeSession &Session, - ArrayRef Modules, - uint32_t Index = 0); + NativeEnumModules(NativeSession &Session, const DbiModuleList &Modules, + uint32_t Index = 0); uint32_t getChildCount() const override; std::unique_ptr getChildAtIndex(uint32_t Index) const override; @@ -32,7 +32,7 @@ public: private: NativeSession &Session; - ArrayRef 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 getHashValues() const; FixedStreamArray getTypeIndexOffsets() const; HashTable &getHashAdjusters(); @@ -55,8 +55,6 @@ public: Error commit(); private: - Error verifyHashValues(); - const PDBFile &Pdb; std::unique_ptr 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 Lock(SerializersMutex); @@ -370,7 +370,7 @@ public: }; } } - + static Error serialize(ChannelT &C, Error &&Err) { std::lock_guard 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 #include #include @@ -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 getSectionLoadAddress(void *LocalAddress) const; + private: std::unique_ptr 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> 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::iterator iterator; + using iterator = ArrayRef::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 td_type; - typedef std::map::iterator td_iterator; - typedef std::map::const_iterator td_const_iterator; - typedef iterator_range td_range; - typedef iterator_range td_const_range; + using td_type = std::pair; + using td_iterator = std::map::iterator; + using td_const_iterator = std::map::const_iterator; + using td_range = iterator_range; + using td_const_range = iterator_range; 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 #include @@ -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 { public: - typedef SymbolTableList InstListType; + using InstListType = SymbolTableList; 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 // Predecessor Iterator class PredIterator : public std::iterator { - typedef std::iterator super; - typedef PredIterator Self; + using super = + std::iterator; + using Self = PredIterator; USE_iterator It; inline void advancePastNonTerminators() { @@ -49,8 +49,8 @@ class PredIterator : public std::iteratoruser_begin()) { @@ -90,11 +90,11 @@ public: } }; -typedef PredIterator pred_iterator; -typedef PredIterator const_pred_iterator; -typedef iterator_range pred_range; -typedef iterator_range pred_const_range; +using pred_iterator = PredIterator; +using const_pred_iterator = + PredIterator; +using pred_range = iterator_range; +using pred_const_range = iterator_range; 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 - succ_iterator; -typedef TerminatorInst::SuccIterator - succ_const_iterator; -typedef iterator_range succ_range; -typedef iterator_range succ_const_range; +using succ_iterator = + TerminatorInst::SuccIterator; +using succ_const_iterator = + TerminatorInst::SuccIterator; +using succ_range = iterator_range; +using succ_const_range = iterator_range; inline succ_iterator succ_begin(BasicBlock *BB) { return succ_iterator(BB->getTerminator()); @@ -160,8 +160,8 @@ struct isPodLike> { // graph of basic blocks... template <> struct GraphTraits { - 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 { }; template <> struct GraphTraits { - 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 { // instead of the successor edges. // template <> struct GraphTraits> { - typedef BasicBlock *NodeRef; - typedef pred_iterator ChildIteratorType; + using NodeRef = BasicBlock *; + using ChildIteratorType = pred_iterator; + static NodeRef getEntryNode(Inverse 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> { - typedef const BasicBlock *NodeRef; - typedef const_pred_iterator ChildIteratorType; + using NodeRef = const BasicBlock *; + using ChildIteratorType = const_pred_iterator; + static NodeRef getEntryNode(Inverse 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 : public GraphTraits { static NodeRef getEntryNode(Function *F) { return &F->getEntryBlock(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef pointer_iterator nodes_iterator; + using nodes_iterator = pointer_iterator; static nodes_iterator nodes_begin(Function *F) { return nodes_iterator(F->begin()); @@ -228,7 +230,7 @@ template <> struct GraphTraits : static NodeRef getEntryNode(const Function *F) { return &F->getEntryBlock(); } // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef pointer_iterator nodes_iterator; + using nodes_iterator = pointer_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 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 +#include +#include // 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 -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 AlignmentsTy; + using AlignmentsTy = SmallVector; AlignmentsTy Alignments; AlignmentsTy::const_iterator @@ -136,7 +143,7 @@ private: /// \brief The string representation used to create this DataLayout std::string StringRepresentation; - typedef SmallVector PointersTy; + using PointersTy = SmallVector; 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 namespace llvm { -class Module; + class DbgDeclareInst; class DbgValueInst; -template -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::const_iterator - compile_unit_iterator; - typedef SmallVectorImpl::const_iterator subprogram_iterator; - typedef SmallVectorImpl::const_iterator - global_variable_expression_iterator; - typedef SmallVectorImpl::const_iterator type_iterator; - typedef SmallVectorImpl::const_iterator scope_iterator; + using compile_unit_iterator = + SmallVectorImpl::const_iterator; + using subprogram_iterator = SmallVectorImpl::const_iterator; + using global_variable_expression_iterator = + SmallVectorImpl::const_iterator; + using type_iterator = SmallVectorImpl::const_iterator; + using scope_iterator = SmallVectorImpl::const_iterator; iterator_range 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>( DominatorTreeBaseByGraphTraits>> &DT, Function &F); -typedef DomTreeNodeBase DomTreeNode; +using DomTreeNode = DomTreeNodeBase; class BasicBlockEdge { const BasicBlock *Start; @@ -70,7 +70,7 @@ public: }; template <> struct DenseMapInfo { - typedef DenseMapInfo BBInfo; + using BBInfo = DenseMapInfo; static unsigned getHashValue(const BasicBlockEdge *V); @@ -113,7 +113,7 @@ template <> struct DenseMapInfo { /// preceding statements; this is stated only to assist human understanding. class DominatorTree : public DominatorTreeBase { public: - typedef DominatorTreeBase Base; + using Base = DominatorTreeBase; DominatorTree() : DominatorTreeBase(false) {} explicit DominatorTree(Function &F) : DominatorTreeBase(false) { @@ -168,9 +168,9 @@ public: // iterable by generic graph iterators. template struct DomTreeGraphTraitsBase { - typedef Node *NodeRef; - typedef ChildIterator ChildIteratorType; - typedef df_iterator> nodes_iterator; + using NodeRef = Node *; + using ChildIteratorType = ChildIterator; + using nodes_iterator = df_iterator>; static NodeRef getEntryNode(NodeRef N) { return N; } static ChildIteratorType child_begin(NodeRef N) { return N->begin(); } @@ -212,7 +212,7 @@ class DominatorTreeAnalysis : public AnalysisInfoMixin { 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 ConstraintCodeVector; + using ConstraintCodeVector = std::vector; 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 SubConstraintInfoVector; + using SubConstraintInfoVector = std::vector; struct ConstraintInfo; - typedef std::vector ConstraintInfoVector; + using ConstraintInfoVector = std::vector; 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 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, Function::iterator, - BasicBlock::iterator, Instruction> inst_iterator; -typedef InstIterator, - Function::const_iterator, BasicBlock::const_iterator, - const Instruction> const_inst_iterator; -typedef iterator_range inst_range; -typedef iterator_range const_inst_range; +using inst_iterator = + InstIterator, Function::iterator, + BasicBlock::iterator, Instruction>; +using const_inst_iterator = + InstIterator, + Function::const_iterator, BasicBlock::const_iterator, + const Instruction>; +using inst_range = iterator_range; +using const_inst_range = iterator_range; 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 @@ -114,17 +116,17 @@ public: template // Successor Iterator class SuccIterator : public std::iterator { - typedef std::iterator - super; + using super = + std::iterator; 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 Self; + using Self = SuccIterator; inline bool index_is_valid(unsigned idx) { return idx < TermInst->getNumSuccessors(); @@ -260,11 +262,11 @@ public: } }; - typedef SuccIterator succ_iterator; - typedef SuccIterator - succ_const_iterator; - typedef iterator_range succ_range; - typedef iterator_range succ_const_range; + using succ_iterator = SuccIterator; + using succ_const_iterator = + SuccIterator; + using succ_range = iterator_range; + using succ_const_range = iterator_range; 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 Args, const Twine &NameStr); - FuncletPadInst(const FuncletPadInst &CPI); explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad, @@ -1136,11 +1138,14 @@ private: ArrayRef Args, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd); + void init(Value *ParentPad, ArrayRef 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 inputs() const { return Inputs; } - typedef typename std::vector::const_iterator input_iterator; + using input_iterator = typename std::vector::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 OperandBundleDef; -typedef OperandBundleDefT ConstOperandBundleDef; +using OperandBundleDef = OperandBundleDefT; +using ConstOperandBundleDef = OperandBundleDefT; /// \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> 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 { - 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 + 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> 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 { + 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 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> 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 - 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; + 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 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 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(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 &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 { for (auto &FSum : FSums) { GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false, false); - Elem.push_back(llvm::make_unique( + Elem.SummaryList.push_back(llvm::make_unique( GVFlags, 0, ArrayRef{}, ArrayRef{}, std::move(FSum.TypeTests), std::move(FSum.TypeTestAssumeVCalls), @@ -213,7 +213,7 @@ template <> struct CustomMappingTraits { static void output(IO &io, GlobalValueSummaryMapTy &V) { for (auto &P : V) { std::vector FSums; - for (auto &Sum : P.second) { + for (auto &Sum : P.second.SummaryList) { if (auto *FSum = dyn_cast(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; 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(31) & NameOffset; + } + } Identifier; + union { + support::ulittle32_t DataEntryOffset; + support::ulittle32_t SubdirOffset; + + bool isSubDir() const { return SubdirOffset >> 31; } + uint32_t value() const { + return maskTrailingOnes(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> getEntryNameString(const coff_resource_dir_entry &Entry); + ErrorOr + getEntrySubDir(const coff_resource_dir_entry &Entry); + ErrorOr getBaseTable(); + +private: + BinaryByteStream BBS; + + ErrorOr getTableAtOffset(uint32_t Offset); + ErrorOr> 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 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 { static void mapping(IO &IO, WasmYAML::Relocation &Relocation); }; +template <> struct MappingTraits { + static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry); +}; + template <> struct MappingTraits { 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 class FixedStreamArrayIterator : public iterator_facade_base, - std::random_access_iterator_tag, T> { + std::random_access_iterator_tag, const T> { public: FixedStreamArrayIterator(const FixedStreamArray &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 &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 T maskLeadingOnes(unsigned N) { return ~maskTrailingOnes(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 T maskTrailingZeros(unsigned N) { + return maskLeadingOnes(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 T maskLeadingZeros(unsigned N) { + return maskTrailingOnes(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 { SDNode Node = node; } -def : GINodeEquiv; +// These are defined in the same order as the G_* instructions. +def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +// 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; def : GINodeEquiv; def : GINodeEquiv; - +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; -def : GINodeEquiv; - def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; - -def : GINodeEquiv; -def : GINodeEquiv; -def : GINodeEquiv; -def : GINodeEquiv; - +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; +def : GINodeEquiv; def : GINodeEquiv; // 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 &Roots); - ConstantRange seen(Instruction *I, ConstantRange R); + void seen(Instruction *I, ConstantRange R); ConstantRange badRange(); ConstantRange unknownRange(); ConstantRange validateRange(ConstantRange R); -- cgit v1.3