diff options
Diffstat (limited to 'include')
36 files changed, 416 insertions, 147 deletions
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 8d45b78320417..55f3e46c45eda 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -757,17 +757,17 @@ extern void thinlto_codegen_add_cross_referenced_symbol(thinlto_code_gen_t cg, * @ingroup LLVMCTLTO * * These entry points control the ThinLTO cache. The cache is intended to - * support incremental build, and thus needs to be persistent accross build. - * The client enabled the cache by supplying a path to an existing directory. + * support incremental builds, and thus needs to be persistent across builds. + * The client enables the cache by supplying a path to an existing directory. * The code generator will use this to store objects files that may be reused * during a subsequent build. * To avoid filling the disk space, a few knobs are provided: - * - The pruning interval limit the frequency at which the garbage collector - * will try to scan the cache directory to prune it from expired entries. - * Setting to -1 disable the pruning (default). + * - The pruning interval limits the frequency at which the garbage collector + * will try to scan the cache directory to prune expired entries. + * Setting to a negative number disables the pruning. * - The pruning expiration time indicates to the garbage collector how old an * entry needs to be to be removed. - * - Finally, the garbage collector can be instructed to prune the cache till + * - Finally, the garbage collector can be instructed to prune the cache until * the occupied space goes below a threshold. * @{ */ @@ -782,7 +782,7 @@ extern void thinlto_codegen_set_cache_dir(thinlto_code_gen_t cg, const char *cache_dir); /** - * Sets the cache pruning interval (in seconds). A negative value disable the + * Sets the cache pruning interval (in seconds). A negative value disables the * pruning. An unspecified default value will be applied, and a value of 0 will * be ignored. * diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 9de075dfd681a..362096b08e134 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -95,46 +95,81 @@ enum AliasResult { /// /// This is no access at all, a modification, a reference, or both /// a modification and a reference. These are specifically structured such that -/// they form a two bit matrix and bit-tests for 'mod' or 'ref' +/// they form a three bit matrix and bit-tests for 'mod' or 'ref' or 'must' /// work with any of the possible values. - enum class ModRefInfo { + /// Must is provided for completeness, but no routines will return only + /// Must today. See definition of Must below. + Must = 0, + /// The access may reference the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustRef = 1, + /// The access may modify the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustMod = 2, + /// The access may reference, modify or both the value stored in memory, + /// a mustAlias relation was found, and no mayAlias or partialAlias found. + MustModRef = MustRef | MustMod, /// The access neither references nor modifies the value stored in memory. - NoModRef = 0, + NoModRef = 4, /// The access may reference the value stored in memory. - Ref = 1, + Ref = NoModRef | MustRef, /// The access may modify the value stored in memory. - Mod = 2, + Mod = NoModRef | MustMod, /// The access may reference and may modify the value stored in memory. ModRef = Ref | Mod, + + /// About Must: + /// Must is set in a best effort manner. + /// We usually do not try our best to infer Must, instead it is merely + /// another piece of "free" information that is presented when available. + /// Must set means there was certainly a MustAlias found. For calls, + /// where multiple arguments are checked (argmemonly), this translates to + /// only MustAlias or NoAlias was found. + /// Must is not set for RAR accesses, even if the two locations must + /// alias. The reason is that two read accesses translate to an early return + /// of NoModRef. An additional alias check to set Must may be + /// expensive. Other cases may also not set Must(e.g. callCapturesBefore). + /// We refer to Must being *set* when the most significant bit is *cleared*. + /// Conversely we *clear* Must information by *setting* the Must bit to 1. }; LLVM_NODISCARD inline bool isNoModRef(const ModRefInfo MRI) { - return MRI == ModRefInfo::NoModRef; + return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef)) == + static_cast<int>(ModRefInfo::Must); } LLVM_NODISCARD inline bool isModOrRefSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::ModRef); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef); } LLVM_NODISCARD inline bool isModAndRefSet(const ModRefInfo MRI) { - return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::ModRef)) == - static_cast<int>(ModRefInfo::ModRef); + return (static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustModRef)) == + static_cast<int>(ModRefInfo::MustModRef); } LLVM_NODISCARD inline bool isModSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustMod); } LLVM_NODISCARD inline bool isRefSet(const ModRefInfo MRI) { - return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref); + return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::MustRef); +} +LLVM_NODISCARD inline bool isMustSet(const ModRefInfo MRI) { + return !(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::NoModRef)); } LLVM_NODISCARD inline ModRefInfo setMod(const ModRefInfo MRI) { - return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Mod)); + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::MustMod)); } LLVM_NODISCARD inline ModRefInfo setRef(const ModRefInfo MRI) { - return ModRefInfo(static_cast<int>(MRI) | static_cast<int>(ModRefInfo::Ref)); + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::MustRef)); +} +LLVM_NODISCARD inline ModRefInfo setMust(const ModRefInfo MRI) { + return ModRefInfo(static_cast<int>(MRI) & + static_cast<int>(ModRefInfo::MustModRef)); } LLVM_NODISCARD inline ModRefInfo setModAndRef(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) | - static_cast<int>(ModRefInfo::ModRef)); + static_cast<int>(ModRefInfo::MustModRef)); } LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref)); @@ -142,6 +177,10 @@ LLVM_NODISCARD inline ModRefInfo clearMod(const ModRefInfo MRI) { LLVM_NODISCARD inline ModRefInfo clearRef(const ModRefInfo MRI) { return ModRefInfo(static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod)); } +LLVM_NODISCARD inline ModRefInfo clearMust(const ModRefInfo MRI) { + return ModRefInfo(static_cast<int>(MRI) | + static_cast<int>(ModRefInfo::NoModRef)); +} LLVM_NODISCARD inline ModRefInfo unionModRef(const ModRefInfo MRI1, const ModRefInfo MRI2) { return ModRefInfo(static_cast<int>(MRI1) | static_cast<int>(MRI2)); @@ -160,11 +199,11 @@ enum FunctionModRefLocation { /// Base case is no access to memory. FMRL_Nowhere = 0, /// Access to memory via argument pointers. - FMRL_ArgumentPointees = 4, + FMRL_ArgumentPointees = 8, /// Memory that is inaccessible via LLVM IR. - FMRL_InaccessibleMem = 8, + FMRL_InaccessibleMem = 16, /// Access to any memory. - FMRL_Anywhere = 16 | FMRL_InaccessibleMem | FMRL_ArgumentPointees + FMRL_Anywhere = 32 | FMRL_InaccessibleMem | FMRL_ArgumentPointees }; /// Summary of how a function affects memory in the program. @@ -344,7 +383,7 @@ public: /// result's bits are set to indicate the allowed aliasing ModRef kinds. Note /// that these bits do not necessarily account for the overall behavior of /// the function, but rather only provide additional per-argument - /// information. + /// information. This never sets ModRefInfo::Must. ModRefInfo getArgModRefInfo(ImmutableCallSite CS, unsigned ArgIdx); /// Return the behavior of the given call site. @@ -624,6 +663,8 @@ public: /// or reads the specified memory location \p MemLoc before instruction \p I /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up /// instruction ordering queries inside the BasicBlock containing \p I. + /// Early exits in callCapturesBefore may lead to ModRefInfo::Must not being + /// set. ModRefInfo callCapturesBefore(const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT, OrderedBasicBlock *OBB = nullptr); diff --git a/include/llvm/Analysis/AliasAnalysisEvaluator.h b/include/llvm/Analysis/AliasAnalysisEvaluator.h index 214574852655a..cd2f631a01f42 100644 --- a/include/llvm/Analysis/AliasAnalysisEvaluator.h +++ b/include/llvm/Analysis/AliasAnalysisEvaluator.h @@ -35,19 +35,23 @@ class AAEvaluator : public PassInfoMixin<AAEvaluator> { int64_t FunctionCount; int64_t NoAliasCount, MayAliasCount, PartialAliasCount, MustAliasCount; int64_t NoModRefCount, ModCount, RefCount, ModRefCount; + int64_t MustCount, MustRefCount, MustModCount, MustModRefCount; public: AAEvaluator() : FunctionCount(), NoAliasCount(), MayAliasCount(), PartialAliasCount(), MustAliasCount(), NoModRefCount(), ModCount(), RefCount(), - ModRefCount() {} + ModRefCount(), MustCount(), MustRefCount(), MustModCount(), + MustModRefCount() {} AAEvaluator(AAEvaluator &&Arg) : FunctionCount(Arg.FunctionCount), NoAliasCount(Arg.NoAliasCount), MayAliasCount(Arg.MayAliasCount), PartialAliasCount(Arg.PartialAliasCount), MustAliasCount(Arg.MustAliasCount), NoModRefCount(Arg.NoModRefCount), ModCount(Arg.ModCount), RefCount(Arg.RefCount), - ModRefCount(Arg.ModRefCount) { + ModRefCount(Arg.ModRefCount), MustCount(Arg.MustCount), + MustRefCount(Arg.MustRefCount), MustModCount(Arg.MustModCount), + MustModRefCount(Arg.MustModRefCount) { Arg.FunctionCount = 0; } ~AAEvaluator(); diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h index 54f151ef82e28..28154c873b709 100644 --- a/include/llvm/Analysis/LoopAccessAnalysis.h +++ b/include/llvm/Analysis/LoopAccessAnalysis.h @@ -667,21 +667,6 @@ int64_t getPtrStride(PredicatedScalarEvolution &PSE, Value *Ptr, const Loop *Lp, const ValueToValueMap &StridesMap = ValueToValueMap(), bool Assume = false, bool ShouldCheckWrap = true); -/// \brief Attempt to sort the 'loads' in \p VL and return the sorted values in -/// \p Sorted. -/// -/// Returns 'false' if sorting is not legal or feasible, otherwise returns -/// 'true'. If \p Mask is not null, it also returns the \p Mask which is the -/// shuffle mask for actual memory access order. -/// -/// For example, for a given VL of memory accesses in program order, a[i+2], -/// a[i+0], a[i+1] and a[i+3], this function will sort the VL and save the -/// sorted value in 'Sorted' as a[i+0], a[i+1], a[i+2], a[i+3] and saves the -/// mask for actual memory accesses in program order in 'Mask' as <2,0,1,3> -bool sortLoadAccesses(ArrayRef<Value *> VL, const DataLayout &DL, - ScalarEvolution &SE, SmallVectorImpl<Value *> &Sorted, - SmallVectorImpl<unsigned> *Mask = nullptr); - /// \brief Returns true if the memory operations \p A and \p B are consecutive. /// This is a simple API that does not depend on the analysis pass. bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index c2974525a6ff8..391a333594e98 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -407,6 +407,12 @@ public: void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl<NonLocalDepResult> &Result); + /// Perform a dependency query specifically for QueryInst's access to Loc. + /// The other comments for getNonLocalPointerDependency apply here as well. + void getNonLocalPointerDependencyFrom(Instruction *QueryInst, + const MemoryLocation &Loc, bool isLoad, + SmallVectorImpl<NonLocalDepResult> &Result); + /// Removes an instruction from the dependence analysis, updating the /// dependence of instructions that previously depended on it. void removeInstruction(Instruction *InstToRemove); diff --git a/include/llvm/Analysis/ProfileSummaryInfo.h b/include/llvm/Analysis/ProfileSummaryInfo.h index bd7b00374821d..293033458429c 100644 --- a/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/include/llvm/Analysis/ProfileSummaryInfo.h @@ -92,12 +92,12 @@ public: bool hasHugeWorkingSetSize(); /// \brief Returns true if \p F has hot function entry. bool isFunctionEntryHot(const Function *F); - /// Returns true if \p F has hot function entry or hot call edge. - bool isFunctionHotInCallGraph(const Function *F); + /// Returns true if \p F contains hot code. + bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI); /// \brief Returns true if \p F has cold function entry. bool isFunctionEntryCold(const Function *F); - /// Returns true if \p F has cold function entry or cold call edge. - bool isFunctionColdInCallGraph(const Function *F); + /// Returns true if \p F contains only cold code. + bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI); /// \brief Returns true if \p F is a hot function. bool isHotCount(uint64_t C); /// \brief Returns true if count \p C is considered cold. diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 4578e0da8ab21..3df04e98bd241 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -47,7 +47,7 @@ namespace llvm { ScalarEvolution &SE; const DataLayout &DL; - // New instructions receive a name to identifies them with the current pass. + // New instructions receive a name to identify them with the current pass. const char* IVName; // InsertedExpressions caches Values for reuse, so must track RAUW. diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h index c20f20cfbe4d1..cecd8958e9d92 100644 --- a/include/llvm/Analysis/TargetTransformInfo.h +++ b/include/llvm/Analysis/TargetTransformInfo.h @@ -646,6 +646,9 @@ public: /// \brief Additional properties of an operand's values. enum OperandValueProperties { OP_None = 0, OP_PowerOf2 = 1 }; + /// \return True if target can execute instructions out of order. + bool isOutOfOrder() const; + /// \return The number of scalar or vector registers that the target has. /// If 'Vectors' is true, it returns the number of vector registers. If it is /// set to false, it returns the number of scalar registers. @@ -1018,6 +1021,7 @@ public: Type *Ty) = 0; virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, Type *Ty) = 0; + virtual bool isOutOfOrder() const = 0; virtual unsigned getNumberOfRegisters(bool Vector) = 0; virtual unsigned getRegisterBitWidth(bool Vector) const = 0; virtual unsigned getMinVectorRegisterBitWidth() = 0; @@ -1295,6 +1299,9 @@ public: Type *Ty) override { return Impl.getIntImmCost(IID, Idx, Imm, Ty); } + bool isOutOfOrder() const override { + return Impl.isOutOfOrder(); + } unsigned getNumberOfRegisters(bool Vector) override { return Impl.getNumberOfRegisters(Vector); } diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h index 4c37402278efe..3625675d53ded 100644 --- a/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -337,6 +337,8 @@ public: return TTI::TCC_Free; } + bool isOutOfOrder() const { return false; } + unsigned getNumberOfRegisters(bool Vector) { return 8; } unsigned getRegisterBitWidth(bool Vector) const { return 32; } diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 506cd0393e9ac..57a0b441821b9 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -208,7 +208,7 @@ const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; #define WASM_RELOC(name, value) name = value, enum : unsigned { -#include "WasmRelocs/WebAssembly.def" +#include "WasmRelocs.def" }; #undef WASM_RELOC diff --git a/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def b/include/llvm/BinaryFormat/WasmRelocs.def index d6f0e42b33bf2..d6f0e42b33bf2 100644 --- a/include/llvm/BinaryFormat/WasmRelocs/WebAssembly.def +++ b/include/llvm/BinaryFormat/WasmRelocs.def diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h index bb5e7f9e8e30f..f1f9275b0786c 100644 --- a/include/llvm/CodeGen/BasicTTIImpl.h +++ b/include/llvm/CodeGen/BasicTTIImpl.h @@ -302,9 +302,13 @@ public: } unsigned getFPOpCost(Type *Ty) { - // By default, FP instructions are no more expensive since they are - // implemented in HW. Target specific TTI can override this. - return TargetTransformInfo::TCC_Basic; + // Check whether FADD is available, as a proxy for floating-point in + // general. + const TargetLoweringBase *TLI = getTLI(); + EVT VT = TLI->getValueType(DL, Ty); + if (TLI->isOperationLegalOrCustomOrPromote(ISD::FADD, VT)) + return TargetTransformInfo::TCC_Basic; + return TargetTransformInfo::TCC_Expensive; } unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) { @@ -398,6 +402,10 @@ public: return BaseT::getInstructionLatency(I); } + bool isOutOfOrder() const { + return getST()->getSchedModel().isOutOfOrder(); + } + /// @} /// \name Vector TTI Implementations diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index e599a1b179ece..4264a866b6c01 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -282,10 +282,6 @@ enum { /// Provides the logic to select generic machine instructions. class InstructionSelector { public: - using I64ImmediatePredicateFn = bool (*)(int64_t); - using APIntImmediatePredicateFn = bool (*)(const APInt &); - using APFloatImmediatePredicateFn = bool (*)(const APFloat &); - virtual ~InstructionSelector() = default; /// Select the (possibly generic) instruction \p I to only use target-specific @@ -319,9 +315,6 @@ public: struct MatcherInfoTy { const LLT *TypeObjects; const PredicateBitset *FeatureBitsets; - const I64ImmediatePredicateFn *I64ImmPredicateFns; - const APIntImmediatePredicateFn *APIntImmPredicateFns; - const APFloatImmediatePredicateFn *APFloatImmPredicateFns; const ComplexMatcherMemFn *ComplexPredicates; }; @@ -340,6 +333,16 @@ protected: const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures, CodeGenCoverage &CoverageInfo) const; + virtual bool testImmPredicate_I64(unsigned, int64_t) const { + llvm_unreachable("Subclasses must override this to use tablegen"); + } + virtual bool testImmPredicate_APInt(unsigned, const APInt &) const { + llvm_unreachable("Subclasses must override this to use tablegen"); + } + virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const { + llvm_unreachable("Subclasses must override this to use tablegen"); + } + /// Constrain a register operand of an instruction \p I to a specified /// register class. This could involve inserting COPYs before (for uses) or /// after (for defs) and may replace the operand of \p I. diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h index ac2c055ab1452..bf834cf8f5e34 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -181,7 +181,7 @@ bool InstructionSelector::executeMatchTable( else llvm_unreachable("Expected Imm or CImm operand"); - if (!MatcherInfo.I64ImmPredicateFns[Predicate](Value)) + if (!testImmPredicate_I64(Predicate, Value)) if (handleReject() == RejectAndGiveUp) return false; break; @@ -202,7 +202,7 @@ bool InstructionSelector::executeMatchTable( else llvm_unreachable("Expected Imm or CImm operand"); - if (!MatcherInfo.APIntImmPredicateFns[Predicate](Value)) + if (!testImmPredicate_APInt(Predicate, Value)) if (handleReject() == RejectAndGiveUp) return false; break; @@ -221,7 +221,7 @@ bool InstructionSelector::executeMatchTable( assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate"); APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF(); - if (!MatcherInfo.APFloatImmPredicateFns[Predicate](Value)) + if (!testImmPredicate_APFloat(Predicate, Value)) if (handleReject() == RejectAndGiveUp) return false; break; diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStacks.h index c90ae7b184f4e..44ed785f7b53d 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStacks.h @@ -1,4 +1,4 @@ -//===- LiveStackAnalysis.h - Live Stack Slot Analysis -----------*- C++ -*-===// +//===- LiveStacks.h - Live Stack Slot Analysis ------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_LIVESTACKANALYSIS_H -#define LLVM_CODEGEN_LIVESTACKANALYSIS_H +#ifndef LLVM_CODEGEN_LIVESTACKS_H +#define LLVM_CODEGEN_LIVESTACKS_H #include "llvm/CodeGen/LiveInterval.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -100,4 +100,4 @@ public: } // end namespace llvm -#endif // LLVM_CODEGEN_LIVESTACK_ANALYSIS_H +#endif diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index ccf0917ed0851..4be7942c2c64b 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -29,6 +29,7 @@ class GlobalValue; class MachineBasicBlock; class MachineInstr; class MachineRegisterInfo; +class MCCFIInstruction; class MDNode; class ModuleSlotTracker; class TargetMachine; @@ -250,6 +251,12 @@ public: static void printStackObjectReference(raw_ostream &OS, unsigned FrameIndex, bool IsFixed, StringRef Name); + /// Print the offset with explicit +/- signs. + static void printOperandOffset(raw_ostream &OS, int64_t Offset); + + /// Print an IRSlotNumber. + static void printIRSlotNumber(raw_ostream &OS, int Slot); + /// Print the MachineOperand to \p os. /// Providing a valid \p TRI and \p IntrinsicInfo results in a more /// target-specific printing. If \p TRI and \p IntrinsicInfo are null, the diff --git a/include/llvm/CodeGen/RuntimeLibcalls.def b/include/llvm/CodeGen/RuntimeLibcalls.def index e042ae982e86c..7695e9d782ef4 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.def +++ b/include/llvm/CodeGen/RuntimeLibcalls.def @@ -165,6 +165,8 @@ HANDLE_LIBCALL(SINCOS_F64, nullptr) HANDLE_LIBCALL(SINCOS_F80, nullptr) HANDLE_LIBCALL(SINCOS_F128, nullptr) HANDLE_LIBCALL(SINCOS_PPCF128, nullptr) +HANDLE_LIBCALL(SINCOS_STRET_F32, nullptr) +HANDLE_LIBCALL(SINCOS_STRET_F64, nullptr) HANDLE_LIBCALL(POW_F32, "powf") HANDLE_LIBCALL(POW_F64, "pow") HANDLE_LIBCALL(POW_F80, "powl") @@ -334,6 +336,7 @@ HANDLE_LIBCALL(O_PPCF128, "__gcc_qunord") HANDLE_LIBCALL(MEMCPY, "memcpy") HANDLE_LIBCALL(MEMMOVE, "memmove") HANDLE_LIBCALL(MEMSET, "memset") +HANDLE_LIBCALL(BZERO, nullptr) // Element-wise unordered-atomic memory of different sizes HANDLE_LIBCALL(MEMCPY_ELEMENT_UNORDERED_ATOMIC_1, "__llvm_memcpy_element_unordered_atomic_1") diff --git a/include/llvm/CodeGen/SDNodeProperties.td b/include/llvm/CodeGen/SDNodeProperties.td new file mode 100644 index 0000000000000..83bbab2fdc8de --- /dev/null +++ b/include/llvm/CodeGen/SDNodeProperties.td @@ -0,0 +1,34 @@ +//===- SDNodeProperties.td - Common code for DAG isels ---*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +class SDNodeProperty; + +// Selection DAG Pattern Operations +class SDPatternOperator { + list<SDNodeProperty> Properties = []; +} + +//===----------------------------------------------------------------------===// +// Selection DAG Node Properties. +// +// Note: These are hard coded into tblgen. +// +def SDNPCommutative : SDNodeProperty; // X op Y == Y op X +def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) +def SDNPHasChain : SDNodeProperty; // R/W chain operand and result +def SDNPOutGlue : SDNodeProperty; // Write a flag result +def SDNPInGlue : SDNodeProperty; // Read a flag operand +def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand +def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. +def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. +def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. +def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand +def SDNPVariadic : SDNodeProperty; // Node has variable arguments. +def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match +def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 7de2e766d521a..522c2f1b2cb22 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -189,8 +189,8 @@ public: inline bool isUndef() const; inline unsigned getMachineOpcode() const; inline const DebugLoc &getDebugLoc() const; - inline void dump() const; - inline void dumpr() const; + inline void dump(const SelectionDAG *G = nullptr) const; + inline void dumpr(const SelectionDAG *G = nullptr) const; /// Return true if this operand (which must be a chain) reaches the /// specified operand without crossing any side-effecting instructions. @@ -1089,12 +1089,12 @@ inline const DebugLoc &SDValue::getDebugLoc() const { return Node->getDebugLoc(); } -inline void SDValue::dump() const { - return Node->dump(); +inline void SDValue::dump(const SelectionDAG *G) const { + return Node->dump(G); } -inline void SDValue::dumpr() const { - return Node->dumpr(); +inline void SDValue::dumpr(const SelectionDAG *G) const { + return Node->dumpr(G); } // Define inline functions from the SDUse class. diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h index 0fa19d09e776a..380e3b19dc80f 100644 --- a/include/llvm/CodeGen/TargetLowering.h +++ b/include/llvm/CodeGen/TargetLowering.h @@ -824,8 +824,8 @@ public: /// 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 { + virtual 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 = @@ -1276,7 +1276,7 @@ public: } /// Return lower limit for number of blocks in a jump table. - unsigned getMinimumJumpTableEntries() const; + virtual unsigned getMinimumJumpTableEntries() const; /// Return lower limit of the density in a jump table. unsigned getMinimumJumpTableDensity(bool OptForSize) const; @@ -2429,7 +2429,7 @@ private: PromoteToType; /// Stores the name each libcall. - const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL]; + const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL + 1]; /// The ISD::CondCode that should be used to test the result of each of the /// comparison libcall against zero. @@ -2438,6 +2438,9 @@ private: /// Stores the CallingConv that should be used for each libcall. CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL]; + /// Set default libcall names and calling conventions. + void InitLibcalls(const Triple &TT); + protected: /// Return true if the extension represented by \p I is free. /// \pre \p I is a sign, zero, or fp extension and diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index e9178e03fa8a2..3cec58383f874 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -165,6 +165,29 @@ struct BaseAddress { uint64_t SectionIndex; }; +/// Represents a unit's contribution to the string offsets table. +struct StrOffsetsContributionDescriptor { + uint64_t Base = 0; + uint64_t Size = 0; + /// Format and version. + DWARFFormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32}; + + StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size, + uint8_t Version, dwarf::DwarfFormat Format) + : Base(Base), Size(Size), FormParams({Version, 0, Format}) {} + + uint8_t getVersion() const { return FormParams.Version; } + dwarf::DwarfFormat getFormat() const { return FormParams.Format; } + uint8_t getDwarfOffsetByteSize() const { + return FormParams.getDwarfOffsetByteSize(); + } + /// Determine whether a contribution to the string offsets table is + /// consistent with the relevant section size and that its length is + /// a multiple of the size of one of its entries. + Optional<StrOffsetsContributionDescriptor> + validateContributionSize(DWARFDataExtractor &DA); +}; + class DWARFUnit { DWARFContext &Context; /// Section containing this DWARFUnit. @@ -176,7 +199,6 @@ class DWARFUnit { const DWARFSection &LineSection; StringRef StringSection; const DWARFSection &StringOffsetSection; - uint64_t StringOffsetSectionBase = 0; const DWARFSection *AddrOffsetSection; uint32_t AddrOffsetSectionBase = 0; bool isLittleEndian; @@ -185,6 +207,9 @@ class DWARFUnit { // Version, address size, and DWARF format. DWARFFormParams FormParams; + /// Start, length, and DWARF format of the unit's contribution to the string + /// offsets table (DWARF v5). + Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution; uint32_t Offset; uint32_t Length; @@ -195,10 +220,40 @@ class DWARFUnit { /// The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; - /// Map from range's start address to end address and corresponding DIE. - /// IntervalMap does not support range removal, as a result, we use the - /// std::map::upper_bound for address range lookup. - std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap; + /// The vector of inlined subroutine DIEs that we can map directly to from + /// their subprogram below. + std::vector<DWARFDie> InlinedSubroutineDIEs; + + /// A type representing a subprogram DIE and a map (built using a sorted + /// vector) into that subprogram's inlined subroutine DIEs. + struct SubprogramDIEAddrInfo { + DWARFDie SubprogramDIE; + + uint64_t SubprogramBasePC; + + /// A vector sorted to allow mapping from a relative PC to the inlined + /// subroutine DIE with the most specific address range covering that PC. + /// + /// The PCs are relative to the `SubprogramBasePC`. + /// + /// The vector is sorted in ascending order of the first int which + /// represents the relative PC for an interval in the map. The second int + /// represents the index into the `InlinedSubroutineDIEs` vector of the DIE + /// that interval maps to. An index of '-1` indicates an empty mapping. The + /// interval covered is from the `.first` relative PC to the next entry's + /// `.first` relative PC. + std::vector<std::pair<uint32_t, int32_t>> InlinedSubroutineDIEAddrMap; + }; + + /// Vector of the subprogram DIEs and their subroutine address maps. + std::vector<SubprogramDIEAddrInfo> SubprogramDIEAddrInfos; + + /// A vector sorted to allow mapping from a PC to the subprogram DIE (and + /// associated addr map) index. Subprograms with overlapping PC ranges aren't + /// supported here. Nothing will crash, but the mapping may be inaccurate. + /// This vector may also contain "empty" ranges marked by an address with + /// a DIE index of '-1'. + std::vector<std::pair<uint64_t, int64_t>> SubprogramDIEAddrMap; using die_iterator_range = iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>; @@ -219,6 +274,21 @@ protected: /// Size in bytes of the unit header. virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; } + /// Find the unit's contribution to the string offsets table and determine its + /// length and form. The given offset is expected to be derived from the unit + /// DIE's DW_AT_str_offsets_base attribute. + Optional<StrOffsetsContributionDescriptor> + determineStringOffsetsTableContribution(DWARFDataExtractor &DA, + uint64_t Offset); + + /// Find the unit's contribution to the string offsets table and determine its + /// length and form. The given offset is expected to be 0 in a dwo file or, + /// in a dwp file, the start of the unit's contribution to the string offsets + /// table section (as determined by the index table). + Optional<StrOffsetsContributionDescriptor> + determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA, + uint64_t Offset); + public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, @@ -242,9 +312,6 @@ public: AddrOffsetSectionBase = Base; } - /// Recursively update address to Die map. - void updateAddressDieMap(DWARFDie Die); - void setRangesSection(const DWARFSection *RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; @@ -272,6 +339,10 @@ public: uint32_t getNextUnitOffset() const { return Offset + Length + 4; } uint32_t getLength() const { return Length; } + const Optional<StrOffsetsContributionDescriptor> & + getStringOffsetsTableContribution() const { + return StringOffsetsTableContribution; + } const DWARFFormParams &getFormParams() const { return FormParams; } uint16_t getVersion() const { return FormParams.Version; } dwarf::DwarfFormat getFormat() const { return FormParams.Format; } @@ -281,6 +352,16 @@ public: return FormParams.getDwarfOffsetByteSize(); } + uint8_t getDwarfStringOffsetsByteSize() const { + assert(StringOffsetsTableContribution); + return StringOffsetsTableContribution->getDwarfOffsetByteSize(); + } + + uint64_t getStringOffsetsBase() const { + assert(StringOffsetsTableContribution); + return StringOffsetsTableContribution->Base; + } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const; uint8_t getUnitType() const { return UnitType; } @@ -426,6 +507,9 @@ private: /// parseDWO - Parses .dwo file for current compile unit. Returns true if /// it was actually constructed. bool parseDWO(); + + void buildSubprogramDIEAddrMap(); + void buildInlinedSubroutineDIEAddrMap(SubprogramDIEAddrInfo &SPInfo); }; } // end namespace llvm diff --git a/include/llvm/FuzzMutate/IRMutator.h b/include/llvm/FuzzMutate/IRMutator.h index 65ab871db0eff..9aa9d6d6a4bc2 100644 --- a/include/llvm/FuzzMutate/IRMutator.h +++ b/include/llvm/FuzzMutate/IRMutator.h @@ -16,6 +16,7 @@ #ifndef LLVM_FUZZMUTATE_IRMUTATOR_H #define LLVM_FUZZMUTATE_IRMUTATOR_H +#include "llvm/ADT/Optional.h" #include "llvm/FuzzMutate/OpDescriptor.h" #include "llvm/Support/ErrorHandling.h" @@ -74,7 +75,8 @@ public: class InjectorIRStrategy : public IRMutationStrategy { std::vector<fuzzerop::OpDescriptor> Operations; - fuzzerop::OpDescriptor chooseOperation(Value *Src, RandomIRBuilder &IB); + Optional<fuzzerop::OpDescriptor> chooseOperation(Value *Src, + RandomIRBuilder &IB); public: InjectorIRStrategy(std::vector<fuzzerop::OpDescriptor> &&Operations) diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index e811ae5e215a3..79c56abe1c377 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -248,6 +248,12 @@ public: /// pgo data. Optional<uint64_t> getEntryCount() const; + /// Return true if the function is annotated with profile data. + /// + /// Presence of entry counts from a profile run implies the function has + /// profile annotations. + bool hasProfileData() const { return getEntryCount().hasValue(); } + /// Returns the set of GUIDs that needs to be imported to the function for /// sample PGO, to enable the same inlines as the profiled optimized binary. DenseSet<GlobalValue::GUID> getImportGUIDs() const; diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 07de0568cab08..a2a1f26292cea 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// include "llvm/CodeGen/ValueTypes.td" +include "llvm/CodeGen/SDNodeProperties.td" //===----------------------------------------------------------------------===// // Properties we keep track of for intrinsics. @@ -264,16 +265,17 @@ def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here // intrinsic. // * Properties can be set to describe the behavior of the intrinsic. // -class SDPatternOperator; class Intrinsic<list<LLVMType> ret_types, list<LLVMType> param_types = [], - list<IntrinsicProperty> properties = [], - string name = ""> : SDPatternOperator { + list<IntrinsicProperty> intr_properties = [], + string name = "", + list<SDNodeProperty> sd_properties = []> : SDPatternOperator { string LLVMName = name; string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics. list<LLVMType> RetTypes = ret_types; list<LLVMType> ParamTypes = param_types; - list<IntrinsicProperty> IntrProperties = properties; + list<IntrinsicProperty> IntrProperties = intr_properties; + let Properties = sd_properties; bit isTarget = 0; } diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 14f0c48266f0b..d794535700e5a 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -148,10 +148,14 @@ public: /// incremental build. void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); } - /// Cache policy: interval (seconds) between two prune of the cache. Set to a - /// negative value (default) to disable pruning. A value of 0 will be ignored. + /// Cache policy: interval (seconds) between two prunes of the cache. Set to a + /// negative value to disable pruning. A value of 0 will be ignored. void setCachePruningInterval(int Interval) { - if (Interval) + if (Interval == 0) + return; + if(Interval < 0) + CacheOptions.Policy.Interval.reset(); + else CacheOptions.Policy.Interval = std::chrono::seconds(Interval); } diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 234762f36dd47..c538c46fc0728 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -165,7 +165,8 @@ protected: const char *ZeroDirective; /// This directive allows emission of an ascii string with the standard C - /// escape characters embedded into it. Defaults to "\t.ascii\t" + /// escape characters embedded into it. If a target doesn't support this, it + /// can be set to null. Defaults to "\t.ascii\t" const char *AsciiDirective; /// If not null, this allows for special handling of zero terminated strings diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 481d96724d40b..a820517007082 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -95,6 +95,17 @@ public: virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, const MCInst &Inst, const MCSubtargetInfo &STI); + virtual void emitDwarfFileDirective(StringRef Directive); + + /// Update streamer for a new active section. + /// + /// This is called by PopSection and SwitchSection, if the current + /// section changes. + virtual void changeSection(const MCSection *CurSection, MCSection *Section, + const MCExpr *SubSection, raw_ostream &OS); + + virtual void emitValue(const MCExpr *Value); + virtual void finish(); }; diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index 5bb1a3fca3d17..71951d83f3cc2 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -43,9 +43,9 @@ public: }; WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, - uint32_t ElementIndex, uint32_t ImportIndex = 0) + uint32_t ElementIndex, uint32_t FunctionType = 0) : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex), - ImportIndex(ImportIndex) {} + FunctionType(FunctionType) {} StringRef Name; SymbolType Type; @@ -55,8 +55,18 @@ public: // Index into either the function or global index space. uint32_t ElementIndex; - // For imports, the index into the import table - uint32_t ImportIndex; + // For function, the type index + uint32_t FunctionType; + + // Symbols can be both exported and imported (in the case of the weakly + // defined symbol). In this the import index is stored as AltIndex. + uint32_t AltIndex = 0; + bool HasAltIndex = false; + + void setAltIndex(uint32_t Index) { + HasAltIndex = true; + AltIndex = Index; + } bool isFunction() const { return Type == WasmSymbol::SymbolType::FUNCTION_IMPORT || @@ -91,8 +101,7 @@ public: void print(raw_ostream &Out) const { Out << "Name=" << Name << ", Type=" << static_cast<int>(Type) - << ", Flags=" << Flags << " ElemIndex=" << ElementIndex - << ", ImportIndex=" << ImportIndex; + << ", Flags=" << Flags << " ElemIndex=" << ElementIndex; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) diff --git a/include/llvm/Support/CachePruning.h b/include/llvm/Support/CachePruning.h index c577e9b8b6310..327c7df4570fe 100644 --- a/include/llvm/Support/CachePruning.h +++ b/include/llvm/Support/CachePruning.h @@ -27,8 +27,9 @@ template <typename T> class Expected; struct CachePruningPolicy { /// The pruning interval. This is intended to be used to avoid scanning the /// directory too often. It does not impact the decision of which file to - /// prune. A value of 0 forces the scan to occur. - std::chrono::seconds Interval = std::chrono::seconds(1200); + /// prune. A value of 0 forces the scan to occur. A value of None disables + /// pruning. + llvm::Optional<std::chrono::seconds> Interval = std::chrono::seconds(1200); /// The expiration for a file. When a file hasn't been accessed for Expiration /// seconds, it is removed from the cache. A value of 0 disables the diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 59c93f15d7b83..7b849fdb86706 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_MEMORYBUFFER_H #include "llvm-c/Types.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/CBindingWrapping.h" @@ -47,6 +48,9 @@ protected: void init(const char *BufStart, const char *BufEnd, bool RequiresNullTerminator); + + static constexpr bool Writable = false; + public: MemoryBuffer(const MemoryBuffer &) = delete; MemoryBuffer &operator=(const MemoryBuffer &) = delete; @@ -119,12 +123,6 @@ public: static std::unique_ptr<MemoryBuffer> getNewMemBuffer(size_t Size, StringRef BufferName = ""); - /// Allocate a new MemoryBuffer of the specified size that is not initialized. - /// Note that the caller should initialize the memory allocated by this - /// method. The memory is owned by the MemoryBuffer object. - static std::unique_ptr<MemoryBuffer> - getNewUninitMemBuffer(size_t Size, const Twine &BufferName = ""); - /// Read all of stdin into a file buffer, and return it. static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN(); @@ -156,6 +154,62 @@ public: MemoryBufferRef getMemBufferRef() const; }; +/// This class is an extension of MemoryBuffer, which allows writing to the +/// underlying contents. It only supports creation methods that are guaranteed +/// to produce a writable buffer. For example, mapping a file read-only is not +/// supported. +class WritableMemoryBuffer : public MemoryBuffer { +protected: + WritableMemoryBuffer() = default; + + static constexpr bool Writable = true; + +public: + using MemoryBuffer::getBuffer; + using MemoryBuffer::getBufferEnd; + using MemoryBuffer::getBufferStart; + + // const_cast is well-defined here, because the underlying buffer is + // guaranteed to have been initialized with a mutable buffer. + char *getBufferStart() { + return const_cast<char *>(MemoryBuffer::getBufferStart()); + } + char *getBufferEnd() { + return const_cast<char *>(MemoryBuffer::getBufferEnd()); + } + MutableArrayRef<char> getBuffer() { + return {getBufferStart(), getBufferEnd()}; + } + + static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> + getFile(const Twine &Filename, int64_t FileSize = -1, + bool IsVolatile = false); + + /// Map a subrange of the specified file as a WritableMemoryBuffer. + static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> + getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset, + bool IsVolatile = false); + + /// Allocate a new MemoryBuffer of the specified size that is not initialized. + /// Note that the caller should initialize the memory allocated by this + /// method. The memory is owned by the MemoryBuffer object. + static std::unique_ptr<WritableMemoryBuffer> + getNewUninitMemBuffer(size_t Size, const Twine &BufferName = ""); + +private: + // Hide these base class factory function so one can't write + // WritableMemoryBuffer::getXXX() + // and be surprised that he got a read-only Buffer. + using MemoryBuffer::getFileAsStream; + using MemoryBuffer::getFileOrSTDIN; + using MemoryBuffer::getMemBuffer; + using MemoryBuffer::getMemBufferCopy; + using MemoryBuffer::getNewMemBuffer; + using MemoryBuffer::getOpenFile; + using MemoryBuffer::getOpenFileSlice; + using MemoryBuffer::getSTDIN; +}; + class MemoryBufferRef { StringRef Buffer; StringRef Identifier; diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 83b097a199d6b..674c78a11695f 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -549,9 +549,9 @@ inline QuotingType needsQuotes(StringRef S) { // range. if (C <= 0x1F) return QuotingType::Double; - // C1 control block (0x80 - 0x9F) is excluded from the allowed character - // range. - if (C >= 0x80 && C <= 0x9F) + + // Always double quote UTF-8. + if ((C & 0x80) != 0) return QuotingType::Double; // The character is not safe, at least simple quoting needed. @@ -1725,7 +1725,7 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl { template <> struct ScalarTraits<Type> { \ static void output(const Type &Value, void *ctx, raw_ostream &Out); \ static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \ - static QuotingType mustQuote(StringRef) { return MustQuote; } \ + static QuotingType mustQuote(StringRef) { return MustQuote; } \ }; \ } \ } diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 5421b22462ae3..97442f9a7849e 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -24,6 +24,7 @@ namespace llvm { +class Function; class GlobalValue; class MachineModuleInfo; class Mangler; @@ -38,6 +39,7 @@ class PassManagerBuilder; class Target; class TargetIntrinsicInfo; class TargetIRAnalysis; +class TargetTransformInfo; class TargetLoweringObjectFile; class TargetPassConfig; class TargetSubtargetInfo; @@ -204,7 +206,13 @@ public: /// This is used to construct the new pass manager's target IR analysis pass, /// set up appropriately for this target machine. Even the old pass manager /// uses this to answer queries about the IR. - virtual TargetIRAnalysis getTargetIRAnalysis(); + TargetIRAnalysis getTargetIRAnalysis(); + + /// \brief Return a TargetTransformInfo for a given function. + /// + /// The returned TargetTransformInfo is specialized to the subtarget + /// corresponding to \p F. + virtual TargetTransformInfo getTargetTransformInfo(const Function &F); /// Allow the target to modify the pass manager, e.g. by calling /// PassManagerBuilder::addExtension. @@ -280,11 +288,11 @@ protected: // Can only create subclasses. void initAsmInfo(); public: - /// \brief Get a TargetIRAnalysis implementation for the target. + /// \brief Get a TargetTransformInfo implementation for the target. /// - /// This analysis will produce a TTI result which uses the common code - /// generator to answer queries about the IR. - TargetIRAnalysis getTargetIRAnalysis() override; + /// The TTI returned uses the common code generator to answer queries about + /// the IR. + TargetTransformInfo getTargetTransformInfo(const Function &F) override; /// Create a pass configuration object to be used by addPassToEmitX methods /// for generating a pipeline of CodeGen passes. diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 06caa21d288c4..f6162377b8b73 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -286,32 +286,6 @@ class SDCallSeqEnd<list<SDTypeConstraint> constraints> : SDTypeProfile<0, 2, constraints>; //===----------------------------------------------------------------------===// -// Selection DAG Node Properties. -// -// Note: These are hard coded into tblgen. -// -class SDNodeProperty; -def SDNPCommutative : SDNodeProperty; // X op Y == Y op X -def SDNPAssociative : SDNodeProperty; // (X op Y) op Z == X op (Y op Z) -def SDNPHasChain : SDNodeProperty; // R/W chain operand and result -def SDNPOutGlue : SDNodeProperty; // Write a flag result -def SDNPInGlue : SDNodeProperty; // Read a flag operand -def SDNPOptInGlue : SDNodeProperty; // Optionally read a flag operand -def SDNPMayStore : SDNodeProperty; // May write to memory, sets 'mayStore'. -def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'. -def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. -def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand -def SDNPVariadic : SDNodeProperty; // Node has variable arguments. -def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match -def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent - -//===----------------------------------------------------------------------===// -// Selection DAG Pattern Operations -class SDPatternOperator { - list<SDNodeProperty> Properties = []; -} - -//===----------------------------------------------------------------------===// // Selection DAG Node definitions. // class SDNode<string opcode, SDTypeProfile typeprof, diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index cd6b770f76ac0..b1e13f17aef15 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -133,7 +133,7 @@ ModulePass *createAddressSanitizerModulePass(bool CompileKernel = false, FunctionPass *createMemorySanitizerPass(int TrackOrigins = 0, bool Recover = false); -FunctionPass *createHWAddressSanitizerPass(); +FunctionPass *createHWAddressSanitizerPass(bool Recover = false); // Insert ThreadSanitizer (race detection) instrumentation FunctionPass *createThreadSanitizerPass(); diff --git a/include/llvm/Transforms/Utils/CallPromotionUtils.h b/include/llvm/Transforms/Utils/CallPromotionUtils.h index e0bf85781d811..6e8ece7236380 100644 --- a/include/llvm/Transforms/Utils/CallPromotionUtils.h +++ b/include/llvm/Transforms/Utils/CallPromotionUtils.h @@ -29,13 +29,23 @@ namespace llvm { bool isLegalToPromote(CallSite CS, Function *Callee, const char **FailureReason = nullptr); +/// Promote the given indirect call site to unconditionally call \p Callee. +/// +/// This function promotes the given call site, returning the direct call or +/// invoke instruction. If the function type of the call site doesn't match that +/// of the callee, bitcast instructions are inserted where appropriate. If \p +/// RetBitCast is non-null, it will be used to store the return value bitcast, +/// if created. +Instruction *promoteCall(CallSite CS, Function *Callee, + CastInst **RetBitCast = nullptr); + /// Promote the given indirect call site to conditionally call \p Callee. /// /// This function creates an if-then-else structure at the location of the call -/// site. The original call site is promoted and moved into the "then" block. A -/// clone of the indirect call site is placed in the "else" block and returned. -/// If \p BranchWeights is non-null, it will be used to set !prof metadata on -/// the new conditional branch. +/// site. The original call site is moved into the "else" block. A clone of the +/// indirect call site is promoted, placed in the "then" block, and returned. If +/// \p BranchWeights is non-null, it will be used to set !prof metadata on the +/// new conditional branch. Instruction *promoteCallWithIfThenElse(CallSite CS, Function *Callee, MDNode *BranchWeights = nullptr); diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap index 382942be64a1e..d8b07c4f54da7 100644 --- a/include/llvm/module.modulemap +++ b/include/llvm/module.modulemap @@ -61,7 +61,7 @@ module LLVM_BinaryFormat { textual header "BinaryFormat/ELFRelocs/SystemZ.def" textual header "BinaryFormat/ELFRelocs/x86_64.def" textual header "BinaryFormat/ELFRelocs/WebAssembly.def" - textual header "BinaryFormat/WasmRelocs/WebAssembly.def" + textual header "BinaryFormat/WasmRelocs.def" } module LLVM_Config { requires cplusplus umbrella "Config" module * { export * } } |