diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-02 18:30:13 +0000 |
commit | a303c417bbdb53703c2c17398b08486bde78f1f6 (patch) | |
tree | 98366d6b93d863cefdc53f16c66c0c5ae7fb2261 /include | |
parent | 12f3ca4cdb95b193af905a00e722a4dcb40b3de3 (diff) | |
download | src-test2-a303c417bbdb53703c2c17398b08486bde78f1f6.tar.gz src-test2-a303c417bbdb53703c2c17398b08486bde78f1f6.zip |
Notes
Diffstat (limited to 'include')
114 files changed, 1889 insertions, 1318 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index d0104c3f0fa9..6d74f344aad5 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -366,7 +366,7 @@ public: /// that 0 is not a positive value. /// /// \returns true if this APInt is positive. - bool isStrictlyPositive() const { return isNonNegative() && !!*this; } + bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); } /// \brief Determine if all bits are set /// @@ -377,6 +377,12 @@ public: return countPopulationSlowCase() == BitWidth; } + /// \brief Determine if all bits are clear + /// + /// This checks to see if the value has all bits of the APInt are clear or + /// not. + bool isNullValue() const { return !*this; } + /// \brief Determine if this is the largest unsigned value. /// /// This checks to see if the value of this APInt is the maximum unsigned @@ -395,7 +401,7 @@ public: /// /// This checks to see if the value of this APInt is the minimum unsigned /// value for the APInt's bit width. - bool isMinValue() const { return !*this; } + bool isMinValue() const { return isNullValue(); } /// \brief Determine if this is the smallest signed value. /// @@ -611,15 +617,7 @@ public: } /// \brief Return a value containing V broadcasted over NewLen bits. - static APInt getSplat(unsigned NewLen, const APInt &V) { - assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!"); - - APInt Val = V.zextOrSelf(NewLen); - for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1) - Val |= Val << I; - - return Val; - } + static APInt getSplat(unsigned NewLen, const APInt &V); /// \brief Determine if two APInts have the same value, after zero-extending /// one of them (if needed!) to ensure that the bit-widths match. @@ -687,7 +685,9 @@ public: /// /// \returns true if *this is zero, false otherwise. bool operator!() const { - return *this == 0; + if (isSingleWord()) + return VAL == 0; + return countLeadingZerosSlowCase() == BitWidth; } /// @} @@ -874,6 +874,13 @@ public: return *this; } + /// \brief Left-shift assignment function. + /// + /// Shifts *this left by shiftAmt and assigns the result to *this. + /// + /// \returns *this after shifting left by ShiftAmt + APInt &operator<<=(const APInt &ShiftAmt); + /// @} /// \name Binary Operators /// @{ @@ -981,7 +988,11 @@ public: /// \brief Left-shift function. /// /// Left-shift this APInt by shiftAmt. - APInt shl(const APInt &shiftAmt) const; + APInt shl(const APInt &ShiftAmt) const { + APInt R(*this); + R <<= ShiftAmt; + return R; + } /// \brief Rotate left by rotateAmt. APInt rotl(const APInt &rotateAmt) const; @@ -1333,7 +1344,14 @@ public: /// \brief Set a given bit to 1. /// /// Set the given bit to 1 whose position is given as "bitPosition". - void setBit(unsigned bitPosition); + void setBit(unsigned BitPosition) { + assert(BitPosition <= BitWidth && "BitPosition out of range"); + WordType Mask = maskBit(BitPosition); + if (isSingleWord()) + VAL |= Mask; + else + pVal[whichWord(BitPosition)] |= Mask; + } /// Set the sign bit to 1. void setSignBit() { @@ -1344,13 +1362,9 @@ public: void setBits(unsigned loBit, unsigned hiBit) { assert(hiBit <= BitWidth && "hiBit out of range"); assert(loBit <= BitWidth && "loBit out of range"); + assert(loBit <= hiBit && "loBit greater than hiBit"); if (loBit == hiBit) return; - if (loBit > hiBit) { - setLowBits(hiBit); - setHighBits(BitWidth - loBit); - return; - } if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) { uint64_t mask = WORD_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit)); mask <<= loBit; @@ -1389,7 +1403,19 @@ public: /// \brief Set a given bit to 0. /// /// Set the given bit to 0 whose position is given as "bitPosition". - void clearBit(unsigned bitPosition); + void clearBit(unsigned BitPosition) { + assert(BitPosition <= BitWidth && "BitPosition out of range"); + WordType Mask = ~maskBit(BitPosition); + if (isSingleWord()) + VAL &= Mask; + else + pVal[whichWord(BitPosition)] &= Mask; + } + + /// Set the sign bit to 0. + void clearSignBit() { + clearBit(BitWidth - 1); + } /// \brief Toggle every bit to its opposite value. void flipAllBits() { @@ -1695,7 +1721,7 @@ public: return VAL - 1; // Handle the zero case. - if (!getBoolValue()) + if (isNullValue()) return UINT32_MAX; // The non-zero case is handled by computing: diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h index f833f417c7dd..04c6fd70e07f 100644 --- a/include/llvm/Analysis/AssumptionCache.h +++ b/include/llvm/Analysis/AssumptionCache.h @@ -43,7 +43,7 @@ class AssumptionCache { /// \brief Vector of weak value handles to calls of the @llvm.assume /// intrinsic. - SmallVector<WeakVH, 4> AssumeHandles; + SmallVector<WeakTrackingVH, 4> AssumeHandles; class AffectedValueCallbackVH final : public CallbackVH { AssumptionCache *AC; @@ -62,12 +62,12 @@ class AssumptionCache { /// \brief A map of values about which an assumption might be providing /// information to the relevant set of assumptions. using AffectedValuesMap = - DenseMap<AffectedValueCallbackVH, SmallVector<WeakVH, 1>, - AffectedValueCallbackVH::DMI>; + DenseMap<AffectedValueCallbackVH, SmallVector<WeakTrackingVH, 1>, + AffectedValueCallbackVH::DMI>; AffectedValuesMap AffectedValues; /// Get the vector of assumptions which affect a value from the cache. - SmallVector<WeakVH, 1> &getOrInsertAffectedValues(Value *V); + SmallVector<WeakTrackingVH, 1> &getOrInsertAffectedValues(Value *V); /// Copy affected values in the cache for OV to be affected values for NV. void copyAffectedValuesInCache(Value *OV, Value *NV); @@ -120,20 +120,20 @@ public: /// FIXME: We should replace this with pointee_iterator<filter_iterator<...>> /// when we can write that to filter out the null values. Then caller code /// will become simpler. - MutableArrayRef<WeakVH> assumptions() { + MutableArrayRef<WeakTrackingVH> assumptions() { if (!Scanned) scanFunction(); return AssumeHandles; } /// \brief Access the list of assumptions which affect this value. - MutableArrayRef<WeakVH> assumptionsFor(const Value *V) { + MutableArrayRef<WeakTrackingVH> assumptionsFor(const Value *V) { if (!Scanned) scanFunction(); auto AVI = AffectedValues.find_as(const_cast<Value *>(V)); if (AVI == AffectedValues.end()) - return MutableArrayRef<WeakVH>(); + return MutableArrayRef<WeakTrackingVH>(); return AVI->second; } diff --git a/include/llvm/Analysis/CGSCCPassManager.h b/include/llvm/Analysis/CGSCCPassManager.h index 398bbfb0c413..a15a9e18c815 100644 --- a/include/llvm/Analysis/CGSCCPassManager.h +++ b/include/llvm/Analysis/CGSCCPassManager.h @@ -646,7 +646,7 @@ public: LazyCallGraph::SCC *C = &InitialC; // Collect value handles for all of the indirect call sites. - SmallVector<WeakVH, 8> CallHandles; + SmallVector<WeakTrackingVH, 8> CallHandles; // Struct to track the counts of direct and indirect calls in each function // of the SCC. @@ -658,7 +658,7 @@ public: // Put value handles on all of the indirect calls and return the number of // direct calls for each function in the SCC. auto ScanSCC = [](LazyCallGraph::SCC &C, - SmallVectorImpl<WeakVH> &CallHandles) { + SmallVectorImpl<WeakTrackingVH> &CallHandles) { assert(CallHandles.empty() && "Must start with a clear set of handles."); SmallVector<CallCount, 4> CallCounts; @@ -671,7 +671,7 @@ public: ++Count.Direct; } else { ++Count.Indirect; - CallHandles.push_back(WeakVH(&I)); + CallHandles.push_back(WeakTrackingVH(&I)); } } } @@ -699,7 +699,7 @@ public: "Cannot have changed the size of the SCC!"); // Check whether any of the handles were devirtualized. - auto IsDevirtualizedHandle = [&](WeakVH &CallH) { + auto IsDevirtualizedHandle = [&](WeakTrackingVH &CallH) { if (!CallH) return false; auto CS = CallSite(CallH); diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index ea85436ee580..cc4788d3edae 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -172,7 +172,7 @@ class CallGraphNode { public: /// \brief A pair of the calling instruction (a call or invoke) /// and the call graph node being called. - typedef std::pair<WeakVH, CallGraphNode *> CallRecord; + typedef std::pair<WeakTrackingVH, CallGraphNode *> CallRecord; public: typedef std::vector<CallRecord> CalledFunctionsVector; diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index bb572dd5603b..035b974c5c1d 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -80,7 +80,7 @@ private: /// OperandValToReplace - The Value of the operand in the user instruction /// that this IVStrideUse is representing. - WeakVH OperandValToReplace; + WeakTrackingVH OperandValToReplace; /// PostIncLoops - The set of loops for which Expr has been adjusted to /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index 17e5cb6db02d..d91d08a524dc 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -160,6 +160,10 @@ InlineParams getInlineParams(int Threshold); /// the -Oz flag. InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel); +/// Return the cost associated with a callsite, including paramater passing +/// and the call/return instruction. +int getCallsiteCost(CallSite CS, const DataLayout &DL); + /// \brief Get an InlineCost object representing the cost of inlining this /// callsite. /// diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index 25240dae75e7..bf73e099a2bf 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -35,35 +35,41 @@ #include "llvm/IR/User.h" namespace llvm { - template<typename T> - class ArrayRef; - class AssumptionCache; - class DominatorTree; - class Instruction; - class DataLayout; - class FastMathFlags; - class OptimizationRemarkEmitter; - class TargetLibraryInfo; - class Type; - class Value; - - struct SimplifyQuery { - const DataLayout &DL; - const TargetLibraryInfo *TLI = nullptr; - const DominatorTree *DT = nullptr; - AssumptionCache *AC = nullptr; - const Instruction *CxtI = nullptr; - SimplifyQuery(const DataLayout &DL) : DL(DL) {} - - SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI, - const DominatorTree *DT, AssumptionCache *AC = nullptr, - const Instruction *CXTI = nullptr) - : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {} - SimplifyQuery getWithInstruction(Instruction *I) const { - SimplifyQuery Copy(*this); - Copy.CxtI = I; - return Copy; - } +class Function; +template <typename T, typename... TArgs> class AnalysisManager; +template <class T> class ArrayRef; +class AssumptionCache; +class DominatorTree; +class Instruction; +class DataLayout; +class FastMathFlags; +struct LoopStandardAnalysisResults; +class OptimizationRemarkEmitter; +class Pass; +class TargetLibraryInfo; +class Type; +class Value; + +struct SimplifyQuery { + const DataLayout &DL; + const TargetLibraryInfo *TLI = nullptr; + const DominatorTree *DT = nullptr; + AssumptionCache *AC = nullptr; + const Instruction *CxtI = nullptr; + + SimplifyQuery(const DataLayout &DL, const Instruction *CXTI = nullptr) + : DL(DL), CxtI(CXTI) {} + + SimplifyQuery(const DataLayout &DL, const TargetLibraryInfo *TLI, + const DominatorTree *DT = nullptr, + AssumptionCache *AC = nullptr, + const Instruction *CXTI = nullptr) + : DL(DL), TLI(TLI), DT(DT), AC(AC), CxtI(CXTI) {} + SimplifyQuery getWithInstruction(Instruction *I) const { + SimplifyQuery Copy(*this); + Copy.CxtI = I; + return Copy; + } }; // NOTE: the explicit multiple argument versions of these functions are @@ -73,257 +79,103 @@ namespace llvm { /// Given operands for an Add, fold the result or return null. Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q); - Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a Sub, fold the result or return null. Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, const SimplifyQuery &Q); - Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FAdd, fold the result or return null. Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FSub, fold the result or return null. Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FMul, fold the result or return null. Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a Mul, fold the result or return null. Value *SimplifyMulInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an SDiv, fold the result or return null. Value *SimplifySDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a UDiv, fold the result or return null. Value *SimplifyUDivInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FDiv, fold the result or return null. Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an SRem, fold the result or return null. Value *SimplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a URem, fold the result or return null. Value *SimplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FRem, fold the result or return null. Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a Shl, fold the result or return null. Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, const SimplifyQuery &Q); - Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a LShr, fold the result or return null. Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, const SimplifyQuery &Q); - Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a AShr, fold the result or return nulll. Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, const SimplifyQuery &Q); - Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an And, fold the result or return null. Value *SimplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an Or, fold the result or return null. Value *SimplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an Xor, fold the result or return null. Value *SimplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an ICmpInst, fold the result or return null. Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FCmpInst, fold the result or return null. Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - FastMathFlags FMF, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a SelectInst, fold the result or return null. Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q); - Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a GetElementPtrInst, fold the result or return null. Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops, const SimplifyQuery &Q); - Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an InsertValueInst, fold the result or return null. Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, const SimplifyQuery &Q); - Value *SimplifyInsertValueInst(Value *Agg, Value *Val, - ArrayRef<unsigned> Idxs, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an ExtractValueInst, fold the result or return null. Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs, const SimplifyQuery &Q); - Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an ExtractElementInst, fold the result or return null. Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, const SimplifyQuery &Q); - Value *SimplifyExtractElementInst(Value *Vec, Value *Idx, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a CastInst, fold the result or return null. Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q); - Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a ShuffleVectorInst, fold the result or return null. Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, Type *RetTy, const SimplifyQuery &Q); - Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, - Type *RetTy, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); //=== Helper functions for higher up the class hierarchy. @@ -331,63 +183,29 @@ namespace llvm { /// Given operands for a CmpInst, fold the result or return null. Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for a BinaryOperator, fold the result or return null. Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q); - Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, - const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given operands for an FP BinaryOperator, fold the result or return null. /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the /// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp. Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, FastMathFlags FMF, const SimplifyQuery &Q); - Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS, - FastMathFlags FMF, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given a function and iterators over arguments, fold the result or return /// null. Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, User::op_iterator ArgEnd, const SimplifyQuery &Q); - Value *SimplifyCall(Value *V, User::op_iterator ArgBegin, - User::op_iterator ArgEnd, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// Given a function and set of arguments, fold the result or return null. Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const SimplifyQuery &Q); - Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - const Instruction *CxtI = nullptr); /// See if we can compute a simplified version of this instruction. If not, /// return null. Value *SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE = nullptr); - Value *SimplifyInstruction(Instruction *I, const DataLayout &DL, - const TargetLibraryInfo *TLI = nullptr, - const DominatorTree *DT = nullptr, - AssumptionCache *AC = nullptr, - OptimizationRemarkEmitter *ORE = nullptr); /// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively. /// @@ -411,6 +229,15 @@ namespace llvm { const TargetLibraryInfo *TLI = nullptr, const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr); + // These helper functions return a SimplifyQuery structure that contains as + // many of the optional analysis we use as are currently valid. This is the + // strongly preferred way of constructing SimplifyQuery in passes. + const SimplifyQuery getBestSimplifyQuery(Pass &, Function &); + template <class T, class... TArgs> + const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &, + Function &); + const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &, + const DataLayout &); } // end namespace llvm #endif diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 743faf2b67db..60dafccd84bd 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -235,7 +235,7 @@ class ObjectSizeOffsetEvaluator : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> { typedef IRBuilder<TargetFolder> BuilderTy; - typedef std::pair<WeakVH, WeakVH> WeakEvalType; + typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType; typedef DenseMap<const Value*, WeakEvalType> CacheMapTy; typedef SmallPtrSet<const Value*, 8> PtrSetTy; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 517592a3d049..7d16f34e54cb 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -189,7 +189,7 @@ namespace llvm { /// replace congruent phis with their most canonical representative. Return /// the number of phis eliminated. unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, - SmallVectorImpl<WeakVH> &DeadInsts, + SmallVectorImpl<WeakTrackingVH> &DeadInsts, const TargetTransformInfo *TTI = nullptr); /// Insert code to directly compute the specified SCEV expression into the diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index 67196687d556..b9639dba1881 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -197,6 +197,12 @@ public: int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) const; + /// \return The estimated number of case clusters when lowering \p 'SI'. + /// \p JTSize Set a jump table size only when \p SI is suitable for a jump + /// table. + unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, + unsigned &JTSize) const; + /// \brief Estimate the cost of a given IR user when lowered. /// /// This can estimate the cost of either a ConstantExpr or Instruction when @@ -764,6 +770,8 @@ public: ArrayRef<Type *> ParamTys) = 0; virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, ArrayRef<const Value *> Arguments) = 0; + virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, + unsigned &JTSize) = 0; virtual int getUserCost(const User *U) = 0; virtual bool hasBranchDivergence() = 0; virtual bool isSourceOfDivergence(const Value *V) = 0; @@ -1067,6 +1075,10 @@ public: unsigned getMaxInterleaveFactor(unsigned VF) override { return Impl.getMaxInterleaveFactor(VF); } + unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, + unsigned &JTSize) override { + return Impl.getEstimatedNumberOfCaseClusters(SI, JTSize); + } unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind Opd1Info, OperandValueKind Opd2Info, diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 9ab6b7445ab8..d7fda9e14b05 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -114,6 +114,12 @@ public: return TTI::TCC_Free; } + unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, + unsigned &JTSize) { + JTSize = 0; + return SI.getNumCases(); + } + unsigned getCallCost(FunctionType *FTy, int NumArgs) { assert(FTy && "FunctionType must be provided to this routine."); diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h index 764308dceed9..a54c39e3ea3a 100644 --- a/include/llvm/Analysis/ValueTracking.h +++ b/include/llvm/Analysis/ValueTracking.h @@ -60,7 +60,7 @@ template <typename T> class ArrayRef; /// \p KnownZero the set of bits that are known to be zero /// \p KnownOne the set of bits that are known to be one void computeKnownBitsFromRangeMetadata(const MDNode &Ranges, - APInt &KnownZero, APInt &KnownOne); + KnownBits &Known); /// Return true if LHS and RHS have no common bits set. bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS, const DataLayout &DL, @@ -417,7 +417,7 @@ template <typename T> class ArrayRef; /// /// Note that this currently only considers the basic block that is /// the parent of I. - bool isKnownNotFullPoison(const Instruction *PoisonI); + bool programUndefinedIfFullPoison(const Instruction *PoisonI); /// \brief Specific patterns of select instructions we can match. enum SelectPatternFlavor { diff --git a/include/llvm/Bitcode/BitcodeReader.h b/include/llvm/Bitcode/BitcodeReader.h index 0701ddbb7f1c..54f990d00233 100644 --- a/include/llvm/Bitcode/BitcodeReader.h +++ b/include/llvm/Bitcode/BitcodeReader.h @@ -93,6 +93,10 @@ namespace llvm { /// Parse the specified bitcode buffer, returning the module summary index. Expected<std::unique_ptr<ModuleSummaryIndex>> getSummary(); + + /// Parse the specified bitcode buffer and merge its module summary index + /// into CombinedIndex. + Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId); }; /// Returns a list of modules in the specified bitcode buffer. @@ -141,6 +145,18 @@ namespace llvm { Expected<std::unique_ptr<ModuleSummaryIndex>> getModuleSummaryIndex(MemoryBufferRef Buffer); + /// Parse the specified bitcode buffer and merge the index into CombinedIndex. + Error readModuleSummaryIndex(MemoryBufferRef Buffer, + ModuleSummaryIndex &CombinedIndex, + unsigned ModuleId); + + /// Parse the module summary index out of an IR file and return the module + /// summary index object if found, or an empty summary if not. If Path refers + /// to an empty file and the -ignore-empty-index-file cl::opt flag is passed + /// this function will return nullptr. + Expected<std::unique_ptr<ModuleSummaryIndex>> + getModuleSummaryIndexForFile(StringRef Path); + /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. /// diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 03eac80bc1e8..8ee1e4b583b6 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -545,7 +545,8 @@ enum AttributeKindCodes { ATTR_KIND_INACCESSIBLEMEM_ONLY = 49, ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50, ATTR_KIND_ALLOC_SIZE = 51, - ATTR_KIND_WRITEONLY = 52 + ATTR_KIND_WRITEONLY = 52, + ATTR_KIND_SPECULATABLE = 53 }; enum ComdatSelectionKindCodes { diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index e30e947f787f..32542fa87463 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -171,6 +171,62 @@ public: return BaseT::getIntrinsicCost(IID, RetTy, ParamTys); } + unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI, + unsigned &JumpTableSize) { + /// Try to find the estimated number of clusters. Note that the number of + /// clusters identified in this function could be different from the actural + /// numbers found in lowering. This function ignore switches that are + /// lowered with a mix of jump table / bit test / BTree. This function was + /// initially intended to be used when estimating the cost of switch in + /// inline cost heuristic, but it's a generic cost model to be used in other + /// places (e.g., in loop unrolling). + unsigned N = SI.getNumCases(); + const TargetLoweringBase *TLI = getTLI(); + const DataLayout &DL = this->getDataLayout(); + + JumpTableSize = 0; + bool IsJTAllowed = TLI->areJTsAllowed(SI.getParent()->getParent()); + + // Early exit if both a jump table and bit test are not allowed. + if (N < 1 || (!IsJTAllowed && DL.getPointerSizeInBits() < N)) + return N; + + APInt MaxCaseVal = SI.case_begin()->getCaseValue()->getValue(); + APInt MinCaseVal = MaxCaseVal; + for (auto CI : SI.cases()) { + const APInt &CaseVal = CI.getCaseValue()->getValue(); + if (CaseVal.sgt(MaxCaseVal)) + MaxCaseVal = CaseVal; + if (CaseVal.slt(MinCaseVal)) + MinCaseVal = CaseVal; + } + + // Check if suitable for a bit test + if (N <= DL.getPointerSizeInBits()) { + SmallPtrSet<const BasicBlock *, 4> Dests; + for (auto I : SI.cases()) + Dests.insert(I.getCaseSuccessor()); + + if (TLI->isSuitableForBitTests(Dests.size(), N, MinCaseVal, MaxCaseVal, + DL)) + return 1; + } + + // Check if suitable for a jump table. + if (IsJTAllowed) { + if (N < 2 || N < TLI->getMinimumJumpTableEntries()) + return N; + uint64_t Range = + (MaxCaseVal - MinCaseVal).getLimitedValue(UINT64_MAX - 1) + 1; + // Check whether a range of clusters is dense enough for a jump table + if (TLI->isSuitableForJumpTable(&SI, N, Range)) { + JumpTableSize = Range; + return 1; + } + } + return N; + } + unsigned getJumpBufAlignment() { return getTLI()->getJumpBufAlignment(); } unsigned getJumpBufSize() { return getTLI()->getJumpBufSize(); } diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 75cd7da9d6b9..14ee5019ef2f 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/Support/KnownBits.h" #include "llvm/Target/TargetRegisterInfo.h" #include <vector> @@ -171,9 +172,8 @@ public: struct LiveOutInfo { unsigned NumSignBits : 31; unsigned IsValid : 1; - APInt KnownOne, KnownZero; - LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0), - KnownZero(1, 0) {} + KnownBits Known; + LiveOutInfo() : NumSignBits(0), IsValid(true), Known(1) {} }; /// Record the preferred extend type (ISD::SIGN_EXTEND or ISD::ZERO_EXTEND) @@ -247,16 +247,16 @@ public: /// AddLiveOutRegInfo - Adds LiveOutInfo for a register. void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits, - const APInt &KnownZero, const APInt &KnownOne) { + const KnownBits &Known) { // Only install this information if it tells us something. - if (NumSignBits == 1 && KnownZero == 0 && KnownOne == 0) + if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0) return; LiveOutRegInfo.grow(Reg); LiveOutInfo &LOI = LiveOutRegInfo[Reg]; LOI.NumSignBits = NumSignBits; - LOI.KnownOne = KnownOne; - LOI.KnownZero = KnownZero; + LOI.Known.One = Known.One; + LOI.Known.Zero = Known.Zero; } /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index 899563acc330..45f25f96ec1f 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -61,9 +61,6 @@ class InstructionSelector { public: virtual ~InstructionSelector() {} - /// This is executed before selecting a function. - virtual void beginFunction(const MachineFunction &MF) {} - /// Select the (possibly generic) instruction \p I to only use target-specific /// opcodes. It is OK to insert multiple instructions, but they cannot be /// generic pre-isel instructions. diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index ee3fd0bdda2a..ca0f3fbad892 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -216,6 +216,9 @@ namespace ISD { /// These nodes take two operands of the same value type, and produce two /// results. The first result is the normal add or sub result, the second /// result is the carry flag result. + /// FIXME: These nodes are deprecated in favor of ADDCARRY and SUBCARRY. + /// They are kept around for now to provide a smooth transition path + /// toward the use of ADDCARRY/SUBCARRY and will eventually be removed. ADDC, SUBC, /// Carry-using nodes for multiple precision addition and subtraction. These @@ -227,6 +230,16 @@ namespace ISD { /// values. ADDE, SUBE, + /// Carry-using nodes for multiple precision addition and subtraction. + /// These nodes take three operands: The first two are the normal lhs and + /// rhs to the add or sub, and the third is a boolean indicating if there + /// is an incoming carry. These nodes produce two results: the normal + /// result of the add or sub, and the output carry so they can be chained + /// together. The use of this opcode is preferable to adde/sube if the + /// target supports it, as the carry is a regular value rather than a + /// glue, which allows further optimisation. + ADDCARRY, SUBCARRY, + /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. /// These nodes take two operands: the normal LHS and RHS to the add. They /// produce two results: the normal result of the add, and a boolean that diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index 38cf8aa165a4..47b40de6fe1f 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -345,7 +345,7 @@ struct MachineFrameInfo { bool HasCalls = false; StringValue StackProtector; // TODO: Serialize FunctionContextIdx - unsigned MaxCallFrameSize = 0; + unsigned MaxCallFrameSize = ~0u; ///< ~0u means: not computed yet. bool HasOpaqueSPAdjustment = false; bool HasVAStart = false; bool HasMustTailInVarArgFunc = false; @@ -366,7 +366,7 @@ template <> struct MappingTraits<MachineFrameInfo> { YamlIO.mapOptional("hasCalls", MFI.HasCalls); YamlIO.mapOptional("stackProtector", MFI.StackProtector, StringValue()); // Don't print it out when it's empty. - YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize); + YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize, ~0u); YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment); YamlIO.mapOptional("hasVAStart", MFI.HasVAStart); YamlIO.mapOptional("hasMustTailInVarArgFunc", MFI.HasMustTailInVarArgFunc); diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 5c9728b0a51e..61be9f775c97 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -21,15 +21,9 @@ namespace llvm { class raw_ostream; -class DataLayout; -class TargetRegisterClass; -class Type; class MachineFunction; class MachineBasicBlock; -class TargetFrameLowering; -class TargetMachine; class BitVector; -class Value; class AllocaInst; /// The CalleeSavedInfo class tracks the information need to locate where a @@ -226,7 +220,7 @@ class MachineFrameInfo { /// setup/destroy pseudo instructions (as defined in the TargetFrameInfo /// class). This information is important for frame pointer elimination. /// It is only valid during and after prolog/epilog code insertion. - unsigned MaxCallFrameSize = 0; + unsigned MaxCallFrameSize = ~0u; /// The prolog/epilog code inserter fills in this vector with each /// callee saved register saved in the frame. Beyond its use by the prolog/ @@ -531,7 +525,16 @@ public: /// CallFrameSetup/Destroy pseudo instructions are used by the target, and /// then only during or after prolog/epilog code insertion. /// - unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; } + unsigned getMaxCallFrameSize() const { + // TODO: Enable this assert when targets are fixed. + //assert(isMaxCallFrameSizeComputed() && "MaxCallFrameSize not computed yet"); + if (!isMaxCallFrameSizeComputed()) + return 0; + return MaxCallFrameSize; + } + bool isMaxCallFrameSizeComputed() const { + return MaxCallFrameSize != ~0u; + } void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; } /// Create a new object at a fixed location on the stack. diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 4bb658898fb5..9e1d148c7ce5 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -33,6 +33,7 @@ namespace llvm { +struct KnownBits; class MachineConstantPoolValue; class MachineFunction; class MDNode; @@ -687,6 +688,10 @@ public: /// Example: shuffle A, B, <0,5,2,7> -> shuffle B, A, <4,1,6,3> SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV); + /// Convert Op, which must be of float type, to the + /// float type VT, by either extending or rounding (by truncation). + SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT); + /// Convert Op, which must be of integer type, to the /// integer type VT, by either any-extending or truncating it. SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT); @@ -773,7 +778,7 @@ public: SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef<SDUse> Ops); SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, - ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr); + ArrayRef<SDValue> Ops, const SDNodeFlags Flags = SDNodeFlags()); SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops); SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, @@ -781,9 +786,10 @@ public: // Specialize based on number of operands. SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT); - SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N, + const SDNodeFlags Flags = SDNodeFlags()); SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, - SDValue N2, const SDNodeFlags *Flags = nullptr); + SDValue N2, const SDNodeFlags Flags = SDNodeFlags()); SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, SDValue N2, SDValue N3); SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, @@ -1103,7 +1109,7 @@ public: /// Get the specified node if it's already available, or else return NULL. SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, ArrayRef<SDValue> Ops, - const SDNodeFlags *Flags = nullptr); + const SDNodeFlags Flags = SDNodeFlags()); /// Creates a SDDbgValue node. SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R, @@ -1266,7 +1272,7 @@ public: SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef<SDValue> Ops, - const SDNodeFlags *Flags = nullptr); + const SDNodeFlags Flags = SDNodeFlags()); /// Constant fold a setcc to true or false. SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond, @@ -1283,21 +1289,19 @@ public: const; /// Determine which bits of Op are known to be either zero or one and return - /// them in the KnownZero/KnownOne bitsets. For vectors, the known bits are - /// those that are shared by every vector element. + /// them in Known. For vectors, the known bits are those that are shared by + /// every vector element. /// Targets can implement the computeKnownBitsForTargetNode method in the /// TargetLowering class to allow target nodes to be understood. - void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, - unsigned Depth = 0) const; + void computeKnownBits(SDValue Op, KnownBits &Known, unsigned Depth = 0) const; /// Determine which bits of Op are known to be either zero or one and return - /// them in the KnownZero/KnownOne bitsets. The DemandedElts argument allows - /// us to only collect the known bits that are shared by the requested vector - /// elements. + /// them in Known. The DemandedElts argument allows us to only collect the + /// known bits that are shared by the requested vector elements. /// Targets can implement the computeKnownBitsForTargetNode method in the /// TargetLowering class to allow target nodes to be understood. - void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, - const APInt &DemandedElts, unsigned Depth = 0) const; + void computeKnownBits(SDValue Op, KnownBits &Known, const APInt &DemandedElts, + unsigned Depth = 0) const; /// Used to represent the possible overflow behavior of an operation. /// Never: the operation cannot overflow. @@ -1439,10 +1443,6 @@ private: void allnodes_clear(); - SDNode *GetBinarySDNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, - SDValue N1, SDValue N2, - const SDNodeFlags *Flags = nullptr); - /// Look up the node specified by ID in CSEMap. If it exists, return it. If /// not, return the insertion token that will make insertion faster. This /// overload is for nodes other than Constant or ConstantFP, use the other one diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 81cc0b39cf87..35ddcf80c91f 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -341,6 +341,11 @@ template<> struct simplify_type<SDUse> { /// the backend. struct SDNodeFlags { private: + // This bit is used to determine if the flags are in a defined state. + // Flag bits can only be masked out during intersection if the masking flags + // are defined. + bool AnyDefined : 1; + bool NoUnsignedWrap : 1; bool NoSignedWrap : 1; bool Exact : 1; @@ -355,22 +360,57 @@ private: public: /// Default constructor turns off all optimization flags. SDNodeFlags() - : NoUnsignedWrap(false), NoSignedWrap(false), Exact(false), - UnsafeAlgebra(false), NoNaNs(false), NoInfs(false), + : AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false), + Exact(false), UnsafeAlgebra(false), NoNaNs(false), NoInfs(false), NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false), AllowContract(false) {} + /// Sets the state of the flags to the defined state. + void setDefined() { AnyDefined = true; } + /// Returns true if the flags are in a defined state. + bool isDefined() const { return AnyDefined; } + // These are mutators for each flag. - void setNoUnsignedWrap(bool b) { NoUnsignedWrap = b; } - void setNoSignedWrap(bool b) { NoSignedWrap = b; } - void setExact(bool b) { Exact = b; } - void setUnsafeAlgebra(bool b) { UnsafeAlgebra = b; } - void setNoNaNs(bool b) { NoNaNs = b; } - void setNoInfs(bool b) { NoInfs = b; } - void setNoSignedZeros(bool b) { NoSignedZeros = b; } - void setAllowReciprocal(bool b) { AllowReciprocal = b; } - void setVectorReduction(bool b) { VectorReduction = b; } - void setAllowContract(bool b) { AllowContract = b; } + void setNoUnsignedWrap(bool b) { + setDefined(); + NoUnsignedWrap = b; + } + void setNoSignedWrap(bool b) { + setDefined(); + NoSignedWrap = b; + } + void setExact(bool b) { + setDefined(); + Exact = b; + } + void setUnsafeAlgebra(bool b) { + setDefined(); + UnsafeAlgebra = b; + } + void setNoNaNs(bool b) { + setDefined(); + NoNaNs = b; + } + void setNoInfs(bool b) { + setDefined(); + NoInfs = b; + } + void setNoSignedZeros(bool b) { + setDefined(); + NoSignedZeros = b; + } + void setAllowReciprocal(bool b) { + setDefined(); + AllowReciprocal = b; + } + void setVectorReduction(bool b) { + setDefined(); + VectorReduction = b; + } + void setAllowContract(bool b) { + setDefined(); + AllowContract = b; + } // These are accessors for each flag. bool hasNoUnsignedWrap() const { return NoUnsignedWrap; } @@ -385,17 +425,20 @@ public: bool hasAllowContract() const { return AllowContract; } /// Clear any flags in this flag set that aren't also set in Flags. - void intersectWith(const SDNodeFlags *Flags) { - NoUnsignedWrap &= Flags->NoUnsignedWrap; - NoSignedWrap &= Flags->NoSignedWrap; - Exact &= Flags->Exact; - UnsafeAlgebra &= Flags->UnsafeAlgebra; - NoNaNs &= Flags->NoNaNs; - NoInfs &= Flags->NoInfs; - NoSignedZeros &= Flags->NoSignedZeros; - AllowReciprocal &= Flags->AllowReciprocal; - VectorReduction &= Flags->VectorReduction; - AllowContract &= Flags->AllowContract; + /// If the given Flags are undefined then don't do anything. + void intersectWith(const SDNodeFlags Flags) { + if (!Flags.isDefined()) + return; + NoUnsignedWrap &= Flags.NoUnsignedWrap; + NoSignedWrap &= Flags.NoSignedWrap; + Exact &= Flags.Exact; + UnsafeAlgebra &= Flags.UnsafeAlgebra; + NoNaNs &= Flags.NoNaNs; + NoInfs &= Flags.NoInfs; + NoSignedZeros &= Flags.NoSignedZeros; + AllowReciprocal &= Flags.AllowReciprocal; + VectorReduction &= Flags.VectorReduction; + AllowContract &= Flags.AllowContract; } }; @@ -527,6 +570,8 @@ private: /// Return a pointer to the specified value type. static const EVT *getValueTypeList(EVT VT); + SDNodeFlags Flags; + public: /// Unique and persistent id per SDNode in the DAG. /// Used for debug printing. @@ -799,12 +844,12 @@ public: return nullptr; } - /// This could be defined as a virtual function and implemented more simply - /// and directly, but it is not to avoid creating a vtable for this class. - const SDNodeFlags *getFlags() const; + const SDNodeFlags getFlags() const { return Flags; } + void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; } /// Clear any flags in this node that aren't also set in Flags. - void intersectFlagsWith(const SDNodeFlags *Flags); + /// If Flags is not in a defined state then this has no effect. + void intersectFlagsWith(const SDNodeFlags Flags); /// Return the number of values defined/returned by this operator. unsigned getNumValues() const { return NumValues; } @@ -1032,43 +1077,6 @@ inline void SDUse::setNode(SDNode *N) { if (N) N->addUse(*this); } -/// Returns true if the opcode is a binary operation with flags. -static bool isBinOpWithFlags(unsigned Opcode) { - switch (Opcode) { - case ISD::SDIV: - case ISD::UDIV: - case ISD::SRA: - case ISD::SRL: - case ISD::MUL: - case ISD::ADD: - case ISD::SUB: - case ISD::SHL: - case ISD::FADD: - case ISD::FDIV: - case ISD::FMUL: - case ISD::FREM: - case ISD::FSUB: - return true; - default: - return false; - } -} - -/// This class is an extension of BinarySDNode -/// used from those opcodes that have associated extra flags. -class BinaryWithFlagsSDNode : public SDNode { -public: - SDNodeFlags Flags; - - BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, - SDVTList VTs, const SDNodeFlags &NodeFlags) - : SDNode(Opc, Order, dl, VTs), Flags(NodeFlags) {} - - static bool classof(const SDNode *N) { - return isBinOpWithFlags(N->getOpcode()); - } -}; - /// This class is used to form a handle around another node that /// is persistent and is updated across invocations of replaceAllUsesWith on its /// operand. This node should be directly created by end-users and not added to diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index cd8434475451..b87a5e56699e 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -42,7 +42,7 @@ def v64i1 : ValueType<64 , 19>; // 64 x i1 vector value def v512i1 : ValueType<512, 20>; // 512 x i1 vector value def v1024i1: ValueType<1024,21>; //1024 x i1 vector value -def v1i8 : ValueType<16, 22>; // 1 x i8 vector value +def v1i8 : ValueType<8, 22>; // 1 x i8 vector value def v2i8 : ValueType<16 , 23>; // 2 x i8 vector value def v4i8 : ValueType<32 , 24>; // 4 x i8 vector value def v8i8 : ValueType<64 , 25>; // 8 x i8 vector value diff --git a/include/llvm/DebugInfo/CodeView/CVRecord.h b/include/llvm/DebugInfo/CodeView/CVRecord.h index 487f3b6446fa..086d6dff11c5 100644 --- a/include/llvm/DebugInfo/CodeView/CVRecord.h +++ b/include/llvm/DebugInfo/CodeView/CVRecord.h @@ -50,8 +50,10 @@ public: template <typename Kind> struct VarStreamArrayExtractor<codeview::CVRecord<Kind>> { - Error operator()(BinaryStreamRef Stream, uint32_t &Len, - codeview::CVRecord<Kind> &Item) const { + typedef void ContextType; + + static Error extract(BinaryStreamRef Stream, uint32_t &Len, + codeview::CVRecord<Kind> &Item, void *Ctx) { using namespace codeview; const RecordPrefix *Prefix = nullptr; BinaryStreamReader Reader(Stream); diff --git a/include/llvm/DebugInfo/CodeView/CodeView.h b/include/llvm/DebugInfo/CodeView/CodeView.h index e599f8a19e34..f881ad0c9d80 100644 --- a/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/include/llvm/DebugInfo/CodeView/CodeView.h @@ -291,7 +291,7 @@ enum class ModifierOptions : uint16_t { }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions) -enum class ModuleSubstreamKind : uint32_t { +enum class ModuleDebugFragmentKind : uint32_t { None = 0, Symbols = 0xf1, Lines = 0xf2, @@ -547,7 +547,8 @@ enum class TrampolineType : uint16_t { TrampIncremental, BranchIsland }; enum class FileChecksumKind : uint8_t { None, MD5, SHA1, SHA256 }; enum LineFlags : uint16_t { - HaveColumns = 1, // CV_LINES_HAVE_COLUMNS + LF_None = 0, + LF_HaveColumns = 1, // CV_LINES_HAVE_COLUMNS }; } } diff --git a/include/llvm/DebugInfo/CodeView/Line.h b/include/llvm/DebugInfo/CodeView/Line.h index 975b503fe30b..ac229c337513 100644 --- a/include/llvm/DebugInfo/CodeView/Line.h +++ b/include/llvm/DebugInfo/CodeView/Line.h @@ -127,27 +127,6 @@ public: bool isNeverStepInto() const { return LineInf.isNeverStepInto(); } }; -enum class InlineeLinesSignature : uint32_t { - Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE - ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX -}; - -struct InlineeSourceLine { - TypeIndex Inlinee; // ID of the function that was inlined. - ulittle32_t FileID; // Offset into FileChecksums subsection. - ulittle32_t SourceLineNum; // First line of inlined code. - // If extra files present: - // ulittle32_t ExtraFileCount; - // ulittle32_t Files[]; -}; - -struct FileChecksum { - ulittle32_t FileNameOffset; // Byte offset of filename in global string table. - uint8_t ChecksumSize; // Number of bytes of checksum. - uint8_t ChecksumKind; // FileChecksumKind - // Checksum bytes follow. -}; - } // namespace codeview } // namespace llvm diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h new file mode 100644 index 000000000000..a5a3b851b841 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h @@ -0,0 +1,91 @@ +//===- ModuleDebugFileChecksumFragment.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFILECHECKSUMFRAGMENT_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" + +namespace llvm { +namespace codeview { + +struct FileChecksumEntry { + uint32_t FileNameOffset; // Byte offset of filename in global stringtable. + FileChecksumKind Kind; // The type of checksum. + ArrayRef<uint8_t> Checksum; // The bytes of the checksum. +}; +} +} + +namespace llvm { +template <> struct VarStreamArrayExtractor<codeview::FileChecksumEntry> { +public: + typedef void ContextType; + + static Error extract(BinaryStreamRef Stream, uint32_t &Len, + codeview::FileChecksumEntry &Item, void *Ctx); +}; +} + +namespace llvm { +namespace codeview { +class ModuleDebugFileChecksumFragmentRef final : public ModuleDebugFragmentRef { + typedef VarStreamArray<codeview::FileChecksumEntry> FileChecksumArray; + typedef FileChecksumArray::Iterator Iterator; + +public: + ModuleDebugFileChecksumFragmentRef() + : ModuleDebugFragmentRef(ModuleDebugFragmentKind::FileChecksums) {} + + static bool classof(const ModuleDebugFragmentRef *S) { + return S->kind() == ModuleDebugFragmentKind::FileChecksums; + } + + Error initialize(BinaryStreamReader Reader); + + Iterator begin() const { return Checksums.begin(); } + Iterator end() const { return Checksums.end(); } + + const FileChecksumArray &getArray() const { return Checksums; } + +private: + FileChecksumArray Checksums; +}; + +class ModuleDebugFileChecksumFragment final : public ModuleDebugFragment { +public: + ModuleDebugFileChecksumFragment(); + + static bool classof(const ModuleDebugFragment *S) { + return S->kind() == ModuleDebugFragmentKind::FileChecksums; + } + + void addChecksum(uint32_t StringTableOffset, FileChecksumKind Kind, + ArrayRef<uint8_t> Bytes); + + uint32_t calculateSerializedLength() override; + Error commit(BinaryStreamWriter &Writer) override; + uint32_t mapChecksumOffset(uint32_t StringTableOffset) const; + +private: + DenseMap<uint32_t, uint32_t> OffsetMap; + uint32_t SerializedSize = 0; + llvm::BumpPtrAllocator Storage; + std::vector<FileChecksumEntry> Checksums; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h new file mode 100644 index 000000000000..a5311cae9480 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFragment.h @@ -0,0 +1,48 @@ +//===- ModuleDebugFragment.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Casting.h" + +namespace llvm { +namespace codeview { + +class ModuleDebugFragmentRef { +public: + explicit ModuleDebugFragmentRef(ModuleDebugFragmentKind Kind) : Kind(Kind) {} + virtual ~ModuleDebugFragmentRef(); + + ModuleDebugFragmentKind kind() const { return Kind; } + +protected: + ModuleDebugFragmentKind Kind; +}; + +class ModuleDebugFragment { +public: + explicit ModuleDebugFragment(ModuleDebugFragmentKind Kind) : Kind(Kind) {} + virtual ~ModuleDebugFragment(); + + ModuleDebugFragmentKind kind() const { return Kind; } + + virtual Error commit(BinaryStreamWriter &Writer) = 0; + virtual uint32_t calculateSerializedLength() = 0; + +protected: + ModuleDebugFragmentKind Kind; +}; + +} // namespace codeview +} // namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENT_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h new file mode 100644 index 000000000000..b98c8605592c --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h @@ -0,0 +1,78 @@ +//===- ModuleDebugFragment.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamRef.h" +#include "llvm/Support/BinaryStreamWriter.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { + +class ModuleDebugFragment; + +// Corresponds to the `CV_DebugSSubsectionHeader_t` structure. +struct ModuleDebugFragmentHeader { + support::ulittle32_t Kind; // codeview::ModuleDebugFragmentKind enum + support::ulittle32_t Length; // number of bytes occupied by this record. +}; + +class ModuleDebugFragmentRecord { +public: + ModuleDebugFragmentRecord(); + ModuleDebugFragmentRecord(ModuleDebugFragmentKind Kind, BinaryStreamRef Data); + + static Error initialize(BinaryStreamRef Stream, + ModuleDebugFragmentRecord &Info); + + uint32_t getRecordLength() const; + ModuleDebugFragmentKind kind() const; + BinaryStreamRef getRecordData() const; + +private: + ModuleDebugFragmentKind Kind; + BinaryStreamRef Data; +}; + +class ModuleDebugFragmentRecordBuilder { +public: + ModuleDebugFragmentRecordBuilder(ModuleDebugFragmentKind Kind, + ModuleDebugFragment &Frag); + uint32_t calculateSerializedLength(); + Error commit(BinaryStreamWriter &Writer); + +private: + ModuleDebugFragmentKind Kind; + ModuleDebugFragment &Frag; +}; + +typedef VarStreamArray<ModuleDebugFragmentRecord> ModuleDebugFragmentArray; + +} // namespace codeview + +template <> +struct VarStreamArrayExtractor<codeview::ModuleDebugFragmentRecord> { + typedef void ContextType; + + static Error extract(BinaryStreamRef Stream, uint32_t &Length, + codeview::ModuleDebugFragmentRecord &Info, void *Ctx) { + if (auto EC = codeview::ModuleDebugFragmentRecord::initialize(Stream, Info)) + return EC; + Length = Info.getRecordLength(); + return Error::success(); + } +}; +} // namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h new file mode 100644 index 000000000000..1f55d2024203 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h @@ -0,0 +1,68 @@ +//===- ModuleDebugFragmentVisitor.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H + +#include "llvm/Support/Error.h" +#include <cstdint> + +namespace llvm { + +namespace codeview { + +class ModuleDebugFileChecksumFragmentRef; +class ModuleDebugFragmentRecord; +class ModuleDebugInlineeLineFragmentRef; +class ModuleDebugLineFragmentRef; +class ModuleDebugUnknownFragmentRef; + +class ModuleDebugFragmentVisitor { +public: + virtual ~ModuleDebugFragmentVisitor() = default; + + virtual Error visitUnknown(ModuleDebugUnknownFragmentRef &Unknown) { + return Error::success(); + } + virtual Error visitLines(ModuleDebugLineFragmentRef &Lines) { + return Error::success(); + } + + virtual Error + visitFileChecksums(ModuleDebugFileChecksumFragmentRef &Checksums) { + return Error::success(); + } + + virtual Error visitInlineeLines(ModuleDebugInlineeLineFragmentRef &Inlinees) { + return Error::success(); + } + + virtual Error finished() { return Error::success(); } +}; + +Error visitModuleDebugFragment(const ModuleDebugFragmentRecord &R, + ModuleDebugFragmentVisitor &V); + +template <typename T> +Error visitModuleDebugFragments(T &&FragmentRange, + ModuleDebugFragmentVisitor &V) { + for (const auto &L : FragmentRange) { + if (auto EC = visitModuleDebugFragment(L, V)) + return EC; + } + if (auto EC = V.finished()) + return EC; + return Error::success(); +} + +} // end namespace codeview + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTVISITOR_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h new file mode 100644 index 000000000000..177367c111c3 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h @@ -0,0 +1,103 @@ +//===- ModuleDebugInlineeLinesFragment.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H + +#include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { + +class ModuleDebugInlineeLineFragmentRef; + +enum class InlineeLinesSignature : uint32_t { + Normal, // CV_INLINEE_SOURCE_LINE_SIGNATURE + ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX +}; + +struct InlineeSourceLineHeader { + TypeIndex Inlinee; // ID of the function that was inlined. + support::ulittle32_t FileID; // Offset into FileChecksums subsection. + support::ulittle32_t SourceLineNum; // First line of inlined code. + // If extra files present: + // ulittle32_t ExtraFileCount; + // ulittle32_t Files[]; +}; + +struct InlineeSourceLine { + const InlineeSourceLineHeader *Header; + FixedStreamArray<support::ulittle32_t> ExtraFiles; +}; +} + +template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> { + typedef codeview::ModuleDebugInlineeLineFragmentRef ContextType; + + static Error extract(BinaryStreamRef Stream, uint32_t &Len, + codeview::InlineeSourceLine &Item, + ContextType *Fragment); +}; + +namespace codeview { +class ModuleDebugInlineeLineFragmentRef final : public ModuleDebugFragmentRef { + typedef VarStreamArray<InlineeSourceLine> LinesArray; + typedef LinesArray::Iterator Iterator; + +public: + ModuleDebugInlineeLineFragmentRef(); + + static bool classof(const ModuleDebugFragmentRef *S) { + return S->kind() == ModuleDebugFragmentKind::InlineeLines; + } + + Error initialize(BinaryStreamReader Reader); + bool hasExtraFiles() const; + + Iterator begin() const { return Lines.begin(); } + Iterator end() const { return Lines.end(); } + +private: + InlineeLinesSignature Signature; + VarStreamArray<InlineeSourceLine> Lines; +}; + +class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment { +public: + explicit ModuleDebugInlineeLineFragment(bool HasExtraFiles); + + static bool classof(const ModuleDebugFragment *S) { + return S->kind() == ModuleDebugFragmentKind::InlineeLines; + } + + Error commit(BinaryStreamWriter &Writer) override; + uint32_t calculateSerializedLength() override; + + void addInlineSite(TypeIndex FuncId, uint32_t FileOffset, + uint32_t SourceLine); + void addExtraFile(uint32_t FileOffset); + +private: + bool HasExtraFiles = false; + uint32_t ExtraFileCount = 0; + + struct Entry { + std::vector<support::ulittle32_t> ExtraFiles; + InlineeSourceLineHeader Header; + }; + std::vector<Entry> Entries; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h new file mode 100644 index 000000000000..dcfe86dd8503 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h @@ -0,0 +1,137 @@ +//===- ModuleDebugLineFragment.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H + +#include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" +#include "llvm/Support/BinaryStreamArray.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Error.h" + +namespace llvm { +namespace codeview { + +// Corresponds to the `CV_DebugSLinesHeader_t` structure. +struct LineFragmentHeader { + support::ulittle32_t RelocOffset; // Code offset of line contribution. + support::ulittle16_t RelocSegment; // Code segment of line contribution. + support::ulittle16_t Flags; // See LineFlags enumeration. + support::ulittle32_t CodeSize; // Code size of this line contribution. +}; + +// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. +struct LineBlockFragmentHeader { + support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File + // checksums buffer. The checksum entry then + // contains another offset into the string + // table of the actual name. + support::ulittle32_t NumLines; // Number of lines + support::ulittle32_t BlockSize; // Code size of block, in bytes. + // The following two variable length arrays appear immediately after the + // header. The structure definitions follow. + // LineNumberEntry Lines[NumLines]; + // ColumnNumberEntry Columns[NumLines]; +}; + +// Corresponds to `CV_Line_t` structure +struct LineNumberEntry { + support::ulittle32_t Offset; // Offset to start of code bytes for line number + support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1 +}; + +// Corresponds to `CV_Column_t` structure +struct ColumnNumberEntry { + support::ulittle16_t StartColumn; + support::ulittle16_t EndColumn; +}; + +struct LineColumnEntry { + support::ulittle32_t NameIndex; + FixedStreamArray<LineNumberEntry> LineNumbers; + FixedStreamArray<ColumnNumberEntry> Columns; +}; + +class LineColumnExtractor { +public: + typedef const LineFragmentHeader ContextType; + + static Error extract(BinaryStreamRef Stream, uint32_t &Len, + LineColumnEntry &Item, const LineFragmentHeader *Header); +}; + +class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef { + friend class LineColumnExtractor; + typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray; + typedef LineInfoArray::Iterator Iterator; + +public: + ModuleDebugLineFragmentRef(); + + static bool classof(const ModuleDebugFragmentRef *S) { + return S->kind() == ModuleDebugFragmentKind::Lines; + } + + Error initialize(BinaryStreamReader Reader); + + Iterator begin() const { return LinesAndColumns.begin(); } + Iterator end() const { return LinesAndColumns.end(); } + + const LineFragmentHeader *header() const { return Header; } + + bool hasColumnInfo() const; + +private: + const LineFragmentHeader *Header = nullptr; + LineInfoArray LinesAndColumns; +}; + +class ModuleDebugLineFragment final : public ModuleDebugFragment { + struct Block { + Block(uint32_t ChecksumBufferOffset) + : ChecksumBufferOffset(ChecksumBufferOffset) {} + + uint32_t ChecksumBufferOffset; + std::vector<LineNumberEntry> Lines; + std::vector<ColumnNumberEntry> Columns; + }; + +public: + ModuleDebugLineFragment(); + + static bool classof(const ModuleDebugFragment *S) { + return S->kind() == ModuleDebugFragmentKind::Lines; + } + + void createBlock(uint32_t ChecksumBufferOffset); + void addLineInfo(uint32_t Offset, const LineInfo &Line); + void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line, + uint32_t ColStart, uint32_t ColEnd); + + uint32_t calculateSerializedLength() override; + Error commit(BinaryStreamWriter &Writer) override; + + void setRelocationAddress(uint16_t Segment, uint16_t Offset); + void setCodeSize(uint32_t Size); + void setFlags(LineFlags Flags); + + bool hasColumnInfo() const; + +private: + uint16_t RelocOffset = 0; + uint16_t RelocSegment = 0; + uint32_t CodeSize = 0; + LineFlags Flags = LF_None; + std::vector<Block> Blocks; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h b/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h new file mode 100644 index 000000000000..b8c1c02e5cf1 --- /dev/null +++ b/include/llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h @@ -0,0 +1,33 @@ +//===- ModuleDebugUnknownFragment.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H +#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGUNKNOWNFRAGMENT_H + +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" +#include "llvm/Support/BinaryStreamRef.h" + +namespace llvm { +namespace codeview { + +class ModuleDebugUnknownFragmentRef final : public ModuleDebugFragmentRef { +public: + ModuleDebugUnknownFragmentRef(ModuleDebugFragmentKind Kind, + BinaryStreamRef Data) + : ModuleDebugFragmentRef(Kind), Data(Data) {} + + BinaryStreamRef getData() const { return Data; } + +private: + BinaryStreamRef Data; +}; +} +} + +#endif diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h b/include/llvm/DebugInfo/CodeView/ModuleSubstream.h deleted file mode 100644 index a1c5c93cc3f8..000000000000 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstream.h +++ /dev/null @@ -1,87 +0,0 @@ -//===- ModuleSubstream.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H -#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H - -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/Support/BinaryStreamArray.h" -#include "llvm/Support/BinaryStreamRef.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" - -namespace llvm { -namespace codeview { - -// Corresponds to the `CV_DebugSSubsectionHeader_t` structure. -struct ModuleSubsectionHeader { - support::ulittle32_t Kind; // codeview::ModuleSubstreamKind enum - support::ulittle32_t Length; // number of bytes occupied by this record. -}; - -// Corresponds to the `CV_DebugSLinesHeader_t` structure. -struct LineSubstreamHeader { - support::ulittle32_t RelocOffset; // Code offset of line contribution. - support::ulittle16_t RelocSegment; // Code segment of line contribution. - support::ulittle16_t Flags; // See LineFlags enumeration. - support::ulittle32_t CodeSize; // Code size of this line contribution. -}; - -// Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. -struct LineFileBlockHeader { - support::ulittle32_t NameIndex; // Index in DBI name buffer of filename. - support::ulittle32_t NumLines; // Number of lines - support::ulittle32_t BlockSize; // Code size of block, in bytes. - // The following two variable length arrays appear immediately after the - // header. The structure definitions follow. - // LineNumberEntry Lines[NumLines]; - // ColumnNumberEntry Columns[NumLines]; -}; - -// Corresponds to `CV_Line_t` structure -struct LineNumberEntry { - support::ulittle32_t Offset; // Offset to start of code bytes for line number - support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1 -}; - -// Corresponds to `CV_Column_t` structure -struct ColumnNumberEntry { - support::ulittle16_t StartColumn; - support::ulittle16_t EndColumn; -}; - -class ModuleSubstream { -public: - ModuleSubstream(); - ModuleSubstream(ModuleSubstreamKind Kind, BinaryStreamRef Data); - static Error initialize(BinaryStreamRef Stream, ModuleSubstream &Info); - uint32_t getRecordLength() const; - ModuleSubstreamKind getSubstreamKind() const; - BinaryStreamRef getRecordData() const; - -private: - ModuleSubstreamKind Kind; - BinaryStreamRef Data; -}; - -typedef VarStreamArray<ModuleSubstream> ModuleSubstreamArray; -} // namespace codeview - -template <> struct VarStreamArrayExtractor<codeview::ModuleSubstream> { - Error operator()(BinaryStreamRef Stream, uint32_t &Length, - codeview::ModuleSubstream &Info) const { - if (auto EC = codeview::ModuleSubstream::initialize(Stream, Info)) - return EC; - Length = Info.getRecordLength(); - return Error::success(); - } -}; -} // namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAM_H diff --git a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h b/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h deleted file mode 100644 index 31344a9427db..000000000000 --- a/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h +++ /dev/null @@ -1,132 +0,0 @@ -//===- ModuleSubstreamVisitor.h ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H -#define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/DebugInfo/CodeView/CodeView.h" -#include "llvm/DebugInfo/CodeView/CodeViewError.h" -#include "llvm/DebugInfo/CodeView/Line.h" -#include "llvm/DebugInfo/CodeView/ModuleSubstream.h" -#include "llvm/Support/BinaryStreamArray.h" -#include "llvm/Support/BinaryStreamReader.h" -#include "llvm/Support/BinaryStreamRef.h" -#include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" -#include <cstdint> - -namespace llvm { - -namespace codeview { - -struct LineColumnEntry { - support::ulittle32_t NameIndex; - FixedStreamArray<LineNumberEntry> LineNumbers; - FixedStreamArray<ColumnNumberEntry> Columns; -}; - -struct FileChecksumEntry { - uint32_t FileNameOffset; // Byte offset of filename in global stringtable. - FileChecksumKind Kind; // The type of checksum. - ArrayRef<uint8_t> Checksum; // The bytes of the checksum. -}; - -typedef VarStreamArray<LineColumnEntry> LineInfoArray; -typedef VarStreamArray<FileChecksumEntry> FileChecksumArray; - -class IModuleSubstreamVisitor { -public: - virtual ~IModuleSubstreamVisitor() = default; - - virtual Error visitUnknown(ModuleSubstreamKind Kind, - BinaryStreamRef Data) = 0; - virtual Error visitSymbols(BinaryStreamRef Data); - virtual Error visitLines(BinaryStreamRef Data, - const LineSubstreamHeader *Header, - const LineInfoArray &Lines); - virtual Error visitStringTable(BinaryStreamRef Data); - virtual Error visitFileChecksums(BinaryStreamRef Data, - const FileChecksumArray &Checksums); - virtual Error visitFrameData(BinaryStreamRef Data); - virtual Error visitInlineeLines(BinaryStreamRef Data); - virtual Error visitCrossScopeImports(BinaryStreamRef Data); - virtual Error visitCrossScopeExports(BinaryStreamRef Data); - virtual Error visitILLines(BinaryStreamRef Data); - virtual Error visitFuncMDTokenMap(BinaryStreamRef Data); - virtual Error visitTypeMDTokenMap(BinaryStreamRef Data); - virtual Error visitMergedAssemblyInput(BinaryStreamRef Data); - virtual Error visitCoffSymbolRVA(BinaryStreamRef Data); -}; - -Error visitModuleSubstream(const ModuleSubstream &R, - IModuleSubstreamVisitor &V); -} // end namespace codeview - -template <> class VarStreamArrayExtractor<codeview::LineColumnEntry> { -public: - VarStreamArrayExtractor(const codeview::LineSubstreamHeader *Header) - : Header(Header) {} - - Error operator()(BinaryStreamRef Stream, uint32_t &Len, - codeview::LineColumnEntry &Item) const { - using namespace codeview; - const LineFileBlockHeader *BlockHeader; - BinaryStreamReader Reader(Stream); - if (auto EC = Reader.readObject(BlockHeader)) - return EC; - bool HasColumn = Header->Flags & uint32_t(LineFlags::HaveColumns); - uint32_t LineInfoSize = - BlockHeader->NumLines * - (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0)); - if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader)) - return make_error<CodeViewError>(cv_error_code::corrupt_record, - "Invalid line block record size"); - uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader); - if (LineInfoSize > Size) - return make_error<CodeViewError>(cv_error_code::corrupt_record, - "Invalid line block record size"); - // The value recorded in BlockHeader->BlockSize includes the size of - // LineFileBlockHeader. - Len = BlockHeader->BlockSize; - Item.NameIndex = BlockHeader->NameIndex; - if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines)) - return EC; - if (HasColumn) { - if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines)) - return EC; - } - return Error::success(); - } - -private: - const codeview::LineSubstreamHeader *Header; -}; - -template <> class VarStreamArrayExtractor<codeview::FileChecksumEntry> { -public: - Error operator()(BinaryStreamRef Stream, uint32_t &Len, - codeview::FileChecksumEntry &Item) const { - using namespace codeview; - const FileChecksum *Header; - BinaryStreamReader Reader(Stream); - if (auto EC = Reader.readObject(Header)) - return EC; - Item.FileNameOffset = Header->FileNameOffset; - Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind); - if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize)) - return EC; - Len = sizeof(FileChecksum) + Header->ChecksumSize; - return Error::success(); - } -}; - -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H diff --git a/include/llvm/DebugInfo/CodeView/TypeDatabase.h b/include/llvm/DebugInfo/CodeView/TypeDatabase.h index 54ad862cfa7e..220de4bf0ee4 100644 --- a/include/llvm/DebugInfo/CodeView/TypeDatabase.h +++ b/include/llvm/DebugInfo/CodeView/TypeDatabase.h @@ -35,6 +35,7 @@ public: StringRef getTypeName(TypeIndex Index) const; const CVType &getTypeRecord(TypeIndex Index) const; + CVType &getTypeRecord(TypeIndex Index); bool containsTypeIndex(TypeIndex Index) const; diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index e3386a8dcd24..d51408122fc9 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -161,6 +161,10 @@ public: virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All, bool DumpEH = false, bool SummarizeTypes = false) = 0; + virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) { + // No verifier? Just say things went well. + return true; + } virtual DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h index d89e2c684cd3..3c04c6716ea3 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -106,6 +106,8 @@ public: void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All, bool DumpEH = false, bool SummarizeTypes = false) override; + bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; + typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range; typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range; typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range; diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index e5bb24707b63..dd0e2648bf30 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -24,7 +24,8 @@ class raw_ostream; class DWARFDebugLine { public: - DWARFDebugLine(const RelocAddrMap* LineInfoRelocMap) : RelocMap(LineInfoRelocMap) {} + DWARFDebugLine(const RelocAddrMap *LineInfoRelocMap) + : RelocMap(LineInfoRelocMap) {} struct FileNameEntry { FileNameEntry() = default; @@ -38,50 +39,46 @@ public: struct Prologue { Prologue(); - // The size in bytes of the statement information for this compilation unit - // (not including the total_length field itself). + /// The size in bytes of the statement information for this compilation unit + /// (not including the total_length field itself). uint64_t TotalLength; - // Version identifier for the statement information format. + /// Version identifier for the statement information format. uint16_t Version; - // The number of bytes following the prologue_length field to the beginning - // of the first byte of the statement program itself. + /// The number of bytes following the prologue_length field to the beginning + /// of the first byte of the statement program itself. uint64_t PrologueLength; - // The size in bytes of the smallest target machine instruction. Statement - // program opcodes that alter the address register first multiply their - // operands by this value. + /// The size in bytes of the smallest target machine instruction. Statement + /// program opcodes that alter the address register first multiply their + /// operands by this value. uint8_t MinInstLength; - // The maximum number of individual operations that may be encoded in an - // instruction. + /// The maximum number of individual operations that may be encoded in an + /// instruction. uint8_t MaxOpsPerInst; - // The initial value of theis_stmtregister. + /// The initial value of theis_stmtregister. uint8_t DefaultIsStmt; - // This parameter affects the meaning of the special opcodes. See below. + /// This parameter affects the meaning of the special opcodes. See below. int8_t LineBase; - // This parameter affects the meaning of the special opcodes. See below. + /// This parameter affects the meaning of the special opcodes. See below. uint8_t LineRange; - // The number assigned to the first special opcode. + /// The number assigned to the first special opcode. uint8_t OpcodeBase; std::vector<uint8_t> StandardOpcodeLengths; - std::vector<const char*> IncludeDirectories; + std::vector<const char *> IncludeDirectories; std::vector<FileNameEntry> FileNames; bool IsDWARF64; - uint32_t sizeofTotalLength() const { - return IsDWARF64 ? 12 : 4; - } + uint32_t sizeofTotalLength() const { return IsDWARF64 ? 12 : 4; } - uint32_t sizeofPrologueLength() const { - return IsDWARF64 ? 8 : 4; - } + uint32_t sizeofPrologueLength() const { return IsDWARF64 ? 8 : 4; } - // Length of the prologue in bytes. + /// Length of the prologue in bytes. uint32_t getLength() const { return PrologueLength + sizeofTotalLength() + sizeof(Version) + sizeofPrologueLength(); } - // Length of the line table data in bytes (not including the prologue). + /// Length of the line table data in bytes (not including the prologue). uint32_t getStatementTableLength() const { return TotalLength + sizeofTotalLength() - getLength(); } @@ -92,70 +89,70 @@ public: void clear(); void dump(raw_ostream &OS) const; - bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr); + bool parse(DataExtractor DebugLineData, uint32_t *OffsetPtr); }; - // Standard .debug_line state machine structure. + /// Standard .debug_line state machine structure. struct Row { - explicit Row(bool default_is_stmt = false); + explicit Row(bool DefaultIsStmt = false); /// Called after a row is appended to the matrix. void postAppend(); - void reset(bool default_is_stmt); + void reset(bool DefaultIsStmt); void dump(raw_ostream &OS) const; - static bool orderByAddress(const Row& LHS, const Row& RHS) { + static bool orderByAddress(const Row &LHS, const Row &RHS) { return LHS.Address < RHS.Address; } - // The program-counter value corresponding to a machine instruction - // generated by the compiler. + /// The program-counter value corresponding to a machine instruction + /// generated by the compiler. uint64_t Address; - // An unsigned integer indicating a source line number. Lines are numbered - // beginning at 1. The compiler may emit the value 0 in cases where an - // instruction cannot be attributed to any source line. + /// An unsigned integer indicating a source line number. Lines are numbered + /// beginning at 1. The compiler may emit the value 0 in cases where an + /// instruction cannot be attributed to any source line. uint32_t Line; - // An unsigned integer indicating a column number within a source line. - // Columns are numbered beginning at 1. The value 0 is reserved to indicate - // that a statement begins at the 'left edge' of the line. + /// An unsigned integer indicating a column number within a source line. + /// Columns are numbered beginning at 1. The value 0 is reserved to indicate + /// that a statement begins at the 'left edge' of the line. uint16_t Column; - // An unsigned integer indicating the identity of the source file - // corresponding to a machine instruction. + /// An unsigned integer indicating the identity of the source file + /// corresponding to a machine instruction. uint16_t File; - // An unsigned integer representing the DWARF path discriminator value - // for this location. + /// An unsigned integer representing the DWARF path discriminator value + /// for this location. uint32_t Discriminator; - // An unsigned integer whose value encodes the applicable instruction set - // architecture for the current instruction. + /// An unsigned integer whose value encodes the applicable instruction set + /// architecture for the current instruction. uint8_t Isa; - // A boolean indicating that the current instruction is the beginning of a - // statement. - uint8_t IsStmt:1, - // A boolean indicating that the current instruction is the - // beginning of a basic block. - BasicBlock:1, - // A boolean indicating that the current address is that of the - // first byte after the end of a sequence of target machine - // instructions. - EndSequence:1, - // A boolean indicating that the current address is one (of possibly - // many) where execution should be suspended for an entry breakpoint - // of a function. - PrologueEnd:1, - // A boolean indicating that the current address is one (of possibly - // many) where execution should be suspended for an exit breakpoint - // of a function. - EpilogueBegin:1; + /// A boolean indicating that the current instruction is the beginning of a + /// statement. + uint8_t IsStmt : 1, + /// A boolean indicating that the current instruction is the + /// beginning of a basic block. + BasicBlock : 1, + /// A boolean indicating that the current address is that of the + /// first byte after the end of a sequence of target machine + /// instructions. + EndSequence : 1, + /// A boolean indicating that the current address is one (of possibly + /// many) where execution should be suspended for an entry breakpoint + /// of a function. + PrologueEnd : 1, + /// A boolean indicating that the current address is one (of possibly + /// many) where execution should be suspended for an exit breakpoint + /// of a function. + EpilogueBegin : 1; }; - // Represents a series of contiguous machine instructions. Line table for each - // compilation unit may consist of multiple sequences, which are not - // guaranteed to be in the order of ascending instruction address. + /// Represents a series of contiguous machine instructions. Line table for + /// each compilation unit may consist of multiple sequences, which are not + /// guaranteed to be in the order of ascending instruction address. struct Sequence { Sequence(); - // Sequence describes instructions at address range [LowPC, HighPC) - // and is described by line table rows [FirstRowIndex, LastRowIndex). + /// Sequence describes instructions at address range [LowPC, HighPC) + /// and is described by line table rows [FirstRowIndex, LastRowIndex). uint64_t LowPC; uint64_t HighPC; unsigned FirstRowIndex; @@ -164,7 +161,7 @@ public: void reset(); - static bool orderByLowPC(const Sequence& LHS, const Sequence& RHS) { + static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) { return LHS.LowPC < RHS.LowPC; } @@ -172,42 +169,38 @@ public: return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex); } - bool containsPC(uint64_t pc) const { - return (LowPC <= pc && pc < HighPC); - } + bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); } }; struct LineTable { LineTable(); - // Represents an invalid row + /// Represents an invalid row const uint32_t UnknownRowIndex = UINT32_MAX; - void appendRow(const DWARFDebugLine::Row &R) { - Rows.push_back(R); - } + void appendRow(const DWARFDebugLine::Row &R) { Rows.push_back(R); } void appendSequence(const DWARFDebugLine::Sequence &S) { Sequences.push_back(S); } - // Returns the index of the row with file/line info for a given address, - // or UnknownRowIndex if there is no such row. - uint32_t lookupAddress(uint64_t address) const; + /// Returns the index of the row with file/line info for a given address, + /// or UnknownRowIndex if there is no such row. + uint32_t lookupAddress(uint64_t Address) const; - bool lookupAddressRange(uint64_t address, uint64_t size, - std::vector<uint32_t> &result) const; + bool lookupAddressRange(uint64_t Address, uint64_t Size, + std::vector<uint32_t> &Result) const; bool hasFileAtIndex(uint64_t FileIndex) const; - // Extracts filename by its index in filename table in prologue. - // Returns true on success. + /// Extracts filename by its index in filename table in prologue. + /// Returns true on success. bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const; - // Fills the Result argument with the file and line information - // corresponding to Address. Returns true on success. + /// Fills the Result argument with the file and line information + /// corresponding to Address. Returns true on success. bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const; @@ -216,8 +209,8 @@ public: void clear(); /// Parse prologue and all rows. - bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap, - uint32_t *offset_ptr); + bool parse(DataExtractor DebugLineData, const RelocAddrMap *RMap, + uint32_t *OffsetPtr); struct Prologue Prologue; typedef std::vector<Row> RowVector; @@ -228,25 +221,25 @@ public: SequenceVector Sequences; private: - uint32_t findRowInSeq(const DWARFDebugLine::Sequence &seq, - uint64_t address) const; + uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq, + uint64_t Address) const; }; - const LineTable *getLineTable(uint32_t offset) const; - const LineTable *getOrParseLineTable(DataExtractor debug_line_data, - uint32_t offset); + const LineTable *getLineTable(uint32_t Offset) const; + const LineTable *getOrParseLineTable(DataExtractor DebugLineData, + uint32_t Offset); private: struct ParsingState { ParsingState(struct LineTable *LT); void resetRowAndSequence(); - void appendRowToMatrix(uint32_t offset); + void appendRowToMatrix(uint32_t Offset); - // Line table we're currently parsing. + /// Line table we're currently parsing. struct LineTable *LineTable; - // The row number that starts at zero for the prologue, and increases for - // each row added to the matrix. + /// The row number that starts at zero for the prologue, and increases for + /// each row added to the matrix. unsigned RowNumber; struct Row Row; struct Sequence Sequence; diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index c8d7a0c1ac7a..36b27228f5c6 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -59,6 +59,7 @@ public: DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {} dwarf::Form getForm() const { return Form; } + uint64_t getRawUValue() const { return Value.uval; } void setForm(dwarf::Form F) { Form = F; } void setUValue(uint64_t V) { Value.uval = V; } void setSValue(int64_t V) { Value.sval = V; } diff --git a/include/llvm/DebugInfo/PDB/Native/ModInfo.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h index d26d0d618449..879cb4285cd7 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModInfo.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h @@ -1,4 +1,4 @@ -//===- ModInfo.h - PDB module information -----------------------*- C++ -*-===// +//===- DbiModuleDescriptor.h - PDB module information -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_MODINFO_H -#define LLVM_DEBUGINFO_PDB_RAW_MODINFO_H +#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H +#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H #include "llvm/ADT/StringRef.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" @@ -22,21 +22,21 @@ namespace llvm { namespace pdb { -class ModInfo { +class DbiModuleDescriptor { friend class DbiStreamBuilder; public: - ModInfo(); - ModInfo(const ModInfo &Info); - ~ModInfo(); + DbiModuleDescriptor(); + DbiModuleDescriptor(const DbiModuleDescriptor &Info); + ~DbiModuleDescriptor(); - static Error initialize(BinaryStreamRef Stream, ModInfo &Info); + static Error initialize(BinaryStreamRef Stream, DbiModuleDescriptor &Info); bool hasECInfo() const; uint16_t getTypeServerIndex() const; uint16_t getModuleStreamIndex() const; uint32_t getSymbolDebugInfoByteSize() const; - uint32_t getLineInfoByteSize() const; + uint32_t getC11LineInfoByteSize() const; uint32_t getC13LineInfoByteSize() const; uint32_t getNumberOfFiles() const; uint32_t getSourceFileNameIndex() const; @@ -54,19 +54,20 @@ private: }; struct ModuleInfoEx { - ModuleInfoEx(const ModInfo &Info) : Info(Info) {} + ModuleInfoEx(const DbiModuleDescriptor &Info) : Info(Info) {} ModuleInfoEx(const ModuleInfoEx &Ex) = default; - ModInfo Info; + DbiModuleDescriptor Info; std::vector<StringRef> SourceFiles; }; } // end namespace pdb -template <> struct VarStreamArrayExtractor<pdb::ModInfo> { - Error operator()(BinaryStreamRef Stream, uint32_t &Length, - pdb::ModInfo &Info) const { - if (auto EC = pdb::ModInfo::initialize(Stream, Info)) +template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> { + typedef void ContextType; + static Error extract(BinaryStreamRef Stream, uint32_t &Length, + pdb::DbiModuleDescriptor &Info, void *Ctx) { + if (auto EC = pdb::DbiModuleDescriptor::initialize(Stream, Info)) return EC; Length = Info.getRecordLength(); return Error::success(); @@ -75,4 +76,4 @@ template <> struct VarStreamArrayExtractor<pdb::ModInfo> { } // end namespace llvm -#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFO_H +#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTOR_H diff --git a/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h new file mode 100644 index 000000000000..8cc5db981f56 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -0,0 +1,101 @@ +//===- DbiModuleDescriptorBuilder.h - PDB module information ----*- 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_DBIMODULEDESCRIPTORBUILDER_H +#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/Error.h" +#include <cstdint> +#include <string> +#include <vector> + +namespace llvm { +class BinaryStreamWriter; + +namespace codeview { +class ModuleDebugFragmentRecordBuilder; +} + +namespace msf { +class MSFBuilder; +struct MSFLayout; +} +namespace pdb { + +class DbiModuleDescriptorBuilder { + friend class DbiStreamBuilder; + +public: + DbiModuleDescriptorBuilder(StringRef ModuleName, uint32_t ModIndex, + msf::MSFBuilder &Msf); + ~DbiModuleDescriptorBuilder(); + + DbiModuleDescriptorBuilder(const DbiModuleDescriptorBuilder &) = delete; + DbiModuleDescriptorBuilder & + operator=(const DbiModuleDescriptorBuilder &) = delete; + + void setObjFileName(StringRef Name); + void addSymbol(codeview::CVSymbol Symbol); + + void addC13Fragment(std::unique_ptr<codeview::ModuleDebugLineFragment> Lines); + void addC13Fragment( + std::unique_ptr<codeview::ModuleDebugInlineeLineFragment> Inlinees); + void setC13FileChecksums( + std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> Checksums); + + uint16_t getStreamIndex() const; + StringRef getModuleName() const { return ModuleName; } + StringRef getObjFileName() const { return ObjFileName; } + + ArrayRef<std::string> source_files() const { + return makeArrayRef(SourceFiles); + } + + uint32_t calculateSerializedLength() const; + + void finalize(); + Error finalizeMsfLayout(); + + Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout, + WritableBinaryStreamRef MsfBuffer); + +private: + uint32_t calculateC13DebugInfoSize() const; + + void addSourceFile(StringRef Path); + msf::MSFBuilder &MSF; + + uint32_t SymbolByteSize = 0; + std::string ModuleName; + std::string ObjFileName; + std::vector<std::string> SourceFiles; + std::vector<codeview::CVSymbol> Symbols; + + std::unique_ptr<codeview::ModuleDebugFileChecksumFragment> ChecksumInfo; + std::vector<std::unique_ptr<codeview::ModuleDebugLineFragment>> LineInfo; + std::vector<std::unique_ptr<codeview::ModuleDebugInlineeLineFragment>> + Inlinees; + + std::vector<std::unique_ptr<codeview::ModuleDebugFragmentRecordBuilder>> + C13Builders; + + ModuleInfoHeader Layout; +}; + +} // end namespace pdb + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULEDESCRIPTORBUILDER_H diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStream.h b/include/llvm/DebugInfo/PDB/Native/DbiStream.h index f49f5aaefaca..84ae57f2e23a 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStream.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStream.h @@ -10,9 +10,9 @@ #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H -#include "llvm/DebugInfo/CodeView/ModuleSubstream.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" -#include "llvm/DebugInfo/PDB/Native/ModInfo.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawTypes.h" #include "llvm/DebugInfo/PDB/Native/StringTable.h" diff --git a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h index 16426bd93847..bcac182e2145 100644 --- a/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -31,7 +31,7 @@ struct coff_section; namespace pdb { class DbiStream; struct DbiStreamHeader; -class ModInfoBuilder; +class DbiModuleDescriptorBuilder; class PDBFile; class DbiStreamBuilder { @@ -57,8 +57,9 @@ public: uint32_t calculateSerializedLength() const; - Expected<ModInfoBuilder &> addModuleInfo(StringRef ModuleName); + Expected<DbiModuleDescriptorBuilder &> addModuleInfo(StringRef ModuleName); Error addModuleSourceFile(StringRef Module, StringRef File); + Expected<uint32_t> getSourceFileNameIndex(StringRef FileName); Error finalizeMsfLayout(); @@ -103,8 +104,8 @@ private: const DbiStreamHeader *Header; - StringMap<std::unique_ptr<ModInfoBuilder>> ModiMap; - std::vector<ModInfoBuilder *> ModiList; + StringMap<std::unique_ptr<DbiModuleDescriptorBuilder>> ModiMap; + std::vector<DbiModuleDescriptorBuilder *> ModiList; StringMap<uint32_t> SourceFileNames; diff --git a/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h b/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h deleted file mode 100644 index 605fd2483c3b..000000000000 --- a/include/llvm/DebugInfo/PDB/Native/ModInfoBuilder.h +++ /dev/null @@ -1,74 +0,0 @@ -//===- ModInfoBuilder.h - PDB module information ----------------*- 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_MODINFOBUILDER_H -#define LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/CodeView/SymbolRecord.h" -#include "llvm/DebugInfo/PDB/Native/RawTypes.h" -#include "llvm/Support/Error.h" -#include <cstdint> -#include <string> -#include <vector> - -namespace llvm { -class BinaryStreamWriter; - -namespace msf { -class MSFBuilder; -struct MSFLayout; -} -namespace pdb { - -class ModInfoBuilder { - friend class DbiStreamBuilder; - -public: - ModInfoBuilder(StringRef ModuleName, uint32_t ModIndex, msf::MSFBuilder &Msf); - - ModInfoBuilder(const ModInfoBuilder &) = delete; - ModInfoBuilder &operator=(const ModInfoBuilder &) = delete; - - void setObjFileName(StringRef Name); - void addSymbol(codeview::CVSymbol Symbol); - - uint16_t getStreamIndex() const; - StringRef getModuleName() const { return ModuleName; } - StringRef getObjFileName() const { return ObjFileName; } - - ArrayRef<std::string> source_files() const { - return makeArrayRef(SourceFiles); - } - - uint32_t calculateSerializedLength() const; - - void finalize(); - Error finalizeMsfLayout(); - - Error commit(BinaryStreamWriter &ModiWriter, const msf::MSFLayout &MsfLayout, - WritableBinaryStreamRef MsfBuffer); - -private: - void addSourceFile(StringRef Path); - msf::MSFBuilder &MSF; - - uint32_t SymbolByteSize = 0; - std::string ModuleName; - std::string ObjFileName; - std::vector<std::string> SourceFiles; - std::vector<codeview::CVSymbol> Symbols; - ModuleInfoHeader Layout; -}; - -} // end namespace pdb - -} // end namespace llvm - -#endif // LLVM_DEBUGINFO_PDB_RAW_MODINFOBUILDER_H diff --git a/include/llvm/DebugInfo/PDB/Native/ModStream.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h index b12d4ff375f3..2c95690ed580 100644 --- a/include/llvm/DebugInfo/PDB/Native/ModStream.h +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h @@ -1,4 +1,4 @@ -//===- ModStream.h - PDB Module Info Stream Access ------------------------===// +//===- ModuleDebugStream.h - PDB Module Info Stream Access ----------------===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H -#define LLVM_DEBUGINFO_PDB_RAW_MODSTREAM_H +#ifndef LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H +#define LLVM_DEBUGINFO_PDB_RAW_MODULEDEBUGSTREAM_H #include "llvm/ADT/iterator_range.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" -#include "llvm/DebugInfo/CodeView/ModuleSubstream.h" +#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/Support/BinaryStreamArray.h" @@ -22,13 +22,16 @@ namespace llvm { namespace pdb { class PDBFile; -class ModInfo; +class DbiModuleDescriptor; + +class ModuleDebugStreamRef { + typedef codeview::ModuleDebugFragmentArray::Iterator + LinesAndChecksumsIterator; -class ModStream { public: - ModStream(const ModInfo &Module, - std::unique_ptr<msf::MappedBlockStream> Stream); - ~ModStream(); + ModuleDebugStreamRef(const DbiModuleDescriptor &Module, + std::unique_ptr<msf::MappedBlockStream> Stream); + ~ModuleDebugStreamRef(); Error reload(); @@ -37,26 +40,25 @@ public: iterator_range<codeview::CVSymbolArray::Iterator> symbols(bool *HadError) const; - iterator_range<codeview::ModuleSubstreamArray::Iterator> - lines(bool *HadError) const; + llvm::iterator_range<LinesAndChecksumsIterator> linesAndChecksums() const; bool hasLineInfo() const; Error commit(); private: - const ModInfo &Mod; + const DbiModuleDescriptor &Mod; uint32_t Signature; std::unique_ptr<msf::MappedBlockStream> Stream; codeview::CVSymbolArray SymbolsSubstream; - BinaryStreamRef LinesSubstream; + BinaryStreamRef C11LinesSubstream; BinaryStreamRef C13LinesSubstream; BinaryStreamRef GlobalRefsSubstream; - codeview::ModuleSubstreamArray LineInfo; + codeview::ModuleDebugFragmentArray LinesAndChecksums; }; } } diff --git a/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/include/llvm/DebugInfo/PDB/Native/ModuleDebugStreamBuilder.h diff --git a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h index 8eeaf3e0ea49..b1d980679a45 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h @@ -10,7 +10,7 @@ #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVECOMPILANDSYMBOL_H -#include "llvm/DebugInfo/PDB/Native/ModInfo.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h" namespace llvm { diff --git a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h index 60a55ee50cc4..18022f599bba 100644 --- a/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h +++ b/include/llvm/DebugInfo/PDB/Native/NativeEnumModules.h @@ -11,7 +11,7 @@ #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMMODULES_H #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" -#include "llvm/DebugInfo/PDB/Native/ModInfo.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" namespace llvm { namespace pdb { diff --git a/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/include/llvm/DebugInfo/PDB/Native/RawTypes.h index 1b2631efce70..e1c6cf0021d5 100644 --- a/include/llvm/DebugInfo/PDB/Native/RawTypes.h +++ b/include/llvm/DebugInfo/PDB/Native/RawTypes.h @@ -200,7 +200,7 @@ struct FileInfoSubstreamHeader { }; struct ModInfoFlags { - /// uint16_t fWritten : 1; // True if ModInfo is dirty + /// uint16_t fWritten : 1; // True if DbiModuleDescriptor is dirty /// uint16_t fECEnabled : 1; // Is EC symbolic info present? (What is EC?) /// uint16_t unused : 6; // Reserved /// uint16_t iTSM : 8; // Type Server Index for this module @@ -231,8 +231,8 @@ struct ModuleInfoHeader { /// Size of local symbol debug info in above stream support::ulittle32_t SymBytes; - /// Size of line number debug info in above stream - support::ulittle32_t LineBytes; + /// Size of C11 line number info in above stream + support::ulittle32_t C11Bytes; /// Size of C13 line number info in above stream support::ulittle32_t C13Bytes; diff --git a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h index dd0f40b1978d..9c4b12e33ba0 100644 --- a/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h +++ b/include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h @@ -29,6 +29,7 @@ public: // If string S does not exist in the string table, insert it. // Returns the ID for S. uint32_t insert(StringRef S); + uint32_t getStringIndex(StringRef S); uint32_t finalize(); Error commit(BinaryStreamWriter &Writer) const; diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h index 9253adf7eedd..5103cc03a6bd 100644 --- a/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -56,8 +56,9 @@ public: Expected<DIGlobal> symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); void flush(); - static std::string DemangleName(const std::string &Name, - const SymbolizableModule *ModInfo); + static std::string + DemangleName(const std::string &Name, + const SymbolizableModule *DbiModuleDescriptor); private: // Bundles together object file with code/data and object file with diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h index 5c05f19abc1f..5ed6d030c984 100644 --- a/include/llvm/IR/Argument.h +++ b/include/llvm/IR/Argument.h @@ -115,8 +115,6 @@ public: void addAttr(Attribute Attr); /// Remove attributes from an argument. - void removeAttr(AttributeList AS); - void removeAttr(Attribute::AttrKind Kind); /// Check if an argument has a given attribute. diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index e2cd4c236fcc..af46034d5a9e 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -457,8 +457,11 @@ public: /// \brief Return the attribute object that exists at the given index. Attribute getAttribute(unsigned Index, StringRef Kind) const; + /// \brief Return the alignment of the return value. + unsigned getRetAlignment() const; + /// \brief Return the alignment for the specified function parameter. - unsigned getParamAlignment(unsigned Index) const; + unsigned getParamAlignment(unsigned ArgNo) const; /// \brief Get the stack alignment. unsigned getStackAlignment(unsigned Index) const; diff --git a/include/llvm/IR/Attributes.td b/include/llvm/IR/Attributes.td index 7b63638a3f6a..75867a6e5833 100644 --- a/include/llvm/IR/Attributes.td +++ b/include/llvm/IR/Attributes.td @@ -137,6 +137,9 @@ def SExt : EnumAttr<"signext">; /// +1 bias 0 means unaligned (different from alignstack=(1)). def StackAlignment : EnumAttr<"alignstack">; +/// Function can be speculated. +def Speculatable : EnumAttr<"speculatable">; + /// Stack protection. def StackProtect : EnumAttr<"ssp">; diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 79f59557a5d6..bad1d4e383d5 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -386,20 +386,25 @@ public: CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, Kind)); } + /// Extract the alignment of the return value. + unsigned getRetAlignment() const { + CALLSITE_DELEGATE_GETTER(getRetAlignment()); + } + /// Extract the alignment for a call or parameter (0=unknown). - uint16_t getParamAlignment(uint16_t i) const { - CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); + unsigned getParamAlignment(unsigned ArgNo) const { + CALLSITE_DELEGATE_GETTER(getParamAlignment(ArgNo)); } /// Extract the number of dereferenceable bytes for a call or parameter /// (0=unknown). - uint64_t getDereferenceableBytes(uint16_t i) const { + uint64_t getDereferenceableBytes(unsigned i) const { CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i)); } /// Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). - uint64_t getDereferenceableOrNullBytes(uint16_t i) const { + uint64_t getDereferenceableOrNullBytes(unsigned i) const { CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i)); } @@ -599,7 +604,7 @@ public: bool isReturnNonNull() const { if (hasRetAttr(Attribute::NonNull)) return true; - else if (getDereferenceableBytes(0) > 0 && + else if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 && getType()->getPointerAddressSpace() == 0) return true; diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h index 9cfbda1f6857..604e99c8b52c 100644 --- a/include/llvm/IR/CallingConv.h +++ b/include/llvm/IR/CallingConv.h @@ -196,6 +196,10 @@ namespace CallingConv { /// Register calling convention used for parameters transfer optimization X86_RegCall = 92, + /// Calling convention used for Mesa hull shaders. (= tessellation control + /// shaders) + AMDGPU_HS = 93, + /// The highest possible calling convention ID. Must be some 2^k - 1. MaxID = 1023 }; diff --git a/include/llvm/IR/DIBuilder.h b/include/llvm/IR/DIBuilder.h index a4b2a02d5050..4afb5d9d63b2 100644 --- a/include/llvm/IR/DIBuilder.h +++ b/include/llvm/IR/DIBuilder.h @@ -577,15 +577,14 @@ namespace llvm { /// These flags are used to emit dwarf attributes. /// \param isOptimized True if optimization is ON. /// \param TParams Function template parameters. - DISubprogram *createFunction(DIScope *Scope, StringRef Name, - StringRef LinkageName, DIFile *File, - unsigned LineNo, DISubroutineType *Ty, - bool isLocalToUnit, bool isDefinition, - unsigned ScopeLine, - DINode::DIFlags Flags = DINode::FlagZero, - bool isOptimized = false, - DITemplateParameterArray TParams = nullptr, - DISubprogram *Decl = nullptr); + /// \param ThrownTypes Exception types this function may throw. + DISubprogram *createFunction( + DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, + unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, + bool isDefinition, unsigned ScopeLine, + DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, + DITemplateParameterArray TParams = nullptr, + DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); /// Identical to createFunction, /// except that the resulting DbgNode is meant to be RAUWed. @@ -595,7 +594,7 @@ namespace llvm { bool isDefinition, unsigned ScopeLine, DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, DITemplateParameterArray TParams = nullptr, - DISubprogram *Decl = nullptr); + DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr); /// Create a new descriptor for the specified C++ method. /// See comments in \a DISubprogram* for descriptions of these fields. @@ -619,23 +618,23 @@ namespace llvm { /// This flags are used to emit dwarf attributes. /// \param isOptimized True if optimization is ON. /// \param TParams Function template parameters. + /// \param ThrownTypes Exception types this function may throw. DISubprogram *createMethod( DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0, int ThisAdjustment = 0, DIType *VTableHolder = nullptr, DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false, - DITemplateParameterArray TParams = nullptr); + DITemplateParameterArray TParams = nullptr, + DITypeArray ThrownTypes = nullptr); /// This creates new descriptor for a namespace with the specified /// parent scope. /// \param Scope Namespace scope /// \param Name Name of this namespace - /// \param File Source file - /// \param LineNo Line number /// \param ExportSymbols True for C++ inline namespaces. - DINamespace *createNameSpace(DIScope *Scope, StringRef Name, DIFile *File, - unsigned LineNo, bool ExportSymbols); + DINamespace *createNameSpace(DIScope *Scope, StringRef Name, + bool ExportSymbols); /// This creates new descriptor for a module with the specified /// parent scope. diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h index 8041e35e0e0a..0331d5229e7f 100644 --- a/include/llvm/IR/DebugInfoMetadata.h +++ b/include/llvm/IR/DebugInfoMetadata.h @@ -56,6 +56,8 @@ namespace llvm { +class DIBuilder; + template <typename T> class Optional; /// Holds a subclass of DINode. @@ -433,7 +435,7 @@ public: /// Return the raw underlying file. /// - /// An \a DIFile is an \a DIScope, but it doesn't point at a separate file + /// A \a DIFile is a \a DIScope, but it doesn't point at a separate file /// (it\em is the file). If \c this is an \a DIFile, we need to return \c /// this. Otherwise, return the first operand, which is where all other /// subclasses store their file pointer. @@ -1509,14 +1511,14 @@ class DISubprogram : public DILocalScope { unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams, DISubprogram *Declaration, - DILocalVariableArray Variables, StorageType Storage, - bool ShouldCreate = true) { + DILocalVariableArray Variables, DITypeArray ThrownTypes, + StorageType Storage, bool ShouldCreate = true) { return getImpl(Context, Scope, getCanonicalMDString(Context, Name), getCanonicalMDString(Context, LinkageName), File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams.get(), Declaration, Variables.get(), - Storage, ShouldCreate); + ThrownTypes.get(), Storage, ShouldCreate); } static DISubprogram * getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name, @@ -1525,15 +1527,16 @@ class DISubprogram : public DILocalScope { Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, - StorageType Storage, bool ShouldCreate = true); + Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true); TempDISubprogram cloneImpl() const { - return getTemporary( - getContext(), getScope(), getName(), getLinkageName(), getFile(), - getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(), - getContainingType(), getVirtuality(), getVirtualIndex(), - getThisAdjustment(), getFlags(), isOptimized(), getUnit(), - getTemplateParams(), getDeclaration(), getVariables()); + return getTemporary(getContext(), getScope(), getName(), getLinkageName(), + getFile(), getLine(), getType(), isLocalToUnit(), + isDefinition(), getScopeLine(), getContainingType(), + getVirtuality(), getVirtualIndex(), getThisAdjustment(), + getFlags(), isOptimized(), getUnit(), + getTemplateParams(), getDeclaration(), getVariables(), + getThrownTypes()); } public: @@ -1546,11 +1549,12 @@ public: bool IsOptimized, DICompileUnit *Unit, DITemplateParameterArray TemplateParams = nullptr, DISubprogram *Declaration = nullptr, - DILocalVariableArray Variables = nullptr), + DILocalVariableArray Variables = nullptr, + DITypeArray ThrownTypes = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, - TemplateParams, Declaration, Variables)) + TemplateParams, Declaration, Variables, ThrownTypes)) DEFINE_MDNODE_GET( DISubprogram, (Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File, @@ -1558,10 +1562,12 @@ public: unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr, - Metadata *Declaration = nullptr, Metadata *Variables = nullptr), + Metadata *Declaration = nullptr, Metadata *Variables = nullptr, + Metadata *ThrownTypes = nullptr), (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, - Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)) + Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables, + ThrownTypes)) TempDISubprogram clone() const { return cloneImpl(); } @@ -1610,11 +1616,7 @@ public: DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } StringRef getName() const { return getStringOperand(2); } - StringRef getDisplayName() const { return getStringOperand(3); } - StringRef getLinkageName() const { return getStringOperand(4); } - - MDString *getRawName() const { return getOperandAs<MDString>(2); } - MDString *getRawLinkageName() const { return getOperandAs<MDString>(4); } + StringRef getLinkageName() const { return getStringOperand(3); } DISubroutineType *getType() const { return cast_or_null<DISubroutineType>(getRawType()); @@ -1626,9 +1628,7 @@ public: DICompileUnit *getUnit() const { return cast_or_null<DICompileUnit>(getRawUnit()); } - void replaceUnit(DICompileUnit *CU) { - replaceOperandWith(7, CU); - } + void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); } DITemplateParameterArray getTemplateParams() const { return cast_or_null<MDTuple>(getRawTemplateParams()); } @@ -1638,14 +1638,26 @@ public: DILocalVariableArray getVariables() const { return cast_or_null<MDTuple>(getRawVariables()); } + DITypeArray getThrownTypes() const { + return cast_or_null<MDTuple>(getRawThrownTypes()); + } Metadata *getRawScope() const { return getOperand(1); } - Metadata *getRawType() const { return getOperand(5); } - Metadata *getRawContainingType() const { return getOperand(6); } - Metadata *getRawUnit() const { return getOperand(7); } - Metadata *getRawTemplateParams() const { return getOperand(8); } - Metadata *getRawDeclaration() const { return getOperand(9); } - Metadata *getRawVariables() const { return getOperand(10); } + MDString *getRawName() const { return getOperandAs<MDString>(2); } + MDString *getRawLinkageName() const { return getOperandAs<MDString>(3); } + Metadata *getRawType() const { return getOperand(4); } + Metadata *getRawUnit() const { return getOperand(5); } + Metadata *getRawDeclaration() const { return getOperand(6); } + Metadata *getRawVariables() const { return getOperand(7); } + Metadata *getRawContainingType() const { + return getNumOperands() > 8 ? getOperandAs<Metadata>(8) : nullptr; + } + Metadata *getRawTemplateParams() const { + return getNumOperands() > 9 ? getOperandAs<Metadata>(9) : nullptr; + } + Metadata *getRawThrownTypes() const { + return getNumOperands() > 10 ? getOperandAs<Metadata>(10) : nullptr; + } /// Check if this subprogram describes the given function. /// @@ -1841,45 +1853,40 @@ class DINamespace : public DIScope { friend class LLVMContextImpl; friend class MDNode; - unsigned Line; unsigned ExportSymbols : 1; - DINamespace(LLVMContext &Context, StorageType Storage, unsigned Line, - bool ExportSymbols, ArrayRef<Metadata *> Ops) + DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols, + ArrayRef<Metadata *> Ops) : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops), - Line(Line), ExportSymbols(ExportSymbols) {} + ExportSymbols(ExportSymbols) {} ~DINamespace() = default; static DINamespace *getImpl(LLVMContext &Context, DIScope *Scope, - DIFile *File, StringRef Name, unsigned Line, - bool ExportSymbols, StorageType Storage, - bool ShouldCreate = true) { - return getImpl(Context, Scope, File, getCanonicalMDString(Context, Name), - Line, ExportSymbols, Storage, ShouldCreate); + StringRef Name, bool ExportSymbols, + StorageType Storage, bool ShouldCreate = true) { + return getImpl(Context, Scope, getCanonicalMDString(Context, Name), + ExportSymbols, Storage, ShouldCreate); } static DINamespace *getImpl(LLVMContext &Context, Metadata *Scope, - Metadata *File, MDString *Name, unsigned Line, - bool ExportSymbols, StorageType Storage, - bool ShouldCreate = true); + MDString *Name, bool ExportSymbols, + StorageType Storage, bool ShouldCreate = true); TempDINamespace cloneImpl() const { - return getTemporary(getContext(), getScope(), getFile(), getName(), - getLine(), getExportSymbols()); + return getTemporary(getContext(), getScope(), getName(), + getExportSymbols()); } public: - DEFINE_MDNODE_GET(DINamespace, (DIScope * Scope, DIFile *File, StringRef Name, - unsigned Line, bool ExportSymbols), - (Scope, File, Name, Line, ExportSymbols)) DEFINE_MDNODE_GET(DINamespace, - (Metadata * Scope, Metadata *File, MDString *Name, - unsigned Line, bool ExportSymbols), - (Scope, File, Name, Line, ExportSymbols)) + (DIScope *Scope, StringRef Name, bool ExportSymbols), + (Scope, Name, ExportSymbols)) + DEFINE_MDNODE_GET(DINamespace, + (Metadata *Scope, MDString *Name, bool ExportSymbols), + (Scope, Name, ExportSymbols)) TempDINamespace clone() const { return cloneImpl(); } - unsigned getLine() const { return Line; } bool getExportSymbols() const { return ExportSymbols; } DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); } StringRef getName() const { return getStringOperand(2); } @@ -2265,6 +2272,17 @@ public: /// Return whether this is a piece of an aggregate variable. bool isFragment() const { return getFragmentInfo().hasValue(); } + + /// Append \p Ops with operations to apply the \p Offset. + static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset); + + /// Constants for DIExpression::prepend. + enum { NoDeref = false, WithDeref = true, WithStackValue = true }; + + /// Prepend \p DIExpr with a deref and offset operation and optionally turn it + /// into a stack value. + static DIExpression *prepend(const DIExpression *DIExpr, bool Deref, + int64_t Offset = 0, bool StackValue = false); }; /// Global variables. diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index a3762a44ccb6..9e723f977755 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -316,18 +316,20 @@ public: void addDereferenceableOrNullAttr(unsigned i, uint64_t Bytes); /// @brief Extract the alignment for a call or parameter (0=unknown). - unsigned getParamAlignment(unsigned i) const { - return AttributeSets.getParamAlignment(i); + unsigned getParamAlignment(unsigned ArgNo) const { + return AttributeSets.getParamAlignment(ArgNo); } /// @brief Extract the number of dereferenceable bytes for a call or /// parameter (0=unknown). + /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableBytes(unsigned i) const { return AttributeSets.getDereferenceableBytes(i); } /// @brief Extract the number of dereferenceable_or_null bytes for a call or /// parameter (0=unknown). + /// @param i AttributeList index, referring to a return value or argument. uint64_t getDereferenceableOrNullBytes(unsigned i) const { return AttributeSets.getDereferenceableOrNullBytes(i); } @@ -416,6 +418,14 @@ public: removeFnAttr(Attribute::Convergent); } + /// @brief Determine if the call has sideeffects. + bool isSpeculatable() const { + return hasFnAttribute(Attribute::Speculatable); + } + void setSpeculatable() { + addFnAttr(Attribute::Speculatable); + } + /// Determine if the function is known not to recurse, directly or /// indirectly. bool doesNotRecurse() const { @@ -440,10 +450,10 @@ public: } /// @brief Determine if the function returns a structure through first - /// pointer argument. + /// or second pointer argument. bool hasStructRetAttr() const { - return AttributeSets.hasAttribute(1, Attribute::StructRet) || - AttributeSets.hasAttribute(2, Attribute::StructRet); + return AttributeSets.hasParamAttribute(0, Attribute::StructRet) || + AttributeSets.hasParamAttribute(1, Attribute::StructRet); } /// @brief Determine if the parameter or return value is marked with NoAlias diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 518094735d72..6795b029cce9 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -1059,18 +1059,6 @@ public: return isFalseWhenEqual(getPredicate()); } - /// @brief Determine if Pred1 implies Pred2 is true when two compares have - /// matching operands. - bool isImpliedTrueByMatchingCmp(Predicate Pred2) const { - return isImpliedTrueByMatchingCmp(getPredicate(), Pred2); - } - - /// @brief Determine if Pred1 implies Pred2 is false when two compares have - /// matching operands. - bool isImpliedFalseByMatchingCmp(Predicate Pred2) const { - return isImpliedFalseByMatchingCmp(getPredicate(), Pred2); - } - /// @returns true if the predicate is unsigned, false otherwise. /// @brief Determine if the predicate is an unsigned operation. static bool isUnsigned(Predicate predicate); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index d23c1ddf9257..4d3f1dc267f2 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1714,9 +1714,12 @@ public: /// (\p i - 1) in the operand list. bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const; + /// Extract the alignment of the return value. + unsigned getRetAlignment() const { return Attrs.getRetAlignment(); } + /// Extract the alignment for a call or parameter (0=unknown). - unsigned getParamAlignment(unsigned i) const { - return Attrs.getParamAlignment(i); + unsigned getParamAlignment(unsigned ArgNo) const { + return Attrs.getParamAlignment(ArgNo); } /// Extract the number of dereferenceable bytes for a call or @@ -3804,9 +3807,12 @@ public: /// (\p i - 1) in the operand list. bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const; + /// Extract the alignment of the return value. + unsigned getRetAlignment() const { return Attrs.getRetAlignment(); } + /// Extract the alignment for a call or parameter (0=unknown). - unsigned getParamAlignment(unsigned i) const { - return Attrs.getParamAlignment(i); + unsigned getParamAlignment(unsigned ArgNo) const { + return Attrs.getParamAlignment(ArgNo); } /// Extract the number of dereferenceable bytes for a call or diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h index f69b5bfc0be2..05e3315cbab2 100644 --- a/include/llvm/IR/IntrinsicInst.h +++ b/include/llvm/IR/IntrinsicInst.h @@ -201,8 +201,8 @@ namespace llvm { Value *getNumElements() const { return getArgOperand(2); } void setNumElements(Value *V) { setArgOperand(2, V); } - uint64_t getSrcAlignment() const { return getParamAlignment(1); } - uint64_t getDstAlignment() const { return getParamAlignment(2); } + uint64_t getSrcAlignment() const { return getParamAlignment(0); } + uint64_t getDstAlignment() const { return getParamAlignment(1); } uint64_t getElementSizeInBytes() const { Value *Arg = getArgOperand(3); diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 309b21489224..39b992cd06a8 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -98,6 +98,18 @@ def IntrNoDuplicate : IntrinsicProperty; // Parallels the convergent attribute on LLVM IR functions. def IntrConvergent : IntrinsicProperty; +// This property indicates that the intrinsic is safe to speculate. +def IntrSpeculatable : IntrinsicProperty; + +// This property can be used to override the 'has no other side effects' +// language of the IntrNoMem, IntrReadMem, IntrWriteMem, and IntrArgMemOnly +// intrinsic properties. By default, intrinsics are assumed to have side +// effects, so this property is only necessary if you have defined one of +// the memory properties listed above. +// For this property, 'side effects' has the same meaning as 'side effects' +// defined by the hasSideEffects property of the TableGen Instruction class. +def IntrHasSideEffects : IntrinsicProperty; + //===----------------------------------------------------------------------===// // Types used by intrinsics. //===----------------------------------------------------------------------===// diff --git a/include/llvm/IR/IntrinsicsAMDGPU.td b/include/llvm/IR/IntrinsicsAMDGPU.td index 21d8a15e7e7a..d7413fe9e56f 100644 --- a/include/llvm/IR/IntrinsicsAMDGPU.td +++ b/include/llvm/IR/IntrinsicsAMDGPU.td @@ -12,10 +12,10 @@ //===----------------------------------------------------------------------===// class AMDGPUReadPreloadRegisterIntrinsic - : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>; class AMDGPUReadPreloadRegisterIntrinsicNamed<string name> - : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, GCCBuiltin<name>; + : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>, GCCBuiltin<name>; let TargetPrefix = "r600" in { @@ -47,7 +47,8 @@ def int_r600_group_barrier : GCCBuiltin<"__builtin_r600_group_barrier">, // AS 7 is PARAM_I_ADDRESS, used for kernel arguments def int_r600_implicitarg_ptr : GCCBuiltin<"__builtin_r600_implicitarg_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [], + [IntrNoMem, IntrSpeculatable]>; def int_r600_rat_store_typed : // 1st parameter: Data @@ -57,15 +58,15 @@ def int_r600_rat_store_typed : GCCBuiltin<"__builtin_r600_rat_store_typed">; def int_r600_recipsqrt_ieee : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_r600_recipsqrt_clamped : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_r600_cube : Intrinsic< - [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem] + [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable] >; } // End TargetPrefix = "r600" @@ -82,31 +83,51 @@ defm int_amdgcn_workgroup_id : AMDGPUReadPreloadRegisterIntrinsic_xyz_named def int_amdgcn_dispatch_ptr : GCCBuiltin<"__builtin_amdgcn_dispatch_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], + [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_queue_ptr : GCCBuiltin<"__builtin_amdgcn_queue_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], + [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_kernarg_segment_ptr : GCCBuiltin<"__builtin_amdgcn_kernarg_segment_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], + [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_implicitarg_ptr : GCCBuiltin<"__builtin_amdgcn_implicitarg_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], + [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_groupstaticsize : GCCBuiltin<"__builtin_amdgcn_groupstaticsize">, - Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_dispatch_id : GCCBuiltin<"__builtin_amdgcn_dispatch_id">, - Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_implicit_buffer_ptr : GCCBuiltin<"__builtin_amdgcn_implicit_buffer_ptr">, - Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], [IntrNoMem]>; + Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 2>], [], + [IntrNoMem, IntrSpeculatable]>; + +// Set EXEC to the 64-bit value given. +// This is always moved to the beginning of the basic block. +def int_amdgcn_init_exec : Intrinsic<[], + [llvm_i64_ty], // 64-bit literal constant + [IntrConvergent]>; + +// Set EXEC according to a thread count packed in an SGPR input: +// thread_count = (input >> bitoffset) & 0x7f; +// This is always moved to the beginning of the basic block. +def int_amdgcn_init_exec_from_input : Intrinsic<[], + [llvm_i32_ty, // 32-bit SGPR input + llvm_i32_ty], // bit offset of the thread count + [IntrConvergent]>; + //===----------------------------------------------------------------------===// // Instruction Intrinsics @@ -135,115 +156,129 @@ def int_amdgcn_div_scale : Intrinsic< // second. (0 = first, 1 = second). [llvm_anyfloat_ty, llvm_i1_ty], [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty], - [IntrNoMem] + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_div_fmas : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty], - [IntrNoMem] + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_div_fixup : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], - [IntrNoMem] + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_trig_preop : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_sin : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cos : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_log_clamp : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_fmul_legacy : GCCBuiltin<"__builtin_amdgcn_fmul_legacy">, - Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem] + Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_rcp : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_rcp_legacy : GCCBuiltin<"__builtin_amdgcn_rcp_legacy">, - Intrinsic<[llvm_float_ty], [llvm_float_ty], [IntrNoMem] + Intrinsic<[llvm_float_ty], [llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_rsq : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_rsq_legacy : GCCBuiltin<"__builtin_amdgcn_rsq_legacy">, Intrinsic< - [llvm_float_ty], [llvm_float_ty], [IntrNoMem] + [llvm_float_ty], [llvm_float_ty], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_rsq_clamp : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; def int_amdgcn_ldexp : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_frexp_mant : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_frexp_exp : Intrinsic< - [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem] + [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem, IntrSpeculatable] >; // v_fract is buggy on SI/CI. It mishandles infinities, may return 1.0 // and always uses rtz, so is not suitable for implementing the OpenCL // fract function. It should be ok on VI. def int_amdgcn_fract : Intrinsic< - [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem] + [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cvt_pkrtz : Intrinsic< - [llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_class : Intrinsic< - [llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty], [IntrNoMem] + [llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_fmed3 : GCCBuiltin<"__builtin_amdgcn_fmed3">, Intrinsic<[llvm_anyfloat_ty], - [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem] + [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cubeid : GCCBuiltin<"__builtin_amdgcn_cubeid">, Intrinsic<[llvm_float_ty], - [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_float_ty, llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cubema : GCCBuiltin<"__builtin_amdgcn_cubema">, Intrinsic<[llvm_float_ty], - [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_float_ty, llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cubesc : GCCBuiltin<"__builtin_amdgcn_cubesc">, Intrinsic<[llvm_float_ty], - [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_float_ty, llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_cubetc : GCCBuiltin<"__builtin_amdgcn_cubetc">, Intrinsic<[llvm_float_ty], - [llvm_float_ty, llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_float_ty, llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; // v_ffbh_i32, as opposed to v_ffbh_u32. For v_ffbh_u32, llvm.ctlz // should be used. def int_amdgcn_sffbh : - Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrNoMem]>; + Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], + [IntrNoMem, IntrSpeculatable] +>; // Fields should mirror atomicrmw @@ -527,7 +562,9 @@ def int_amdgcn_s_decperflevel : def int_amdgcn_s_getreg : GCCBuiltin<"__builtin_amdgcn_s_getreg">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty], + [IntrReadMem, IntrSpeculatable] +>; // __builtin_amdgcn_interp_mov <param>, <attr_chan>, <attr>, <m0> // param values: 0 = P10, 1 = P20, 2 = P0 @@ -535,23 +572,24 @@ def int_amdgcn_interp_mov : GCCBuiltin<"__builtin_amdgcn_interp_mov">, Intrinsic<[llvm_float_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; + [IntrNoMem, IntrSpeculatable]>; // __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0> +// This intrinsic reads from lds, but the memory values are constant, +// so it behaves like IntrNoMem. def int_amdgcn_interp_p1 : GCCBuiltin<"__builtin_amdgcn_interp_p1">, Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; // This intrinsic reads from lds, but the memory - // values are constant, so it behaves like IntrNoMem. + [IntrNoMem, IntrSpeculatable]>; // __builtin_amdgcn_interp_p2 <p1>, <j>, <attr_chan>, <attr>, <m0> def int_amdgcn_interp_p2 : GCCBuiltin<"__builtin_amdgcn_interp_p2">, Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], - [IntrNoMem]>; // See int_amdgcn_v_interp_p1 for why this is - // IntrNoMem. + [IntrNoMem, IntrSpeculatable]>; + // See int_amdgcn_v_interp_p1 for why this is IntrNoMem. // Pixel shaders only: whether the current pixel is live (i.e. not a helper // invocation for derivative computation). @@ -574,48 +612,68 @@ def int_amdgcn_ds_swizzle : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>; def int_amdgcn_ubfe : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrNoMem] + [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_sbfe : Intrinsic<[llvm_anyint_ty], - [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], [IntrNoMem] + [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] >; def int_amdgcn_lerp : GCCBuiltin<"__builtin_amdgcn_lerp">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_sad_u8 : GCCBuiltin<"__builtin_amdgcn_sad_u8">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_msad_u8 : GCCBuiltin<"__builtin_amdgcn_msad_u8">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_sad_hi_u8 : GCCBuiltin<"__builtin_amdgcn_sad_hi_u8">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_sad_u16 : GCCBuiltin<"__builtin_amdgcn_sad_u16">, - Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_qsad_pk_u16_u8 : GCCBuiltin<"__builtin_amdgcn_qsad_pk_u16_u8">, - Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_mqsad_pk_u16_u8 : GCCBuiltin<"__builtin_amdgcn_mqsad_pk_u16_u8">, - Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_mqsad_u32_u8 : GCCBuiltin<"__builtin_amdgcn_mqsad_u32_u8">, - Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_cvt_pk_u8_f32 : GCCBuiltin<"__builtin_amdgcn_cvt_pk_u8_f32">, - Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty], + [IntrNoMem, IntrSpeculatable] +>; def int_amdgcn_icmp : Intrinsic<[llvm_i64_ty], [llvm_anyint_ty, LLVMMatchType<0>, llvm_i32_ty], @@ -716,6 +774,7 @@ def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>; // Emit 2.5 ulp, no denormal division. Should only be inserted by // pass based on !fpmath metadata. def int_amdgcn_fdiv_fast : Intrinsic< - [llvm_float_ty], [llvm_float_ty, llvm_float_ty], [IntrNoMem] + [llvm_float_ty], [llvm_float_ty, llvm_float_ty], + [IntrNoMem, IntrSpeculatable] >; } diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 9c0a4159cad2..a7274fbfbced 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -644,13 +644,6 @@ public: return It->second.second; } - /// Add the given per-module index into this module index/summary, - /// assigning it the given module ID. Each module merged in should have - /// a unique ID, necessary for consistent renaming of promoted - /// static (local) variables. - void mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other, - uint64_t NextModuleId); - /// Convenience method for creating a promoted global name /// for the given value name of a local, and its original module's ID. static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash) { @@ -703,13 +696,6 @@ public: return &I->second; } - /// Remove entries in the GlobalValueMap that have empty summaries due to the - /// eager nature of map entry creation during VST parsing. These would - /// also be suppressed during combined index generation in mergeFrom(), - /// but if there was only one module or this was the first module we might - /// not invoke mergeFrom. - void removeEmptySummaryEntries(); - /// Collect for the given module the list of function it defines /// (GUID -> Summary). void collectDefinedFunctionsForModule(StringRef ModulePath, diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index 4838bac9e0f7..393618d5511b 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -34,19 +34,14 @@ protected: /// /// This is to avoid having a vtable for the light-weight handle pointers. The /// fully general Callback version does have a vtable. - enum HandleBaseKind { - Assert, - Callback, - Tracking, - Weak - }; + enum HandleBaseKind { Assert, Callback, Weak, WeakTracking }; ValueHandleBase(const ValueHandleBase &RHS) : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) - : PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) { - if (isValid(V)) + : PrevPair(nullptr, Kind), Next(nullptr), Val(RHS.getValPtr()) { + if (isValid(getValPtr())) AddToExistingUseList(RHS.getPrevPtr()); } @@ -54,43 +49,51 @@ private: PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; ValueHandleBase *Next; - Value* V; + Value *Val; + + void setValPtr(Value *V) { Val = V; } public: explicit ValueHandleBase(HandleBaseKind Kind) - : PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {} + : PrevPair(nullptr, Kind), Next(nullptr), Val(nullptr) {} ValueHandleBase(HandleBaseKind Kind, Value *V) - : PrevPair(nullptr, Kind), Next(nullptr), V(V) { - if (isValid(V)) + : PrevPair(nullptr, Kind), Next(nullptr), Val(V) { + if (isValid(getValPtr())) AddToUseList(); } ~ValueHandleBase() { - if (isValid(V)) + if (isValid(getValPtr())) RemoveFromUseList(); } Value *operator=(Value *RHS) { - if (V == RHS) return RHS; - if (isValid(V)) RemoveFromUseList(); - V = RHS; - if (isValid(V)) AddToUseList(); + if (getValPtr() == RHS) + return RHS; + if (isValid(getValPtr())) + RemoveFromUseList(); + setValPtr(RHS); + if (isValid(getValPtr())) + AddToUseList(); return RHS; } Value *operator=(const ValueHandleBase &RHS) { - if (V == RHS.V) return RHS.V; - if (isValid(V)) RemoveFromUseList(); - V = RHS.V; - if (isValid(V)) AddToExistingUseList(RHS.getPrevPtr()); - return V; + if (getValPtr() == RHS.getValPtr()) + return RHS.getValPtr(); + if (isValid(getValPtr())) + RemoveFromUseList(); + setValPtr(RHS.getValPtr()); + if (isValid(getValPtr())) + AddToExistingUseList(RHS.getPrevPtr()); + return getValPtr(); } - Value *operator->() const { return V; } - Value &operator*() const { return *V; } + Value *operator->() const { return getValPtr(); } + Value &operator*() const { return *getValPtr(); } protected: - Value *getValPtr() const { return V; } + Value *getValPtr() const { return Val; } static bool isValid(Value *V) { return V && @@ -105,7 +108,7 @@ protected: /// /// This should only be used if a derived class has manually removed the /// handle from the use list. - void clearValPtr() { V = nullptr; } + void clearValPtr() { setValPtr(nullptr); } public: // Callbacks made from Value. @@ -131,19 +134,16 @@ private: void AddToUseList(); }; -/// \brief Value handle that is nullable, but tries to track the Value. +/// \brief A nullable Value handle that is nullable. /// -/// This is a value handle that tries hard to point to a Value, even across -/// RAUW operations, but will null itself out if the value is destroyed. this -/// is useful for advisory sorts of information, but should not be used as the -/// key of a map (since the map would have to rearrange itself when the pointer -/// changes). +/// This is a value handle that points to a value, and nulls itself +/// out if that value is deleted. class WeakVH : public ValueHandleBase { public: WeakVH() : ValueHandleBase(Weak) {} WeakVH(Value *P) : ValueHandleBase(Weak, P) {} WeakVH(const WeakVH &RHS) - : ValueHandleBase(Weak, RHS) {} + : ValueHandleBase(Weak, RHS) {} WeakVH &operator=(const WeakVH &RHS) = default; @@ -170,6 +170,51 @@ template <> struct simplify_type<const WeakVH> { static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } }; +/// \brief Value handle that is nullable, but tries to track the Value. +/// +/// This is a value handle that tries hard to point to a Value, even across +/// RAUW operations, but will null itself out if the value is destroyed. this +/// is useful for advisory sorts of information, but should not be used as the +/// key of a map (since the map would have to rearrange itself when the pointer +/// changes). +class WeakTrackingVH : public ValueHandleBase { +public: + WeakTrackingVH() : ValueHandleBase(WeakTracking) {} + WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {} + WeakTrackingVH(const WeakTrackingVH &RHS) + : ValueHandleBase(WeakTracking, RHS) {} + + WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default; + + Value *operator=(Value *RHS) { + return ValueHandleBase::operator=(RHS); + } + Value *operator=(const ValueHandleBase &RHS) { + return ValueHandleBase::operator=(RHS); + } + + operator Value*() const { + return getValPtr(); + } + + bool pointsToAliveValue() const { + return ValueHandleBase::isValid(getValPtr()); + } +}; + +// Specialize simplify_type to allow WeakTrackingVH to participate in +// dyn_cast, isa, etc. +template <> struct simplify_type<WeakTrackingVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; } +}; +template <> struct simplify_type<const WeakTrackingVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) { + return WVH; + } +}; + /// \brief Value handle that asserts if the Value is deleted. /// /// This is a Value Handle that points to a value and asserts out if the value @@ -272,39 +317,37 @@ struct isPodLike<AssertingVH<T> > { /// to a Value (or subclass) across some operations which may move that value, /// but should never destroy it or replace it with some unacceptable type. /// -/// It is an error to do anything with a TrackingVH whose value has been -/// destroyed, except to destruct it. -/// /// It is an error to attempt to replace a value with one of a type which is /// incompatible with any of its outstanding TrackingVHs. -template<typename ValueTy> -class TrackingVH : public ValueHandleBase { - void CheckValidity() const { - Value *VP = ValueHandleBase::getValPtr(); - - // Null is always ok. - if (!VP) return; +/// +/// It is an error to read from a TrackingVH that does not point to a valid +/// value. A TrackingVH is said to not point to a valid value if either it +/// hasn't yet been assigned a value yet or because the value it was tracking +/// has since been deleted. +/// +/// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH +/// no longer points to a valid value. +template <typename ValueTy> class TrackingVH { + WeakTrackingVH InnerHandle; - // Check that this value is valid (i.e., it hasn't been deleted). We - // explicitly delay this check until access to avoid requiring clients to be - // unnecessarily careful w.r.t. destruction. - assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!"); +public: + ValueTy *getValPtr() const { + assert(InnerHandle.pointsToAliveValue() && + "TrackingVH must be non-null and valid on dereference!"); // Check that the value is a member of the correct subclass. We would like // to check this property on assignment for better debugging, but we don't // want to require a virtual interface on this VH. Instead we allow RAUW to // replace this value with a value of an invalid type, and check it here. - assert(isa<ValueTy>(VP) && + assert(isa<ValueTy>(InnerHandle) && "Tracked Value was replaced by one with an invalid type!"); + return cast<ValueTy>(InnerHandle); } - ValueTy *getValPtr() const { - CheckValidity(); - return (ValueTy*)ValueHandleBase::getValPtr(); - } void setValPtr(ValueTy *P) { - CheckValidity(); - ValueHandleBase::operator=(GetAsValue(P)); + // Assigning to non-valid TrackingVH's are fine so we just unconditionally + // assign here. + InnerHandle = GetAsValue(P); } // Convert a ValueTy*, which may be const, to the type the base @@ -313,8 +356,8 @@ class TrackingVH : public ValueHandleBase { static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } public: - TrackingVH() : ValueHandleBase(Tracking) {} - TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {} + TrackingVH() {} + TrackingVH(ValueTy *P) { setValPtr(P); } operator ValueTy*() const { return getValPtr(); @@ -359,7 +402,8 @@ public: /// /// Called when this->getValPtr() is destroyed, inside ~Value(), so you /// may call any non-virtual Value method on getValPtr(), but no subclass - /// methods. If WeakVH were implemented as a CallbackVH, it would use this + /// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use + /// this /// method to call setValPtr(NULL). AssertingVH would use this method to /// cause an assertion failure. /// @@ -370,7 +414,8 @@ public: /// \brief Callback for Value RAUW. /// /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, - /// _before_ any of the uses have actually been replaced. If WeakVH were + /// _before_ any of the uses have actually been replaced. If WeakTrackingVH + /// were /// implemented as a CallbackVH, it would use this method to call /// setValPtr(new_value). AssertingVH would do nothing in this method. virtual void allUsesReplacedWith(Value *) {} diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 15c8ff6d04de..44ff4c1a581b 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -329,6 +329,7 @@ void initializeSeparateConstOffsetFromGEPPass(PassRegistry&); void initializeShadowStackGCLoweringPass(PassRegistry&); void initializeShrinkWrapPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&); +void initializeSimpleLoopUnswitchLegacyPassPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSinkingLegacyPassPass(PassRegistry&); void initializeSjLjEHPreparePass(PassRegistry&); diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h index 643902377dd3..c34211c2bd12 100644 --- a/include/llvm/MC/ConstantPools.h +++ b/include/llvm/MC/ConstantPools.h @@ -42,7 +42,7 @@ struct ConstantPoolEntry { // A class to keep track of assembler-generated constant pools that are use to // implement the ldr-pseudo. class ConstantPool { - typedef SmallVector<ConstantPoolEntry, 4> EntryVecTy; + using EntryVecTy = SmallVector<ConstantPoolEntry, 4>; EntryVecTy Entries; DenseMap<int64_t, const MCSymbolRefExpr *> CachedEntries; @@ -80,7 +80,7 @@ class AssemblerConstantPools { // sections in a stable order to ensure that we have print the // constant pools in a deterministic order when printing an assembly // file. - typedef MapVector<MCSection *, ConstantPool> ConstantPoolMapTy; + using ConstantPoolMapTy = MapVector<MCSection *, ConstantPool>; ConstantPoolMapTy ConstantPools; public: diff --git a/include/llvm/MC/LaneBitmask.h b/include/llvm/MC/LaneBitmask.h index 89e60928405d..5ca06d1148e2 100644 --- a/include/llvm/MC/LaneBitmask.h +++ b/include/llvm/MC/LaneBitmask.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/LaneBitmask.h -----------------------------------*- C++ -*-===// +//===- llvm/MC/LaneBitmask.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -30,14 +30,16 @@ #ifndef LLVM_MC_LANEBITMASK_H #define LLVM_MC_LANEBITMASK_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/Printable.h" #include "llvm/Support/raw_ostream.h" namespace llvm { + struct LaneBitmask { // When changing the underlying type, change the format string as well. - typedef unsigned Type; + using Type = unsigned; enum : unsigned { BitWidth = 8*sizeof(Type) }; constexpr static const char *const FormatStr = "%08X"; @@ -84,6 +86,7 @@ namespace llvm { OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger()); }); } -} + +} // end namespace llvm #endif // LLVM_MC_LANEBITMASK_H diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index c29abaa03a6d..185b892d9621 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -60,36 +60,36 @@ class MCAssembler { friend class MCAsmLayout; public: - typedef std::vector<MCSection *> SectionListType; - typedef std::vector<const MCSymbol *> SymbolDataListType; + using SectionListType = std::vector<MCSection *>; + using SymbolDataListType = std::vector<const MCSymbol *>; - typedef pointee_iterator<SectionListType::const_iterator> const_iterator; - typedef pointee_iterator<SectionListType::iterator> iterator; + using const_iterator = pointee_iterator<SectionListType::const_iterator>; + using iterator = pointee_iterator<SectionListType::iterator>; - typedef pointee_iterator<SymbolDataListType::const_iterator> - const_symbol_iterator; - typedef pointee_iterator<SymbolDataListType::iterator> symbol_iterator; + using const_symbol_iterator = + pointee_iterator<SymbolDataListType::const_iterator>; + using symbol_iterator = pointee_iterator<SymbolDataListType::iterator>; - typedef iterator_range<symbol_iterator> symbol_range; - typedef iterator_range<const_symbol_iterator> const_symbol_range; + using symbol_range = iterator_range<symbol_iterator>; + using const_symbol_range = iterator_range<const_symbol_iterator>; - typedef std::vector<IndirectSymbolData>::const_iterator - const_indirect_symbol_iterator; - typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator; + using const_indirect_symbol_iterator = + std::vector<IndirectSymbolData>::const_iterator; + using indirect_symbol_iterator = std::vector<IndirectSymbolData>::iterator; - typedef std::vector<DataRegionData>::const_iterator - const_data_region_iterator; - typedef std::vector<DataRegionData>::iterator data_region_iterator; + using const_data_region_iterator = + std::vector<DataRegionData>::const_iterator; + using data_region_iterator = std::vector<DataRegionData>::iterator; /// MachO specific deployment target version info. // A Major version of 0 indicates that no version information was supplied // and so the corresponding load command should not be emitted. - typedef struct { + using VersionMinInfoType = struct { MCVersionMinType Kind; unsigned Major; unsigned Minor; unsigned Update; - } VersionMinInfoType; + }; private: MCContext &Context; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index b3106936e27f..9bea19631303 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -46,17 +46,19 @@ namespace llvm { class MCSectionELF; class MCSectionMachO; class MCSectionWasm; + class MCStreamer; class MCSymbol; class MCSymbolELF; class MCSymbolWasm; class SMLoc; + class SourceMgr; /// Context object for machine code objects. This class owns all of the /// sections that it creates. /// class MCContext { public: - typedef StringMap<MCSymbol *, BumpPtrAllocator &> SymbolTable; + using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>; private: /// The SourceMgr for this object, if any. @@ -223,10 +225,12 @@ namespace llvm { std::string SectionName; StringRef GroupName; unsigned UniqueID; + WasmSectionKey(StringRef SectionName, StringRef GroupName, unsigned UniqueID) : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) { } + bool operator<(const WasmSectionKey &Other) const { if (SectionName != Other.SectionName) return SectionName < Other.SectionName; diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 0d69c2005cb4..79f1b9525019 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -168,10 +168,10 @@ public: MCLineDivisions[Sec].push_back(LineEntry); } - typedef std::vector<MCDwarfLineEntry> MCDwarfLineEntryCollection; - typedef MCDwarfLineEntryCollection::iterator iterator; - typedef MCDwarfLineEntryCollection::const_iterator const_iterator; - typedef MapVector<MCSection *, MCDwarfLineEntryCollection> MCLineDivisionMap; + using MCDwarfLineEntryCollection = std::vector<MCDwarfLineEntry>; + using iterator = MCDwarfLineEntryCollection::iterator; + using const_iterator = MCDwarfLineEntryCollection::const_iterator; + using MCLineDivisionMap = MapVector<MCSection *, MCDwarfLineEntryCollection>; private: // A collection of MCDwarfLineEntry for each section. diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index c850abf42e2c..a91a31414bdb 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -28,7 +28,8 @@ class MCSymbol; class MCValue; class raw_ostream; class StringRef; -typedef DenseMap<const MCSection *, uint64_t> SectionAddrMap; + +using SectionAddrMap = DenseMap<const MCSection *, uint64_t>; /// \brief Base class for the full range of assembler expressions which are /// needed for parsing. diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index fc8257f90a9f..0ca530c45102 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -200,8 +200,8 @@ protected: Sec) {} public: - typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; - typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; + using const_fixup_iterator = SmallVectorImpl<MCFixup>::const_iterator; + using fixup_iterator = SmallVectorImpl<MCFixup>::iterator; SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 702279659371..9bf440ea96d2 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -176,8 +176,9 @@ public: void addOperand(const MCOperand &Op) { Operands.push_back(Op); } - typedef SmallVectorImpl<MCOperand>::iterator iterator; - typedef SmallVectorImpl<MCOperand>::const_iterator const_iterator; + using iterator = SmallVectorImpl<MCOperand>::iterator; + using const_iterator = SmallVectorImpl<MCOperand>::const_iterator; + void clear() { Operands.clear(); } void erase(iterator I) { Operands.erase(I); } size_t size() const { return Operands.size(); } diff --git a/include/llvm/MC/MCLinkerOptimizationHint.h b/include/llvm/MC/MCLinkerOptimizationHint.h index 0c3525bbeda6..f0fd07f43cf3 100644 --- a/include/llvm/MC/MCLinkerOptimizationHint.h +++ b/include/llvm/MC/MCLinkerOptimizationHint.h @@ -111,7 +111,7 @@ class MCLOHDirective { const MCAsmLayout &Layout) const; public: - typedef SmallVectorImpl<MCSymbol *> LOHArgs; + using LOHArgs = SmallVectorImpl<MCSymbol *>; MCLOHDirective(MCLOHType Kind, const LOHArgs &Args) : Kind(Kind), Args(Args.begin(), Args.end()) { @@ -140,7 +140,7 @@ class MCLOHContainer { SmallVector<MCLOHDirective, 32> Directives; public: - typedef SmallVectorImpl<MCLOHDirective> LOHDirectives; + using LOHDirectives = SmallVectorImpl<MCLOHDirective>; MCLOHContainer() = default; @@ -179,8 +179,8 @@ public: }; // Add types for specialized template using MCSymbol. -typedef MCLOHDirective::LOHArgs MCLOHArgs; -typedef MCLOHContainer::LOHDirectives MCLOHDirectives; +using MCLOHArgs = MCLOHDirective::LOHArgs; +using MCLOHDirectives = MCLOHContainer::LOHDirectives; } // end namespace llvm diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 7ddc7722e512..7836ece2d688 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -161,6 +161,7 @@ protected: // Can only create subclasses. bool IsAtStartOfStatement = true; AsmCommentConsumer *CommentConsumer = nullptr; + bool AltMacroMode; MCAsmLexer(); virtual AsmToken LexToken() = 0; @@ -175,6 +176,14 @@ public: MCAsmLexer &operator=(const MCAsmLexer &) = delete; virtual ~MCAsmLexer(); + bool IsaAltMacroMode() { + return AltMacroMode; + } + + void SetAltMacroMode(bool AltMacroSet) { + AltMacroMode = AltMacroSet; + } + /// Consume the next token from the input stream and return it. /// /// The lexer will continuosly return the end-of-file token once the end of diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 6763374185ec..75d45f490bde 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -67,9 +67,9 @@ public: /// assembly parsers. class MCAsmParser { public: - typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc); - typedef std::pair<MCAsmParserExtension*, DirectiveHandler> - ExtensionDirectiveHandler; + using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc); + using ExtensionDirectiveHandler = + std::pair<MCAsmParserExtension*, DirectiveHandler>; struct MCPendingError { SMLoc Loc; diff --git a/include/llvm/MC/MCParser/MCTargetAsmParser.h b/include/llvm/MC/MCParser/MCTargetAsmParser.h index c81a7624011f..b8d3180cd49c 100644 --- a/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -27,7 +27,7 @@ class MCStreamer; class MCSubtargetInfo; template <typename T> class SmallVectorImpl; -typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector; +using OperandVector = SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>>; enum AsmRewriteKind { AOK_Delete = 0, // Rewrite should be ignored. diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 015d0b96d9f2..de98abe0dc46 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -27,13 +27,13 @@ namespace llvm { /// An unsigned integer type large enough to represent all physical registers, /// but not necessarily virtual registers. -typedef uint16_t MCPhysReg; +using MCPhysReg = uint16_t; /// MCRegisterClass - Base class of TargetRegisterClass. class MCRegisterClass { public: - typedef const MCPhysReg* iterator; - typedef const MCPhysReg* const_iterator; + using iterator = const MCPhysReg*; + using const_iterator = const MCPhysReg*; const iterator RegsBegin; const uint8_t *const RegSet; @@ -134,7 +134,7 @@ struct MCRegisterDesc { /// class MCRegisterInfo { public: - typedef const MCRegisterClass *regclass_iterator; + using regclass_iterator = const MCRegisterClass *; /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be /// performed with a binary search. diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 2974d8f1b80b..7bfffbcdb7c2 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -47,13 +47,13 @@ public: BundleLockedAlignToEnd }; - typedef iplist<MCFragment> FragmentListType; + using FragmentListType = iplist<MCFragment>; - typedef FragmentListType::const_iterator const_iterator; - typedef FragmentListType::iterator iterator; + using const_iterator = FragmentListType::const_iterator; + using iterator = FragmentListType::iterator; - typedef FragmentListType::const_reverse_iterator const_reverse_iterator; - typedef FragmentListType::reverse_iterator reverse_iterator; + using const_reverse_iterator = FragmentListType::const_reverse_iterator; + using reverse_iterator = FragmentListType::reverse_iterator; private: MCSymbol *Begin; diff --git a/include/llvm/MC/MCSectionWasm.h b/include/llvm/MC/MCSectionWasm.h index 4e19196175c0..29d62a7a6f82 100644 --- a/include/llvm/MC/MCSectionWasm.h +++ b/include/llvm/MC/MCSectionWasm.h @@ -26,6 +26,7 @@ class MCSymbol; /// This represents a section on wasm. class MCSectionWasm final : public MCSection { +private: /// This is the name of the section. The referenced memory is owned by /// TargetLoweringObjectFileWasm's WasmUniqueMap. StringRef SectionName; @@ -40,10 +41,11 @@ class MCSectionWasm final : public MCSection { const MCSymbolWasm *Group; - // The offset of the MC function section in the wasm code section. + // The offset of the MC function/data section in the wasm code/data section. + // For data relocations the offset is relative to start of the data payload + // itself and does not include the size of the section header. uint64_t SectionOffset; -private: friend class MCContext; MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K, const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin) diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index eb301031ba3f..5390e7942424 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -44,12 +44,11 @@ class MCInstPrinter; class MCSection; class MCStreamer; class MCSymbolRefExpr; -class MCSymbolWasm; class MCSubtargetInfo; class raw_ostream; class Twine; -typedef std::pair<MCSection *, const MCExpr *> MCSectionSubPair; +using MCSectionSubPair = std::pair<MCSection *, const MCExpr *>; /// Target specific streamer interface. This is used so that targets can /// implement support for target specific assembly directives. diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index bb16463588c3..d1d5d070bf5b 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -26,6 +26,7 @@ #include <string> namespace llvm { + class MachineInstr; class MCInst; @@ -63,8 +64,7 @@ public: MCSubtargetInfo() = delete; MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete; MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete; - - virtual ~MCSubtargetInfo() {} + virtual ~MCSubtargetInfo() = default; /// getTargetTriple - Return the target triple string. const Triple &getTargetTriple() const { return TargetTriple; } @@ -178,11 +178,11 @@ public: /// Returns string representation of scheduler comment virtual std::string getSchedInfoStr(const MachineInstr &MI) const { - return std::string(); + return {}; } virtual std::string getSchedInfoStr(MCInst const &MCI) const { - return std::string(); + return {}; } }; diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index e8432afd8627..9b1cc6e7d7e8 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -145,10 +145,10 @@ protected: /// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit /// system, the name is a pointer so isn't going to satisfy the 8 byte /// alignment of uint64_t. Account for that here. - typedef union { + using NameEntryStorageTy = union { const StringMapEntry<bool> *NameEntry; uint64_t AlignmentPadding; - } NameEntryStorageTy; + }; MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary) : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false), diff --git a/include/llvm/MC/MCWasmObjectWriter.h b/include/llvm/MC/MCWasmObjectWriter.h index 6e458eaac9c8..a4dd382706d7 100644 --- a/include/llvm/MC/MCWasmObjectWriter.h +++ b/include/llvm/MC/MCWasmObjectWriter.h @@ -32,12 +32,12 @@ class raw_pwrite_stream; struct WasmRelocationEntry { uint64_t Offset; // Where is the relocation. const MCSymbolWasm *Symbol; // The symbol to relocate with. - uint64_t Addend; // A value to add to the symbol. + int64_t Addend; // A value to add to the symbol. unsigned Type; // The type of the relocation. MCSectionWasm *FixupSection;// The section the relocation is targeting. WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol, - uint64_t Addend, unsigned Type, + int64_t Addend, unsigned Type, MCSectionWasm *FixupSection) : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type), FixupSection(FixupSection) {} diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 06788326ff57..f42048e48ee3 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -42,7 +42,6 @@ protected: ID_MachOUniversalBinary, ID_COFFImportFile, ID_IR, // LLVM IR - ID_ModuleSummaryIndex, // Module summary index // Object and children. ID_StartObjects, @@ -128,8 +127,6 @@ public: return TypeID == ID_IR; } - bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; } - bool isLittleEndian() const { return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B || TypeID == ID_MachO32B || TypeID == ID_MachO64B); diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index e0bb8f1cf3dd..1b6aaf4be666 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -623,6 +623,15 @@ struct coff_base_reloc_block_entry { int getOffset() const { return Data & ((1 << 12) - 1); } }; +struct coff_resource_dir_table { + support::ulittle32_t Characteristics; + support::ulittle32_t TimeDateStamp; + support::ulittle16_t MajorVersion; + support::ulittle16_t MinorVersion; + support::ulittle16_t NumberOfNameEntries; + support::ulittle16_t NumberOfIDEntries; +}; + class COFFObjectFile : public ObjectFile { private: friend class ImportDirectoryEntryRef; diff --git a/include/llvm/Object/COFFImportFile.h b/include/llvm/Object/COFFImportFile.h index 4192fe7e5c90..78d9d679acd3 100644 --- a/include/llvm/Object/COFFImportFile.h +++ b/include/llvm/Object/COFFImportFile.h @@ -53,7 +53,7 @@ public: basic_symbol_iterator symbol_end() const override { DataRefImpl Symb; - Symb.p = isCode() ? 2 : 1; + Symb.p = isData() ? 1 : 2; return BasicSymbolRef(Symb, this); } @@ -63,8 +63,8 @@ public: } private: - bool isCode() const { - return getCOFFImportHeader()->getType() == COFF::IMPORT_CODE; + bool isData() const { + return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA; } }; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 9c72bd4023d8..42fdfe3e5a74 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -32,6 +32,7 @@ namespace llvm { namespace object { StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type); +StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type); // Subclasses of ELFFile may need this for template instantiation inline std::pair<unsigned char, unsigned char> diff --git a/include/llvm/Object/ModuleSummaryIndexObjectFile.h b/include/llvm/Object/ModuleSummaryIndexObjectFile.h deleted file mode 100644 index f733f861e2c0..000000000000 --- a/include/llvm/Object/ModuleSummaryIndexObjectFile.h +++ /dev/null @@ -1,112 +0,0 @@ -//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -===// -// -// 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 ModuleSummaryIndexObjectFile template class. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H -#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Object/Binary.h" -#include "llvm/Object/SymbolicFile.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/MemoryBuffer.h" -#include <memory> -#include <system_error> - -namespace llvm { - -class ModuleSummaryIndex; - -namespace object { - -class ObjectFile; - -/// This class is used to read just the module summary index related -/// sections out of the given object (which may contain a single module's -/// bitcode or be a combined index bitcode file). It builds a ModuleSummaryIndex -/// object. -class ModuleSummaryIndexObjectFile : public SymbolicFile { - std::unique_ptr<ModuleSummaryIndex> Index; - -public: - ModuleSummaryIndexObjectFile(MemoryBufferRef Object, - std::unique_ptr<ModuleSummaryIndex> I); - ~ModuleSummaryIndexObjectFile() override; - - // TODO: Walk through GlobalValueMap entries for symbols. - // However, currently these interfaces are not used by any consumers. - void moveSymbolNext(DataRefImpl &Symb) const override { - llvm_unreachable("not implemented"); - } - - std::error_code printSymbolName(raw_ostream &OS, - DataRefImpl Symb) const override { - llvm_unreachable("not implemented"); - return std::error_code(); - } - - uint32_t getSymbolFlags(DataRefImpl Symb) const override { - llvm_unreachable("not implemented"); - return 0; - } - - basic_symbol_iterator symbol_begin() const override { - llvm_unreachable("not implemented"); - return basic_symbol_iterator(BasicSymbolRef()); - } - basic_symbol_iterator symbol_end() const override { - llvm_unreachable("not implemented"); - return basic_symbol_iterator(BasicSymbolRef()); - } - - const ModuleSummaryIndex &getIndex() const { - return const_cast<ModuleSummaryIndexObjectFile *>(this)->getIndex(); - } - ModuleSummaryIndex &getIndex() { return *Index; } - std::unique_ptr<ModuleSummaryIndex> takeIndex(); - - static inline bool classof(const Binary *v) { - return v->isModuleSummaryIndex(); - } - - /// \brief Finds and returns bitcode embedded in the given object file, or an - /// error code if not found. - static ErrorOr<MemoryBufferRef> findBitcodeInObject(const ObjectFile &Obj); - - /// \brief Finds and returns bitcode in the given memory buffer (which may - /// be either a bitcode file or a native object file with embedded bitcode), - /// or an error code if not found. - static ErrorOr<MemoryBufferRef> - findBitcodeInMemBuffer(MemoryBufferRef Object); - - /// \brief Parse module summary index in the given memory buffer. - /// Return new ModuleSummaryIndexObjectFile instance containing parsed module - /// summary/index. - static Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>> - create(MemoryBufferRef Object); -}; - -} // end namespace object - -/// Parse the module summary index out of an IR file and return the module -/// summary index object if found, or nullptr if not. If Identifier is -/// non-empty, it is used as the module ID (module path) in the resulting -/// index. This can be used when the index is being read from a file -/// containing minimized bitcode just for the thin link. -Expected<std::unique_ptr<ModuleSummaryIndex>> -getModuleSummaryIndexForFile(StringRef Path, StringRef Identifier = ""); - -} // end namespace llvm - -#endif // LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H diff --git a/include/llvm/Support/AArch64TargetParser.def b/include/llvm/Support/AArch64TargetParser.def index 46d253bf0ec7..1700deadeaef 100644 --- a/include/llvm/Support/AArch64TargetParser.def +++ b/include/llvm/Support/AArch64TargetParser.def @@ -21,7 +21,7 @@ AARCH64_ARCH("invalid", AK_INVALID, nullptr, nullptr, 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_LSE)) + 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 | diff --git a/include/llvm/Support/BinaryStreamArray.h b/include/llvm/Support/BinaryStreamArray.h index 21b2474660f2..748a62be231e 100644 --- a/include/llvm/Support/BinaryStreamArray.h +++ b/include/llvm/Support/BinaryStreamArray.h @@ -42,10 +42,12 @@ namespace llvm { /// having to specify a second template argument to VarStreamArray (documented /// below). template <typename T> struct VarStreamArrayExtractor { + typedef void Context; + // Method intentionally deleted. You must provide an explicit specialization // with the following method implemented. - Error operator()(BinaryStreamRef Stream, uint32_t &Len, - T &Item) const = delete; + static Error extract(BinaryStreamRef Stream, uint32_t &Len, T &Item, + Context *Ctx) = delete; }; /// VarStreamArray represents an array of variable length records backed by a @@ -64,82 +66,87 @@ template <typename T> struct VarStreamArrayExtractor { /// If you do not specify an Extractor type, you are expected to specialize /// VarStreamArrayExtractor<T> for your ValueType. /// -/// By default an Extractor is default constructed in the class, but in some -/// cases you might find it useful for an Extractor to maintain state across -/// extractions. In this case you can provide your own Extractor through a -/// secondary constructor. The following examples show various ways of -/// creating a VarStreamArray. -/// -/// // Will use VarStreamArrayExtractor<MyType> as the extractor. -/// VarStreamArray<MyType> MyTypeArray; -/// -/// // Will use a default-constructed MyExtractor as the extractor. -/// VarStreamArray<MyType, MyExtractor> MyTypeArray2; -/// -/// // Will use the specific instance of MyExtractor provided. -/// // MyExtractor need not be default-constructible in this case. -/// MyExtractor E(SomeContext); -/// VarStreamArray<MyType, MyExtractor> MyTypeArray3(E); +/// The default extractor type is stateless, but by specializing +/// VarStreamArrayExtractor or defining your own custom extractor type and +/// adding the appropriate ContextType typedef to the class, you can pass a +/// context field during construction of the VarStreamArray that will be +/// passed to each call to extract. /// -template <typename ValueType, typename Extractor> class VarStreamArrayIterator; +template <typename ValueType, typename ExtractorType> +class VarStreamArrayIterator; template <typename ValueType, - typename Extractor = VarStreamArrayExtractor<ValueType>> - + typename ExtractorType = VarStreamArrayExtractor<ValueType>> class VarStreamArray { - friend class VarStreamArrayIterator<ValueType, Extractor>; - public: - typedef VarStreamArrayIterator<ValueType, Extractor> Iterator; + typedef typename ExtractorType::ContextType ContextType; + typedef VarStreamArrayIterator<ValueType, ExtractorType> Iterator; + friend Iterator; VarStreamArray() = default; - explicit VarStreamArray(const Extractor &E) : E(E) {} - explicit VarStreamArray(BinaryStreamRef Stream) : Stream(Stream) {} - VarStreamArray(BinaryStreamRef Stream, const Extractor &E) - : Stream(Stream), E(E) {} + explicit VarStreamArray(BinaryStreamRef Stream, + ContextType *Context = nullptr) + : Stream(Stream), Context(Context) {} - VarStreamArray(const VarStreamArray<ValueType, Extractor> &Other) - : Stream(Other.Stream), E(Other.E) {} + VarStreamArray(const VarStreamArray<ValueType, ExtractorType> &Other) + : Stream(Other.Stream), Context(Other.Context) {} Iterator begin(bool *HadError = nullptr) const { - return Iterator(*this, E, HadError); + if (empty()) + return end(); + + return Iterator(*this, Context, HadError); } - Iterator end() const { return Iterator(E); } + Iterator end() const { return Iterator(); } - const Extractor &getExtractor() const { return E; } + bool empty() const { return Stream.getLength() == 0; } + + /// \brief given an offset into the array's underlying stream, return an + /// iterator to the record at that offset. This is considered unsafe + /// 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, Context, Stream.drop_front(Offset), nullptr); + } BinaryStreamRef getUnderlyingStream() const { return Stream; } private: BinaryStreamRef Stream; - Extractor E; + ContextType *Context = nullptr; }; -template <typename ValueType, typename Extractor> +template <typename ValueType, typename ExtractorType> class VarStreamArrayIterator - : public iterator_facade_base<VarStreamArrayIterator<ValueType, Extractor>, - std::forward_iterator_tag, ValueType> { - typedef VarStreamArrayIterator<ValueType, Extractor> IterType; - typedef VarStreamArray<ValueType, Extractor> ArrayType; + : public iterator_facade_base< + VarStreamArrayIterator<ValueType, ExtractorType>, + std::forward_iterator_tag, ValueType> { + typedef typename ExtractorType::ContextType ContextType; + typedef VarStreamArrayIterator<ValueType, ExtractorType> IterType; + typedef VarStreamArray<ValueType, ExtractorType> ArrayType; public: - VarStreamArrayIterator(const ArrayType &Array, const Extractor &E, - bool *HadError = nullptr) - : IterRef(Array.Stream), Array(&Array), HadError(HadError), Extract(E) { + VarStreamArrayIterator(const ArrayType &Array, ContextType *Context, + BinaryStreamRef Stream, bool *HadError = nullptr) + : IterRef(Stream), Context(Context), Array(&Array), HadError(HadError) { if (IterRef.getLength() == 0) moveToEnd(); else { - auto EC = Extract(IterRef, ThisLen, ThisValue); + auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context); if (EC) { consumeError(std::move(EC)); markError(); } } } + + VarStreamArrayIterator(const ArrayType &Array, ContextType *Context, + bool *HadError = nullptr) + : VarStreamArrayIterator(Array, Context, Array.Stream, HadError) {} + VarStreamArrayIterator() = default; - explicit VarStreamArrayIterator(const Extractor &E) : Extract(E) {} ~VarStreamArrayIterator() = default; bool operator==(const IterType &R) const { @@ -178,7 +185,7 @@ public: moveToEnd(); } else { // There is some data after the current record. - auto EC = Extract(IterRef, ThisLen, ThisValue); + auto EC = ExtractorType::extract(IterRef, ThisLen, ThisValue, Context); if (EC) { consumeError(std::move(EC)); markError(); @@ -205,11 +212,11 @@ private: ValueType ThisValue; BinaryStreamRef IterRef; + ContextType *Context{nullptr}; const ArrayType *Array{nullptr}; uint32_t ThisLen{0}; bool HasError{false}; bool *HadError{nullptr}; - Extractor Extract; }; template <typename T> class FixedStreamArrayIterator; diff --git a/include/llvm/Support/BinaryStreamReader.h b/include/llvm/Support/BinaryStreamReader.h index d994fa0f49d0..f30d82d81b25 100644 --- a/include/llvm/Support/BinaryStreamReader.h +++ b/include/llvm/Support/BinaryStreamReader.h @@ -172,11 +172,13 @@ public: /// \returns a success error code if the data was successfully read, otherwise /// returns an appropriate error code. template <typename T, typename U> - Error readArray(VarStreamArray<T, U> &Array, uint32_t Size) { + Error + readArray(VarStreamArray<T, U> &Array, uint32_t Size, + typename VarStreamArray<T, U>::ContextType *Context = nullptr) { BinaryStreamRef S; if (auto EC = readStreamRef(S, Size)) return EC; - Array = VarStreamArray<T, U>(S, Array.getExtractor()); + Array = VarStreamArray<T, U>(S, Context); return Error::success(); } diff --git a/include/llvm/Support/BinaryStreamWriter.h b/include/llvm/Support/BinaryStreamWriter.h index 64f26b24543d..6734a797ccc4 100644 --- a/include/llvm/Support/BinaryStreamWriter.h +++ b/include/llvm/Support/BinaryStreamWriter.h @@ -30,6 +30,8 @@ namespace llvm { /// although no methods are overridable. class BinaryStreamWriter { public: + // FIXME: We should be able to slice and drop_front etc on Writers / Readers. + BinaryStreamWriter() = default; explicit BinaryStreamWriter(WritableBinaryStreamRef Stream); virtual ~BinaryStreamWriter() {} diff --git a/include/llvm/Support/CMakeLists.txt b/include/llvm/Support/CMakeLists.txt index b4b993705745..c58ccf216303 100644 --- a/include/llvm/Support/CMakeLists.txt +++ b/include/llvm/Support/CMakeLists.txt @@ -14,10 +14,15 @@ macro(find_first_existing_vc_file out_var path) execute_process(COMMAND ${git_executable} rev-parse --git-dir WORKING_DIRECTORY ${path}/cmake RESULT_VARIABLE git_result - OUTPUT_VARIABLE git_dir) + OUTPUT_VARIABLE git_dir + ERROR_QUIET) if(git_result EQUAL 0) string(STRIP "${git_dir}" git_dir) set(${out_var} "${git_dir}/logs/HEAD") + # some branchless cases (e.g. 'repo') may not yet have .git/logs/HEAD + if (NOT EXISTS "${git_dir}/logs/HEAD") + file(WRITE "${git_dir}/logs/HEAD" "") + endif() else() find_first_existing_file(${out_var} "${path}/.svn/wc.db" # SVN 1.7 diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h index aa9bb8938ad3..a8874a10d461 100644 --- a/include/llvm/Support/DynamicLibrary.h +++ b/include/llvm/Support/DynamicLibrary.h @@ -58,7 +58,7 @@ namespace sys { void *getAddressOfSymbol(const char *symbolName); /// This function permanently loads the dynamic library at the given path. - /// The library will only be unloaded when the program terminates. + /// The library will only be unloaded when llvm_shutdown() is called. /// This returns a valid DynamicLibrary instance on success and an invalid /// instance on failure (see isValid()). \p *errMsg will only be modified /// if the library fails to load. @@ -71,7 +71,8 @@ namespace sys { /// Registers an externally loaded library. The library will be unloaded /// when the program terminates. /// - /// It is safe to call this function multiple times for the same library. + /// It is safe to call this function multiple times for the same library, + /// though ownership is only taken if there was no error. /// /// \returns An empty \p DynamicLibrary if the library was already loaded. static DynamicLibrary addPermanentLibrary(void *handle, @@ -106,6 +107,8 @@ namespace sys { /// libraries. /// @brief Add searchable symbol/value pair. static void AddSymbol(StringRef symbolName, void *symbolValue); + + class HandleSet; }; } // End sys namespace diff --git a/include/llvm/Support/ELFRelocs/AArch64.def b/include/llvm/Support/ELFRelocs/AArch64.def index c21df07d2dbc..4afcd7d1f093 100644 --- a/include/llvm/Support/ELFRelocs/AArch64.def +++ b/include/llvm/Support/ELFRelocs/AArch64.def @@ -109,8 +109,8 @@ ELF_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 0x22f) ELF_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 0x230) ELF_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 0x231) ELF_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 0x232) -ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12_NC, 0x233) -ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12_NC, 0x234) +ELF_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 0x233) +ELF_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 0x234) ELF_RELOC(R_AARCH64_TLSDESC_OFF_G1, 0x235) ELF_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 0x236) ELF_RELOC(R_AARCH64_TLSDESC_LDR, 0x237) @@ -144,21 +144,28 @@ ELF_RELOC(R_AARCH64_P32_ADR_PREL_LO21, 0x00a) ELF_RELOC(R_AARCH64_P32_ADR_PREL_PG_HI21, 0x00b) ELF_RELOC(R_AARCH64_P32_ADD_ABS_LO12_NC, 0x00c) ELF_RELOC(R_AARCH64_P32_LDST8_ABS_LO12_NC, 0x00d) +ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC, 0x00e) +ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC, 0x00f) +ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC, 0x010) +ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC, 0x011) ELF_RELOC(R_AARCH64_P32_TSTBR14, 0x012) ELF_RELOC(R_AARCH64_P32_CONDBR19, 0x013) ELF_RELOC(R_AARCH64_P32_JUMP26, 0x014) ELF_RELOC(R_AARCH64_P32_CALL26, 0x015) -ELF_RELOC(R_AARCH64_P32_LDST16_ABS_LO12_NC, 0x00e) -ELF_RELOC(R_AARCH64_P32_LDST32_ABS_LO12_NC, 0x00f) -ELF_RELOC(R_AARCH64_P32_LDST64_ABS_LO12_NC, 0x010) ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0, 0x016) ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G0_NC, 0x017) ELF_RELOC(R_AARCH64_P32_MOVW_PREL_G1, 0x018) -ELF_RELOC(R_AARCH64_P32_LDST128_ABS_LO12_NC, 0x011) ELF_RELOC(R_AARCH64_P32_GOT_LD_PREL19, 0x019) ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a) -ELF_RELOC(R_AARCH64_P32_LD64_GOT_LO12_NC, 0x01b) +ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b) ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c) +ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21, 0x050) +ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21, 0x051) +ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC, 0x052) +ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PREL21, 0x053) +ELF_RELOC(R_AARCH64_P32_TLSLD_ADR_PAGE21, 0x054) +ELF_RELOC(R_AARCH64_P32_TLSLD_ADD_LO12_NC, 0x055) +ELF_RELOC(R_AARCH64_P32_TLSLD_LD_PREL19, 0x056) ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G1, 0x057) ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0, 0x058) ELF_RELOC(R_AARCH64_P32_TLSLD_MOVW_DTPREL_G0_NC, 0x059) @@ -173,6 +180,8 @@ ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12, 0x061) ELF_RELOC(R_AARCH64_P32_TLSLD_LDST32_DTPREL_LO12_NC, 0x062) ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12, 0x063) ELF_RELOC(R_AARCH64_P32_TLSLD_LDST64_DTPREL_LO12_NC, 0x064) +ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12, 0x065) +ELF_RELOC(R_AARCH64_P32_TLSLD_LDST128_DTPREL_LO12_NC,0x066) ELF_RELOC(R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21, 0x067) ELF_RELOC(R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC, 0x068) ELF_RELOC(R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19, 0x069) @@ -190,12 +199,20 @@ ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12, 0x074) ELF_RELOC(R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC, 0x075) ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12, 0x076) ELF_RELOC(R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC, 0x077) -ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21, 0x051) -ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12_NC, 0x07d) -ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12_NC, 0x034) +ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12, 0x078) +ELF_RELOC(R_AARCH64_P32_TLSLE_LDST128_TPREL_LO12_NC, 0x079) +ELF_RELOC(R_AARCH64_P32_TLSDESC_LD_PREL19, 0x07a) +ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PREL21, 0x07b) +ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21, 0x07c) +ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12, 0x07d) +ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12, 0x07e) ELF_RELOC(R_AARCH64_P32_TLSDESC_CALL, 0x07f) ELF_RELOC(R_AARCH64_P32_COPY, 0x0b4) ELF_RELOC(R_AARCH64_P32_GLOB_DAT, 0x0b5) ELF_RELOC(R_AARCH64_P32_JUMP_SLOT, 0x0b6) ELF_RELOC(R_AARCH64_P32_RELATIVE, 0x0b7) +ELF_RELOC(R_AARCH64_P32_TLS_DTPREL, 0x0b8) +ELF_RELOC(R_AARCH64_P32_TLS_DTPMOD, 0x0b9) +ELF_RELOC(R_AARCH64_P32_TLS_TPREL, 0x0ba) +ELF_RELOC(R_AARCH64_P32_TLSDESC, 0x0bb) ELF_RELOC(R_AARCH64_P32_IRELATIVE, 0x0bc) diff --git a/include/llvm/Support/KnownBits.h b/include/llvm/Support/KnownBits.h index 08d4dedd0ac8..292ea9e4b717 100644 --- a/include/llvm/Support/KnownBits.h +++ b/include/llvm/Support/KnownBits.h @@ -19,7 +19,7 @@ namespace llvm { -// For now this is a simple wrapper around two APInts. +// Struct for tracking the known zeros and ones of a value. struct KnownBits { APInt Zero; APInt One; @@ -36,6 +36,24 @@ struct KnownBits { "Zero and One should have the same width!"); return Zero.getBitWidth(); } + + /// Returns true if this value is known to be negative. + bool isNegative() const { return One.isSignBitSet(); } + + /// Returns true if this value is known to be non-negative. + bool isNonNegative() const { return Zero.isSignBitSet(); } + + /// Make this value negative. + void makeNegative() { + assert(!isNonNegative() && "Can't make a non-negative value negative"); + One.setSignBit(); + } + + /// Make this value negative. + void makeNonNegative() { + assert(!isNegative() && "Can't make a negative value non-negative"); + Zero.setSignBit(); + } }; } // end namespace llvm diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h index ff775f3b7b36..29640db69218 100644 --- a/include/llvm/Support/LEB128.h +++ b/include/llvm/Support/LEB128.h @@ -45,8 +45,7 @@ inline void encodeSLEB128(int64_t Value, raw_ostream &OS, /// Utility function to encode a SLEB128 value to a buffer. Returns /// the length in bytes of the encoded value. -inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, - unsigned Padding = 0) { +inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, unsigned Padding = 0) { uint8_t *orig_p = p; bool More; do { @@ -111,7 +110,6 @@ inline unsigned encodeULEB128(uint64_t Value, uint8_t *p, return (unsigned)(p - orig_p); } - /// Utility function to decode a ULEB128 value. inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *end = nullptr, @@ -119,19 +117,19 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr, const uint8_t *orig_p = p; uint64_t Value = 0; unsigned Shift = 0; - if(error) + if (error) *error = nullptr; do { - if(end && p == end){ - if(error) + if (end && p == end) { + if (error) *error = "malformed uleb128, extends past end"; if (n) *n = (unsigned)(p - orig_p); return 0; } uint64_t Slice = *p & 0x7f; - if(Shift >= 64 || Slice << Shift >> Shift != Slice){ - if(error) + if (Shift >= 64 || Slice << Shift >> Shift != Slice) { + if (error) *error = "uleb128 too big for uint64"; if (n) *n = (unsigned)(p - orig_p); @@ -154,15 +152,15 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr, unsigned Shift = 0; uint8_t Byte; do { - if(end && p == end){ - if(error) + if (end && p == end) { + if (error) *error = "malformed sleb128, extends past end"; if (n) *n = (unsigned)(p - orig_p); return 0; } Byte = *p++; - Value |= ((Byte & 0x7f) << Shift); + Value |= (int64_t(Byte & 0x7f) << Shift); Shift += 7; } while (Byte >= 128); // Sign extend negative numbers. @@ -173,13 +171,12 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr, return Value; } - /// Utility function to get the size of the ULEB128-encoded value. extern unsigned getULEB128Size(uint64_t Value); /// Utility function to get the size of the SLEB128-encoded value. extern unsigned getSLEB128Size(int64_t Value); -} // namespace llvm +} // namespace llvm -#endif // LLVM_SYSTEM_LEB128_H +#endif // LLVM_SYSTEM_LEB128_H diff --git a/include/llvm/Support/ScopedPrinter.h b/include/llvm/Support/ScopedPrinter.h index a2f2e0985431..1b6651932212 100644 --- a/include/llvm/Support/ScopedPrinter.h +++ b/include/llvm/Support/ScopedPrinter.h @@ -295,6 +295,11 @@ public: printBinaryImpl(Label, StringRef(), V, false); } + void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value, + uint32_t StartOffset) { + printBinaryImpl(Label, StringRef(), Value, true, StartOffset); + } + void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) { printBinaryImpl(Label, StringRef(), Value, true); } @@ -333,7 +338,7 @@ private: } void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value, - bool Block); + bool Block, uint32_t StartOffset = 0); raw_ostream &OS; int IndentLevel; diff --git a/include/llvm/Support/StringSaver.h b/include/llvm/Support/StringSaver.h index fcddd4cde5b6..e85b2895ce51 100644 --- a/include/llvm/Support/StringSaver.h +++ b/include/llvm/Support/StringSaver.h @@ -26,7 +26,7 @@ public: StringRef save(const char *S) { return save(StringRef(S)); } StringRef save(StringRef S); StringRef save(const Twine &S) { return save(StringRef(S.str())); } - StringRef save(std::string &S) { return save(StringRef(S)); } + StringRef save(const std::string &S) { return save(StringRef(S)); } }; } #endif diff --git a/include/llvm/Support/Wasm.h b/include/llvm/Support/Wasm.h index 8e6c418c8189..a48dfe10b3bb 100644 --- a/include/llvm/Support/Wasm.h +++ b/include/llvm/Support/Wasm.h @@ -24,6 +24,8 @@ namespace wasm { const char WasmMagic[] = {'\0', 'a', 's', 'm'}; // Wasm binary format version const uint32_t WasmVersion = 0x1; +// Wasm uses a 64k page size +const uint32_t WasmPageSize = 65536; struct WasmObjectHeader { StringRef Magic; @@ -106,7 +108,7 @@ struct WasmRelocation { uint32_t Type; // The type of the relocation. int32_t Index; // Index into function to global index space. uint64_t Offset; // Offset from the start of the section. - uint64_t Addend; // A value to add to the symbol. + int64_t Addend; // A value to add to the symbol. }; enum : unsigned { diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index b21689e0e134..d7fbca93f59b 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -530,6 +530,12 @@ class Predicate<string cond> { /// PredicateName - User-level name to use for the predicate. Mainly for use /// in diagnostics such as missing feature errors in the asm matcher. string PredicateName = ""; + + /// Setting this to '1' indicates that the predicate must be recomputed on + /// every function change. Most predicates can leave this at '0'. + /// + /// Ignored by SelectionDAG, it always recomputes the predicate on every use. + bit RecomputePerFunction = 0; } /// NoHonorSignDependentRounding - This predicate is true if support for diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 51f11e1a9a25..aa9230044b1f 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -69,6 +69,7 @@ class CCValAssign; class FastISel; class FunctionLoweringInfo; class IntrinsicInst; +struct KnownBits; class MachineBasicBlock; class MachineFunction; class MachineInstr; @@ -774,6 +775,74 @@ public: return (!isTypeLegal(VT) && getOperationAction(Op, VT) == Custom); } + /// Return true if lowering to a jump table is allowed. + bool areJTsAllowed(const Function *Fn) const { + if (Fn->getFnAttribute("no-jump-tables").getValueAsString() == "true") + return false; + + return isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || + isOperationLegalOrCustom(ISD::BRIND, MVT::Other); + } + + /// Check whether the range [Low,High] fits in a machine word. + bool rangeFitsInWord(const APInt &Low, const APInt &High, + const DataLayout &DL) const { + // FIXME: Using the pointer type doesn't seem ideal. + uint64_t BW = DL.getPointerSizeInBits(); + uint64_t Range = (High - Low).getLimitedValue(UINT64_MAX - 1) + 1; + return Range <= BW; + } + + /// Return true if lowering to a jump table is suitable for a set of case + /// clusters which may contain \p NumCases cases, \p Range range of values. + /// FIXME: This function check the maximum table size and density, but the + /// minimum size is not checked. It would be nice if the the minimum size is + /// also combined within this function. Currently, the minimum size check is + /// performed in findJumpTable() in SelectionDAGBuiler and + /// getEstimatedNumberOfCaseClusters() in BasicTTIImpl. + bool isSuitableForJumpTable(const SwitchInst *SI, uint64_t NumCases, + uint64_t Range) const { + const bool OptForSize = SI->getParent()->getParent()->optForSize(); + const unsigned MinDensity = getMinimumJumpTableDensity(OptForSize); + const unsigned MaxJumpTableSize = + OptForSize || getMaximumJumpTableSize() == 0 + ? UINT_MAX + : getMaximumJumpTableSize(); + // Check whether a range of clusters is dense enough for a jump table. + if (Range <= MaxJumpTableSize && + (NumCases * 100 >= Range * MinDensity)) { + return true; + } + return false; + } + + /// Return true if lowering to a bit test is suitable for a set of case + /// clusters which contains \p NumDests unique destinations, \p Low and + /// \p High as its lowest and highest case values, and expects \p NumCmps + /// case value comparisons. Check if the number of destinations, comparison + /// metric, and range are all suitable. + bool isSuitableForBitTests(unsigned NumDests, unsigned NumCmps, + const APInt &Low, const APInt &High, + const DataLayout &DL) const { + // FIXME: I don't think NumCmps is the correct metric: a single case and a + // range of cases both require only one branch to lower. Just looking at the + // number of clusters and destinations should be enough to decide whether to + // build bit tests. + + // To lower a range with bit tests, the range must fit the bitwidth of a + // machine word. + if (!rangeFitsInWord(Low, High, DL)) + return false; + + // Decide whether it's profitable to lower this range with bit tests. Each + // destination requires a bit test and branch, and there is an overall range + // check branch. For a small number of clusters, separate comparisons might + // be cheaper, and for many destinations, splitting the range might be + // better. + return (NumDests == 1 && NumCmps >= 3) || (NumDests == 2 && NumCmps >= 5) || + (NumDests == 3 && NumCmps >= 6); + } + /// Return true if the specified operation is illegal on this target or /// unlikely to be made legal with custom lowering. This is used to help guide /// high-level lowering decisions. @@ -1148,6 +1217,9 @@ public: /// Return lower limit for number of blocks in a jump table. unsigned getMinimumJumpTableEntries() const; + /// Return lower limit of the density in a jump table. + unsigned getMinimumJumpTableDensity(bool OptForSize) const; + /// Return upper limit for number of entries in a jump table. /// Zero if no limit. unsigned getMaximumJumpTableSize() const; @@ -2025,6 +2097,12 @@ public: return LibcallCallingConvs[Call]; } + /// Execute target specific actions to finalize target lowering. + /// This is used to set extra flags in MachineFrameInformation and freezing + /// the set of reserved registers. + /// The default implementation just freezes the set of reserved registers. + virtual void finalizeLowering(MachineFunction &MF) const; + private: const TargetMachine &TM; @@ -2442,7 +2520,7 @@ public: /// with TLO.New will be incorrect when this parameter is true and TLO.Old /// has multiple uses. bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask, - APInt &KnownZero, APInt &KnownOne, + KnownBits &Known, TargetLoweringOpt &TLO, unsigned Depth = 0, bool AssumeSingleUse = false) const; @@ -2456,8 +2534,7 @@ public: /// argument allows us to only collect the known bits that are shared by the /// requested vector elements. virtual void computeKnownBitsForTargetNode(const SDValue Op, - APInt &KnownZero, - APInt &KnownOne, + KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth = 0) const; @@ -2584,12 +2661,6 @@ public: return false; } - /// Return true if the MachineFunction contains a COPY which would imply - /// HasCopyImplyingStackAdjustment. - virtual bool hasCopyImplyingStackAdjustment(MachineFunction *MF) const { - return false; - } - /// Perform necessary initialization to handle a subset of CSRs explicitly /// via copies. This function is called at the beginning of instruction /// selection. diff --git a/include/llvm/Transforms/Scalar/NaryReassociate.h b/include/llvm/Transforms/Scalar/NaryReassociate.h index a74bb6cc4194..f35707eeb3f0 100644 --- a/include/llvm/Transforms/Scalar/NaryReassociate.h +++ b/include/llvm/Transforms/Scalar/NaryReassociate.h @@ -167,7 +167,7 @@ private: // foo(a + b); // if (p2) // bar(a + b); - DenseMap<const SCEV *, SmallVector<WeakVH, 2>> SeenExprs; + DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs; }; } // namespace llvm diff --git a/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h b/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h new file mode 100644 index 000000000000..d7282ac6a781 --- /dev/null +++ b/include/llvm/Transforms/Scalar/SimpleLoopUnswitch.h @@ -0,0 +1,53 @@ +//===- SimpleLoopUnswitch.h - Hoist loop-invariant control flow -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H +#define LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H + +#include "llvm/Analysis/LoopAnalysisManager.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" + +namespace llvm { + +/// This pass transforms loops that contain branches on loop-invariant +/// conditions to have multiple loops. For example, it turns the left into the +/// right code: +/// +/// for (...) if (lic) +/// A for (...) +/// if (lic) A; B; C +/// B else +/// C for (...) +/// A; C +/// +/// This can increase the size of the code exponentially (doubling it every time +/// a loop is unswitched) so we only unswitch if the resultant code will be +/// smaller than a threshold. +/// +/// This pass expects LICM to be run before it to hoist invariant conditions out +/// of the loop, to make the unswitching opportunity obvious. +/// +class SimpleLoopUnswitchPass : public PassInfoMixin<SimpleLoopUnswitchPass> { +public: + SimpleLoopUnswitchPass() = default; + + PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, LPMUpdater &U); +}; + +/// Create the legacy pass object for the simple loop unswitcher. +/// +/// See the documentaion for `SimpleLoopUnswitchPass` for details. +Pass *createSimpleLoopUnswitchLegacyPass(); + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_SIMPLELOOPUNSWITCH_H diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 337305a0a82c..0a8903a6ed7b 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -74,7 +74,7 @@ struct ClonedCodeInfo { /// All cloned call sites that have operand bundles attached are appended to /// this vector. This vector may contain nulls or undefs if some of the /// originally inserted callsites were DCE'ed after they were cloned. - std::vector<WeakVH> OperandBundleCallSites; + std::vector<WeakTrackingVH> OperandBundleCallSites; ClonedCodeInfo() = default; }; @@ -192,7 +192,7 @@ public: /// InlinedCalls - InlineFunction fills this in with callsites that were /// inlined from the callee. This is only filled in if CG is non-null. - SmallVector<WeakVH, 8> InlinedCalls; + SmallVector<WeakTrackingVH, 8> InlinedCalls; /// All of the new call sites inlined into the caller. /// diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 4933712fb8ad..b5a5f4c2704c 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -286,9 +286,6 @@ DbgDeclareInst *FindAllocaDbgDeclare(Value *V); /// Finds the llvm.dbg.value intrinsics describing a value. void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V); -/// Constants for \p replaceDbgDeclare and friends. -enum { NoDeref = false, WithDeref = true }; - /// Replaces llvm.dbg.declare instruction when the address it describes /// is replaced with a new value. If Deref is true, an additional DW_OP_deref is /// prepended to the expression. If Offset is non-zero, a constant displacement diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h index f5e843e2e8b5..e9793fe4b666 100644 --- a/include/llvm/Transforms/Utils/ModuleUtils.h +++ b/include/llvm/Transforms/Utils/ModuleUtils.h @@ -84,6 +84,17 @@ void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values); void filterDeadComdatFunctions( Module &M, SmallVectorImpl<Function *> &DeadComdatFunctions); +/// \brief Produce a unique identifier for this module by taking the MD5 sum of +/// the names of the module's strong external symbols. +/// +/// This identifier is normally guaranteed to be unique, or the program would +/// fail to link due to multiply defined symbols. +/// +/// If the module has no strong external symbols (such a module may still have a +/// semantic effect if it performs global initialization), we cannot produce a +/// unique identifier for this module, so we return the empty string. +std::string getUniqueModuleId(Module *M); + } // End llvm namespace #endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h index 6cdeeeb60a65..8d50aeb10d6e 100644 --- a/include/llvm/Transforms/Utils/SimplifyIndVar.h +++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -46,13 +46,13 @@ public: /// simplifyUsersOfIV - Simplify instructions that use this induction variable /// by using ScalarEvolution to analyze the IV's recurrence. bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, - LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead, + LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead, IVVisitor *V = nullptr); /// SimplifyLoopIVs - Simplify users of induction variables within this /// loop. This does not actually change or add IVs. bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, - LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead); + LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead); } // end namespace llvm diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 950ad92afcd7..e44dc437342d 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -23,7 +23,7 @@ namespace llvm { class Value; class Instruction; -typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy; +typedef ValueMap<const Value *, WeakTrackingVH> ValueToValueMapTy; /// This is a class that can be implemented by clients to remap types when /// cloning constants and instructions. diff --git a/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/include/llvm/Transforms/Vectorize/SLPVectorizer.h index d669a8e5b615..10338f7937e8 100644 --- a/include/llvm/Transforms/Vectorize/SLPVectorizer.h +++ b/include/llvm/Transforms/Vectorize/SLPVectorizer.h @@ -40,8 +40,8 @@ class BoUpSLP; struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> { typedef SmallVector<StoreInst *, 8> StoreList; typedef MapVector<Value *, StoreList> StoreListMap; - typedef SmallVector<WeakVH, 8> WeakVHList; - typedef MapVector<Value *, WeakVHList> WeakVHListMap; + typedef SmallVector<WeakTrackingVH, 8> WeakTrackingVHList; + typedef MapVector<Value *, WeakTrackingVHList> WeakTrackingVHListMap; ScalarEvolution *SE = nullptr; TargetTransformInfo *TTI = nullptr; @@ -111,7 +111,7 @@ private: StoreListMap Stores; /// The getelementptr instructions in a basic block organized by base pointer. - WeakVHListMap GEPs; + WeakTrackingVHListMap GEPs; }; } |