diff options
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AsmWriter.cpp | 147 | ||||
-rw-r--r-- | lib/IR/AttributeImpl.h | 5 | ||||
-rw-r--r-- | lib/IR/Attributes.cpp | 33 | ||||
-rw-r--r-- | lib/IR/AutoUpgrade.cpp | 39 | ||||
-rw-r--r-- | lib/IR/BasicBlock.cpp | 13 | ||||
-rw-r--r-- | lib/IR/ConstantRange.cpp | 30 | ||||
-rw-r--r-- | lib/IR/Instructions.cpp | 25 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.cpp | 30 | ||||
-rw-r--r-- | lib/IR/LLVMContextImpl.h | 148 | ||||
-rw-r--r-- | lib/IR/Metadata.cpp | 14 | ||||
-rw-r--r-- | lib/IR/Statepoint.cpp | 12 |
11 files changed, 334 insertions, 162 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 556e122ff82ff..c7f112887a306 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1,5 +1,4 @@ - -//===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===// +//===- AsmWriter.cpp - Printing LLVM as an assembly file ------------------===// // // The LLVM Compiler Infrastructure // @@ -15,63 +14,105 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/IR/Argument.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Comdat.h" +#include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalIFunc.h" +#include "llvm/IR/GlobalIndirectSymbol.h" +#include "llvm/IR/GlobalObject.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/InlineAsm.h" -#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/Operator.h" #include "llvm/IR/Statepoint.h" +#include "llvm/IR/Type.h" #include "llvm/IR/TypeFinder.h" +#include "llvm/IR/Use.h" #include "llvm/IR/UseListOrder.h" -#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/IR/User.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/AtomicOrdering.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> +#include <cassert> #include <cctype> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string> +#include <tuple> +#include <utility> +#include <vector> + using namespace llvm; // Make virtual table appear in this compilation unit. -AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} +AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default; //===----------------------------------------------------------------------===// // Helper Functions //===----------------------------------------------------------------------===// namespace { + struct OrderMap { DenseMap<const Value *, std::pair<unsigned, bool>> IDs; unsigned size() const { return IDs.size(); } std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; } + std::pair<unsigned, bool> lookup(const Value *V) const { return IDs.lookup(V); } + void index(const Value *V) { // Explicitly sequence get-size and insert-value operations to avoid UB. unsigned ID = IDs.size() + 1; IDs[V].first = ID; } }; -} + +} // end anonymous namespace static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) @@ -139,7 +180,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, unsigned ID, const OrderMap &OM, UseListOrderStack &Stack) { // Predict use-list order for this one. - typedef std::pair<const Use *, unsigned> Entry; + using Entry = std::pair<const Use *, unsigned>; SmallVector<Entry, 64> List; for (const Use &U : V->uses()) // Check if this user will be serialized. @@ -421,13 +462,10 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix); } - namespace { + class TypePrinting { - TypePrinting(const TypePrinting &) = delete; - void operator=(const TypePrinting&) = delete; public: - /// NamedTypes - The named types that are used by the current module. TypeFinder NamedTypes; @@ -435,6 +473,8 @@ public: DenseMap<StructType*, unsigned> NumberedTypes; TypePrinting() = default; + TypePrinting(const TypePrinting &) = delete; + TypePrinting &operator=(const TypePrinting &) = delete; void incorporateTypes(const Module &M); @@ -442,7 +482,8 @@ public: void printStructBody(StructType *Ty, raw_ostream &OS); }; -} // namespace + +} // end anonymous namespace void TypePrinting::incorporateTypes(const Module &M) { NamedTypes.run(M, false); @@ -574,6 +615,7 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) { } namespace llvm { + //===----------------------------------------------------------------------===// // SlotTracker Class: Enumerate slot numbers for unnamed values //===----------------------------------------------------------------------===// @@ -582,32 +624,33 @@ namespace llvm { class SlotTracker { public: /// ValueMap - A mapping of Values to slot numbers. - typedef DenseMap<const Value*, unsigned> ValueMap; + using ValueMap = DenseMap<const Value *, unsigned>; private: /// TheModule - The module for which we are holding slot numbers. const Module* TheModule; /// TheFunction - The function for which we are holding slot numbers. - const Function* TheFunction; - bool FunctionProcessed; + const Function* TheFunction = nullptr; + bool FunctionProcessed = false; bool ShouldInitializeAllMetadata; /// mMap - The slot map for the module level data. ValueMap mMap; - unsigned mNext; + unsigned mNext = 0; /// fMap - The slot map for the function level data. ValueMap fMap; - unsigned fNext; + unsigned fNext = 0; /// mdnMap - Map for MDNodes. DenseMap<const MDNode*, unsigned> mdnMap; - unsigned mdnNext; + unsigned mdnNext = 0; /// asMap - The slot map for attribute sets. DenseMap<AttributeSet, unsigned> asMap; - unsigned asNext; + unsigned asNext = 0; + public: /// Construct from a module. /// @@ -616,6 +659,7 @@ public: /// within a function (even if no functions have been initialized). explicit SlotTracker(const Module *M, bool ShouldInitializeAllMetadata = false); + /// Construct from a function, starting out in incorp state. /// /// If \c ShouldInitializeAllMetadata, initializes all metadata in all @@ -624,6 +668,9 @@ public: explicit SlotTracker(const Function *F, bool ShouldInitializeAllMetadata = false); + SlotTracker(const SlotTracker &) = delete; + SlotTracker &operator=(const SlotTracker &) = delete; + /// Return the slot number of the specified value in it's type /// plane. If something is not in the SlotTracker, return -1. int getLocalSlot(const Value *V); @@ -646,14 +693,16 @@ public: void purgeFunction(); /// MDNode map iterators. - typedef DenseMap<const MDNode*, unsigned>::iterator mdn_iterator; + using mdn_iterator = DenseMap<const MDNode*, unsigned>::iterator; + mdn_iterator mdn_begin() { return mdnMap.begin(); } mdn_iterator mdn_end() { return mdnMap.end(); } unsigned mdn_size() const { return mdnMap.size(); } bool mdn_empty() const { return mdnMap.empty(); } /// AttributeSet map iterators. - typedef DenseMap<AttributeSet, unsigned>::iterator as_iterator; + using as_iterator = DenseMap<AttributeSet, unsigned>::iterator; + as_iterator as_begin() { return asMap.begin(); } as_iterator as_end() { return asMap.end(); } unsigned as_size() const { return asMap.size(); } @@ -691,11 +740,9 @@ private: /// Add all of the metadata from an instruction. void processInstructionMetadata(const Instruction &I); - - SlotTracker(const SlotTracker &) = delete; - void operator=(const SlotTracker &) = delete; }; -} // namespace llvm + +} // end namespace llvm ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M, const Function *F) @@ -706,7 +753,7 @@ ModuleSlotTracker::ModuleSlotTracker(const Module *M, : ShouldCreateStorage(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {} -ModuleSlotTracker::~ModuleSlotTracker() {} +ModuleSlotTracker::~ModuleSlotTracker() = default; SlotTracker *ModuleSlotTracker::getMachine() { if (!ShouldCreateStorage) @@ -773,17 +820,13 @@ static SlotTracker *createSlotTracker(const Value *V) { // Module level constructor. Causes the contents of the Module (sans functions) // to be added to the slot table. SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata) - : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), - ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0), - fNext(0), mdnNext(0), asNext(0) {} + : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {} // Function level constructor. Causes the contents of the Module and the one // function provided to be added to the slot table. SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata) : TheModule(F ? F->getParent() : nullptr), TheFunction(F), - FunctionProcessed(false), - ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0), - fNext(0), mdnNext(0), asNext(0) {} + ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {} inline void SlotTracker::initialize() { if (TheModule) { @@ -949,7 +992,6 @@ int SlotTracker::getMetadataSlot(const MDNode *N) { return MI == mdnMap.end() ? -1 : (int)MI->second; } - /// getLocalSlot - Get the slot number for a value that is local to a function. int SlotTracker::getLocalSlot(const Value *V) { assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!"); @@ -1248,7 +1290,6 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } - if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) { if (CS->getType()->isPacked()) Out << '<'; @@ -1381,11 +1422,14 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node, } namespace { + struct FieldSeparator { - bool Skip; + bool Skip = true; const char *Sep; - FieldSeparator(const char *Sep = ", ") : Skip(true), Sep(Sep) {} + + FieldSeparator(const char *Sep = ", ") : Sep(Sep) {} }; + raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) { if (FS.Skip) { FS.Skip = false; @@ -1393,19 +1437,20 @@ raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) { } return OS << FS.Sep; } + struct MDFieldPrinter { raw_ostream &Out; FieldSeparator FS; - TypePrinting *TypePrinter; - SlotTracker *Machine; - const Module *Context; + TypePrinting *TypePrinter = nullptr; + SlotTracker *Machine = nullptr; + const Module *Context = nullptr; - explicit MDFieldPrinter(raw_ostream &Out) - : Out(Out), TypePrinter(nullptr), Machine(nullptr), Context(nullptr) {} + explicit MDFieldPrinter(raw_ostream &Out) : Out(Out) {} MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter, SlotTracker *Machine, const Module *Context) : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) { } + void printTag(const DINode *N); void printMacinfoType(const DIMacroNode *N); void printChecksumKind(const DIFile *N); @@ -1422,7 +1467,8 @@ struct MDFieldPrinter { bool ShouldSkipZero = true); void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK); }; -} // end namespace + +} // end anonymous namespace void MDFieldPrinter::printTag(const DINode *N) { Out << FS << "tag: "; @@ -1518,7 +1564,6 @@ void MDFieldPrinter::printEmissionKind(StringRef Name, Out << FS << Name << ": " << DICompileUnit::EmissionKindString(EK); } - template <class IntTy, class Stringifier> void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString, bool ShouldSkipZero) { @@ -1923,7 +1968,6 @@ static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N, Out << ")"; } - static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, TypePrinting *TypePrinter, SlotTracker *Machine, @@ -2062,6 +2106,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, } namespace { + class AssemblyWriter { formatted_raw_ostream &Out; const Module *TheModule; @@ -2125,7 +2170,8 @@ private: // intrinsic indicating base and derived pointer names. void printGCRelocateComment(const GCRelocateInst &Relocate); }; -} // namespace + +} // end anonymous namespace AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac, const Module *M, AssemblyAnnotationWriter *AAW, @@ -2594,7 +2640,6 @@ void AssemblyWriter::printTypeIdentities() { } /// printFunction - Print all aspects of a function. -/// void AssemblyWriter::printFunction(const Function *F) { // Print out the return type and name. Out << '\n'; @@ -2730,7 +2775,6 @@ void AssemblyWriter::printFunction(const Function *F) { /// printArgument - This member is called for every argument that is passed into /// the function. Simply print it out -/// void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) { // Output type... TypePrinter.print(Arg->getType(), Out); @@ -2747,7 +2791,6 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) { } /// printBasicBlock - This member is called for each basic block in a method. -/// void AssemblyWriter::printBasicBlock(const BasicBlock *BB) { if (BB->hasName()) { // Print out the label if it exists... Out << "\n"; @@ -2813,7 +2856,6 @@ void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) { /// printInfoComment - Print a little comment after the instruction indicating /// which slot it occupies. -/// void AssemblyWriter::printInfoComment(const Value &V) { if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V)) printGCRelocateComment(*Relocate); @@ -3046,7 +3088,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes()); writeOperandBundles(CI); - } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { Operand = II->getCalledValue(); FunctionType *FTy = II->getFunctionType(); @@ -3087,7 +3128,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(II->getNormalDest(), true); Out << " unwind "; writeOperand(II->getUnwindDest(), true); - } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) { Out << ' '; if (AI->isUsedWithInAlloca()) @@ -3113,7 +3153,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (AddrSpace != 0) { Out << ", addrspace(" << AddrSpace << ')'; } - } else if (isa<CastInst>(I)) { if (Operand) { Out << ' '; diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 4ed7b021883de..9c7b61f679236 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -100,6 +100,7 @@ public: class EnumAttributeImpl : public AttributeImpl { virtual void anchor(); + Attribute::AttrKind Kind; protected: @@ -133,6 +134,7 @@ public: class StringAttributeImpl : public AttributeImpl { virtual void anchor(); + std::string Kind; std::string Val; @@ -243,7 +245,8 @@ public: return AvailableFunctionAttrs & ((uint64_t)1) << Kind; } - typedef const AttributeSet *iterator; + using iterator = const AttributeSet *; + iterator begin() const { return getTrailingObjects<AttributeSet>(); } iterator end() const { return begin() + NumAttrSets; } diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index a518f7b5c81a8..8f2e641d64b92 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -1638,6 +1638,39 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { Caller.addFnAttr(Attribute::StackProtect); } +/// \brief If the inlined function required stack probes, then ensure that +/// the calling function has those too. +static void adjustCallerStackProbes(Function &Caller, const Function &Callee) { + if (!Caller.hasFnAttribute("probe-stack") && + Callee.hasFnAttribute("probe-stack")) { + Caller.addFnAttr(Callee.getFnAttribute("probe-stack")); + } +} + +/// \brief If the inlined function defines the size of guard region +/// on the stack, then ensure that the calling function defines a guard region +/// that is no larger. +static void +adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { + if (Callee.hasFnAttribute("stack-probe-size")) { + uint64_t CalleeStackProbeSize; + Callee.getFnAttribute("stack-probe-size") + .getValueAsString() + .getAsInteger(0, CalleeStackProbeSize); + if (Caller.hasFnAttribute("stack-probe-size")) { + uint64_t CallerStackProbeSize; + Caller.getFnAttribute("stack-probe-size") + .getValueAsString() + .getAsInteger(0, CallerStackProbeSize); + if (CallerStackProbeSize > CalleeStackProbeSize) { + Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); + } + } else { + Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); + } + } +} + #define GET_ATTR_COMPAT_FUNC #include "AttributesCompatFunc.inc" diff --git a/lib/IR/AutoUpgrade.cpp b/lib/IR/AutoUpgrade.cpp index 06934b365a11b..6a4b8032ffd54 100644 --- a/lib/IR/AutoUpgrade.cpp +++ b/lib/IR/AutoUpgrade.cpp @@ -142,6 +142,11 @@ static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) { Name.startswith("avx512.mask.packssdw.") || // Added in 5.0 Name.startswith("avx512.mask.packuswb.") || // Added in 5.0 Name.startswith("avx512.mask.packusdw.") || // Added in 5.0 + Name.startswith("avx512.mask.cmp.b") || // Added in 5.0 + Name.startswith("avx512.mask.cmp.d") || // Added in 5.0 + Name.startswith("avx512.mask.cmp.q") || // Added in 5.0 + Name.startswith("avx512.mask.cmp.w") || // Added in 5.0 + Name.startswith("avx512.mask.ucmp.") || // Added in 5.0 Name == "avx512.mask.add.pd.128" || // Added in 4.0 Name == "avx512.mask.add.pd.256" || // Added in 4.0 Name == "avx512.mask.add.ps.128" || // Added in 4.0 @@ -783,12 +788,30 @@ static Value *upgradeIntMinMax(IRBuilder<> &Builder, CallInst &CI, } static Value *upgradeMaskedCompare(IRBuilder<> &Builder, CallInst &CI, - ICmpInst::Predicate Pred) { + unsigned CC, bool Signed) { Value *Op0 = CI.getArgOperand(0); unsigned NumElts = Op0->getType()->getVectorNumElements(); - Value *Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1)); - Value *Mask = CI.getArgOperand(2); + Value *Cmp; + if (CC == 3) { + Cmp = Constant::getNullValue(llvm::VectorType::get(Builder.getInt1Ty(), NumElts)); + } else if (CC == 7) { + Cmp = Constant::getAllOnesValue(llvm::VectorType::get(Builder.getInt1Ty(), NumElts)); + } else { + ICmpInst::Predicate Pred; + switch (CC) { + default: llvm_unreachable("Unknown condition code"); + case 0: Pred = ICmpInst::ICMP_EQ; break; + case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; + case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; + case 4: Pred = ICmpInst::ICMP_NE; break; + case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; + case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; + } + Cmp = Builder.CreateICmp(Pred, Op0, CI.getArgOperand(1)); + } + + Value *Mask = CI.getArgOperand(CI.getNumArgOperands() - 1); const auto *C = dyn_cast<Constant>(Mask); if (!C || !C->isAllOnesValue()) Cmp = Builder.CreateAnd(Cmp, getX86MaskVec(Builder, Mask, NumElts)); @@ -1007,9 +1030,13 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { } else if (IsX86 && Name.startswith("avx512.mask.pcmp")) { // "avx512.mask.pcmpeq." or "avx512.mask.pcmpgt." bool CmpEq = Name[16] == 'e'; - Rep = upgradeMaskedCompare(Builder, *CI, - CmpEq ? ICmpInst::ICMP_EQ - : ICmpInst::ICMP_SGT); + Rep = upgradeMaskedCompare(Builder, *CI, CmpEq ? 0 : 6, true); + } else if (IsX86 && Name.startswith("avx512.mask.cmp")) { + unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); + Rep = upgradeMaskedCompare(Builder, *CI, Imm, true); + } else if (IsX86 && Name.startswith("avx512.mask.ucmp")) { + unsigned Imm = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); + Rep = upgradeMaskedCompare(Builder, *CI, Imm, false); } else if (IsX86 && (Name == "sse41.pmaxsb" || Name == "sse2.pmaxs.w" || Name == "sse41.pmaxsd" || diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp index 1f8659d4e2cae..2b780adf6c69c 100644 --- a/lib/IR/BasicBlock.cpp +++ b/lib/IR/BasicBlock.cpp @@ -355,6 +355,19 @@ bool BasicBlock::canSplitPredecessors() const { return true; } +bool BasicBlock::isLegalToHoistInto() const { + auto *Term = getTerminator(); + // No terminator means the block is under construction. + if (!Term) + return true; + + // If the block has no successors, there can be no instructions to hoist. + assert(Term->getNumSuccessors() > 0); + + // Instructions should not be hoisted across exception handling boundaries. + return !Term->isExceptional(); +} + /// This splits a basic block into two at the specified /// instruction. Note that all instructions BEFORE the specified iterator stay /// as part of the original basic block, an unconditional branch is added to diff --git a/lib/IR/ConstantRange.cpp b/lib/IR/ConstantRange.cpp index 21d1996ef8514..4bd17257016d7 100644 --- a/lib/IR/ConstantRange.cpp +++ b/lib/IR/ConstantRange.cpp @@ -1,4 +1,4 @@ -//===-- ConstantRange.cpp - ConstantRange implementation ------------------===// +//===- ConstantRange.cpp - ConstantRange implementation -------------------===// // // The LLVM Compiler Infrastructure // @@ -21,12 +21,21 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/APInt.h" #include "llvm/IR/ConstantRange.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> + using namespace llvm; ConstantRange::ConstantRange(uint32_t BitWidth, bool Full) @@ -170,7 +179,7 @@ ConstantRange ConstantRange::makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind) { - typedef OverflowingBinaryOperator OBO; + using OBO = OverflowingBinaryOperator; // Computes the intersection of CR0 and CR1. It is different from // intersectWith in that the ConstantRange returned will only contain elements @@ -284,27 +293,14 @@ APInt ConstantRange::getUnsignedMin() const { } APInt ConstantRange::getSignedMax() const { - if (!isWrappedSet()) { - APInt UpperMinusOne = getUpper() - 1; - if (getLower().sle(UpperMinusOne)) - return UpperMinusOne; - return APInt::getSignedMaxValue(getBitWidth()); - } - if (getLower().isNegative() == getUpper().isNegative()) + if (isFullSet() || Lower.sgt(Upper)) return APInt::getSignedMaxValue(getBitWidth()); return getUpper() - 1; } APInt ConstantRange::getSignedMin() const { - if (!isWrappedSet()) { - if (getLower().sle(getUpper() - 1)) - return getLower(); + if (isFullSet() || (Lower.sgt(Upper) && !getUpper().isMinSignedValue())) return APInt::getSignedMinValue(getBitWidth()); - } - if ((getUpper() - 1).slt(getLower())) { - if (!getUpper().isMinSignedValue()) - return APInt::getSignedMinValue(getBitWidth()); - } return getLower(); } diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp index 023a0b178a145..a79b00be4ffe8 100644 --- a/lib/IR/Instructions.cpp +++ b/lib/IR/Instructions.cpp @@ -1995,8 +1995,8 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, InsertBefore) { Op<0>() = S1; Op<1>() = S2; - init(iType); setName(Name); + AssertOK(); } BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, @@ -2008,17 +2008,17 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, InsertAtEnd) { Op<0>() = S1; Op<1>() = S2; - init(iType); setName(Name); + AssertOK(); } -void BinaryOperator::init(BinaryOps iType) { +void BinaryOperator::AssertOK() { Value *LHS = getOperand(0), *RHS = getOperand(1); (void)LHS; (void)RHS; // Silence warnings. assert(LHS->getType() == RHS->getType() && "Binary operator operand types must match!"); #ifndef NDEBUG - switch (iType) { + switch (getOpcode()) { case Add: case Sub: case Mul: assert(getType() == LHS->getType() && @@ -2038,8 +2038,7 @@ void BinaryOperator::init(BinaryOps iType) { case SDiv: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); - assert((getType()->isIntegerTy() || (getType()->isVectorTy() && - cast<VectorType>(getType())->getElementType()->isIntegerTy())) && + assert(getType()->isIntOrIntVectorTy() && "Incorrect operand type (not integer) for S/UDIV"); break; case FDiv: @@ -2052,8 +2051,7 @@ void BinaryOperator::init(BinaryOps iType) { case SRem: assert(getType() == LHS->getType() && "Arithmetic operation should return same type as operands!"); - assert((getType()->isIntegerTy() || (getType()->isVectorTy() && - cast<VectorType>(getType())->getElementType()->isIntegerTy())) && + assert(getType()->isIntOrIntVectorTy() && "Incorrect operand type (not integer) for S/UREM"); break; case FRem: @@ -2067,22 +2065,17 @@ void BinaryOperator::init(BinaryOps iType) { case AShr: assert(getType() == LHS->getType() && "Shift operation should return same type as operands!"); - assert((getType()->isIntegerTy() || - (getType()->isVectorTy() && - cast<VectorType>(getType())->getElementType()->isIntegerTy())) && + assert(getType()->isIntOrIntVectorTy() && "Tried to create a shift operation on a non-integral type!"); break; case And: case Or: case Xor: assert(getType() == LHS->getType() && "Logical operation should return same type as operands!"); - assert((getType()->isIntegerTy() || - (getType()->isVectorTy() && - cast<VectorType>(getType())->getElementType()->isIntegerTy())) && + assert(getType()->isIntOrIntVectorTy() && "Tried to create a logical operation on a non-integral type!"); break; - default: - break; + default: llvm_unreachable("Invalid opcode provided"); } #endif } diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp index 4a30d28c39138..c19e1be44fdc7 100644 --- a/lib/IR/LLVMContextImpl.cpp +++ b/lib/IR/LLVMContextImpl.cpp @@ -1,4 +1,4 @@ -//===-- LLVMContextImpl.cpp - Implement LLVMContextImpl -------------------===// +//===- LLVMContextImpl.cpp - Implement LLVMContextImpl --------------------===// // // The LLVM Compiler Infrastructure // @@ -12,18 +12,17 @@ //===----------------------------------------------------------------------===// #include "LLVMContextImpl.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/IR/Attributes.h" -#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Module.h" #include "llvm/IR/OptBisect.h" +#include "llvm/IR/Type.h" #include "llvm/Support/ManagedStatic.h" -#include <algorithm> +#include <cassert> +#include <utility> + using namespace llvm; LLVMContextImpl::LLVMContextImpl(LLVMContext &C) - : TheTrueVal(nullptr), TheFalseVal(nullptr), - VoidTy(C, Type::VoidTyID), + : VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), HalfTy(C, Type::HalfTyID), FloatTy(C, Type::FloatTyID), @@ -39,17 +38,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C) Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64), - Int128Ty(C, 128) { - InlineAsmDiagHandler = nullptr; - InlineAsmDiagContext = nullptr; - DiagnosticHandler = nullptr; - DiagnosticContext = nullptr; - RespectDiagnosticFilters = false; - DiagnosticHotnessRequested = false; - YieldCallback = nullptr; - YieldOpaqueHandle = nullptr; - NamedStructTypesUniqueID = 0; -} + Int128Ty(C, 128) {} LLVMContextImpl::~LLVMContextImpl() { // NOTE: We need to delete the contents of OwnedModules, but Module's dtor @@ -156,7 +145,6 @@ void LLVMContextImpl::dropTriviallyDeadConstantArrays() { C->destroyConstant(); } } - } while (Changed); } @@ -165,6 +153,7 @@ void Module::dropTriviallyDeadConstantArrays() { } namespace llvm { + /// \brief Make MDOperand transparent for hashing. /// /// This overload of an implementation detail of the hashing library makes @@ -179,7 +168,8 @@ namespace llvm { /// does not cause MDOperand to be transparent. In particular, a bare pointer /// doesn't get hashed before it's combined, whereas \a MDOperand would. static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); } -} + +} // end namespace llvm unsigned MDNodeOpsKey::calculateHash(MDNode *N, unsigned Offset) { unsigned Hash = hash_combine_range(N->op_begin() + Offset, N->op_end()); diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 4ba974409a4fc..4147f71ad9d2c 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -1,4 +1,4 @@ -//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class ----*- C++ -*-===// +//===- LLVMContextImpl.h - The LLVMContextImpl opaque class -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -21,11 +21,16 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/IR/Constants.h" @@ -33,21 +38,26 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" -#include "llvm/IR/ValueHandle.h" +#include "llvm/IR/TrackingMDRef.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/YAMLTraits.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <string> +#include <utility> #include <vector> namespace llvm { -class ConstantInt; class ConstantFP; -class DiagnosticInfoOptimizationRemark; -class DiagnosticInfoOptimizationRemarkMissed; -class DiagnosticInfoOptimizationRemarkAnalysis; -class GCStrategy; -class LLVMContext; +class ConstantInt; class Type; class Value; +class ValueHandleBase; struct DenseMapAPIntKeyInfo { static inline APInt getEmptyKey() { @@ -55,14 +65,17 @@ struct DenseMapAPIntKeyInfo { V.U.VAL = 0; return V; } + static inline APInt getTombstoneKey() { APInt V(nullptr, 0); V.U.VAL = 1; return V; } + static unsigned getHashValue(const APInt &Key) { return static_cast<unsigned>(hash_value(Key)); } + static bool isEqual(const APInt &LHS, const APInt &RHS) { return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS; } @@ -71,9 +84,11 @@ struct DenseMapAPIntKeyInfo { struct DenseMapAPFloatKeyInfo { static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus(), 1); } static inline APFloat getTombstoneKey() { return APFloat(APFloat::Bogus(), 2); } + static unsigned getHashValue(const APFloat &Key) { return static_cast<unsigned>(hash_value(Key)); } + static bool isEqual(const APFloat &LHS, const APFloat &RHS) { return LHS.bitwiseIsEqual(RHS); } @@ -83,10 +98,13 @@ struct AnonStructTypeKeyInfo { struct KeyTy { ArrayRef<Type*> ETypes; bool isPacked; + KeyTy(const ArrayRef<Type*>& E, bool P) : ETypes(E), isPacked(P) {} + KeyTy(const StructType *ST) : ETypes(ST->elements()), isPacked(ST->isPacked()) {} + bool operator==(const KeyTy& that) const { if (isPacked != that.isPacked) return false; @@ -98,25 +116,31 @@ struct AnonStructTypeKeyInfo { return !this->operator==(that); } }; + static inline StructType* getEmptyKey() { return DenseMapInfo<StructType*>::getEmptyKey(); } + static inline StructType* getTombstoneKey() { return DenseMapInfo<StructType*>::getTombstoneKey(); } + static unsigned getHashValue(const KeyTy& Key) { return hash_combine(hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()), Key.isPacked); } + static unsigned getHashValue(const StructType *ST) { return getHashValue(KeyTy(ST)); } + static bool isEqual(const KeyTy& LHS, const StructType *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return LHS == KeyTy(RHS); } + static bool isEqual(const StructType *LHS, const StructType *RHS) { return LHS == RHS; } @@ -127,11 +151,13 @@ struct FunctionTypeKeyInfo { const Type *ReturnType; ArrayRef<Type*> Params; bool isVarArg; + KeyTy(const Type* R, const ArrayRef<Type*>& P, bool V) : ReturnType(R), Params(P), isVarArg(V) {} KeyTy(const FunctionType *FT) : ReturnType(FT->getReturnType()), Params(FT->params()), isVarArg(FT->isVarArg()) {} + bool operator==(const KeyTy& that) const { if (ReturnType != that.ReturnType) return false; @@ -145,26 +171,32 @@ struct FunctionTypeKeyInfo { return !this->operator==(that); } }; + static inline FunctionType* getEmptyKey() { return DenseMapInfo<FunctionType*>::getEmptyKey(); } + static inline FunctionType* getTombstoneKey() { return DenseMapInfo<FunctionType*>::getTombstoneKey(); } + static unsigned getHashValue(const KeyTy& Key) { return hash_combine(Key.ReturnType, hash_combine_range(Key.Params.begin(), Key.Params.end()), Key.isVarArg); } + static unsigned getHashValue(const FunctionType *FT) { return getHashValue(KeyTy(FT)); } + static bool isEqual(const KeyTy& LHS, const FunctionType *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return LHS == KeyTy(RHS); } + static bool isEqual(const FunctionType *LHS, const FunctionType *RHS) { return LHS == RHS; } @@ -174,7 +206,6 @@ struct FunctionTypeKeyInfo { class MDNodeOpsKey { ArrayRef<Metadata *> RawOps; ArrayRef<MDOperand> Ops; - unsigned Hash; protected: @@ -212,14 +243,15 @@ public: }; template <class NodeTy> struct MDNodeKeyImpl; -template <class NodeTy> struct MDNodeInfo; /// Configuration point for MDNodeInfo::isEqual(). template <class NodeTy> struct MDNodeSubsetEqualImpl { - typedef MDNodeKeyImpl<NodeTy> KeyTy; + using KeyTy = MDNodeKeyImpl<NodeTy>; + static bool isSubsetEqual(const KeyTy &LHS, const NodeTy *RHS) { return false; } + static bool isSubsetEqual(const NodeTy *LHS, const NodeTy *RHS) { return false; } @@ -252,7 +284,6 @@ template <> struct MDNodeKeyImpl<DILocation> { MDNodeKeyImpl(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt) : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt) {} - MDNodeKeyImpl(const DILocation *L) : Line(L->getLine()), Column(L->getColumn()), Scope(L->getRawScope()), InlinedAt(L->getRawInlinedAt()) {} @@ -261,6 +292,7 @@ template <> struct MDNodeKeyImpl<DILocation> { return Line == RHS->getLine() && Column == RHS->getColumn() && Scope == RHS->getRawScope() && InlinedAt == RHS->getRawInlinedAt(); } + unsigned getHashValue() const { return hash_combine(Line, Column, Scope, InlinedAt); } @@ -270,6 +302,7 @@ template <> struct MDNodeKeyImpl<DILocation> { template <> struct MDNodeKeyImpl<GenericDINode> : MDNodeOpsKey { unsigned Tag; MDString *Header; + MDNodeKeyImpl(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps) : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {} MDNodeKeyImpl(const GenericDINode *N) @@ -299,6 +332,7 @@ template <> struct MDNodeKeyImpl<DISubrange> { bool isKeyOf(const DISubrange *RHS) const { return Count == RHS->getCount() && LowerBound == RHS->getLowerBound(); } + unsigned getHashValue() const { return hash_combine(Count, LowerBound); } }; @@ -313,6 +347,7 @@ template <> struct MDNodeKeyImpl<DIEnumerator> { bool isKeyOf(const DIEnumerator *RHS) const { return Value == RHS->getValue() && Name == RHS->getRawName(); } + unsigned getHashValue() const { return hash_combine(Value, Name); } }; @@ -337,6 +372,7 @@ template <> struct MDNodeKeyImpl<DIBasicType> { AlignInBits == RHS->getAlignInBits() && Encoding == RHS->getEncoding(); } + unsigned getHashValue() const { return hash_combine(Tag, Name, SizeInBits, AlignInBits, Encoding); } @@ -384,6 +420,7 @@ template <> struct MDNodeKeyImpl<DIDerivedType> { Flags == RHS->getFlags() && ExtraData == RHS->getRawExtraData(); } + unsigned getHashValue() const { // If this is a member inside an ODR type, only hash the type and the name. // Otherwise the hash will be stronger than @@ -402,10 +439,12 @@ template <> struct MDNodeKeyImpl<DIDerivedType> { }; template <> struct MDNodeSubsetEqualImpl<DIDerivedType> { - typedef MDNodeKeyImpl<DIDerivedType> KeyTy; + using KeyTy = MDNodeKeyImpl<DIDerivedType>; + static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) { return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS); } + static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS) { return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(), RHS); @@ -480,6 +519,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> { TemplateParams == RHS->getRawTemplateParams() && Identifier == RHS->getRawIdentifier(); } + unsigned getHashValue() const { // Intentionally computes the hash on a subset of the operands for // performance reason. The subset has to be significant enough to avoid @@ -504,6 +544,7 @@ template <> struct MDNodeKeyImpl<DISubroutineType> { return Flags == RHS->getFlags() && CC == RHS->getCC() && TypeArray == RHS->getRawTypeArray(); } + unsigned getHashValue() const { return hash_combine(Flags, CC, TypeArray); } }; @@ -527,6 +568,7 @@ template <> struct MDNodeKeyImpl<DIFile> { CSKind == RHS->getChecksumKind() && Checksum == RHS->getRawChecksum(); } + unsigned getHashValue() const { return hash_combine(Filename, Directory, CSKind, Checksum); } @@ -601,6 +643,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> { Variables == RHS->getRawVariables() && ThrownTypes == RHS->getRawThrownTypes(); } + unsigned getHashValue() const { // If this is a declaration inside an ODR type, only hash the type and the // name. Otherwise the hash will be stronger than @@ -619,11 +662,13 @@ template <> struct MDNodeKeyImpl<DISubprogram> { }; template <> struct MDNodeSubsetEqualImpl<DISubprogram> { - typedef MDNodeKeyImpl<DISubprogram> KeyTy; + using KeyTy = MDNodeKeyImpl<DISubprogram>; + static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { return isDeclarationOfODRMember(LHS.IsDefinition, LHS.Scope, LHS.LinkageName, LHS.TemplateParams, RHS); } + static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) { return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(), LHS->getRawLinkageName(), @@ -672,6 +717,7 @@ template <> struct MDNodeKeyImpl<DILexicalBlock> { return Scope == RHS->getRawScope() && File == RHS->getRawFile() && Line == RHS->getLine() && Column == RHS->getColumn(); } + unsigned getHashValue() const { return hash_combine(Scope, File, Line, Column); } @@ -692,6 +738,7 @@ template <> struct MDNodeKeyImpl<DILexicalBlockFile> { return Scope == RHS->getRawScope() && File == RHS->getRawFile() && Discriminator == RHS->getDiscriminator(); } + unsigned getHashValue() const { return hash_combine(Scope, File, Discriminator); } @@ -712,6 +759,7 @@ template <> struct MDNodeKeyImpl<DINamespace> { return Scope == RHS->getRawScope() && Name == RHS->getRawName() && ExportSymbols == RHS->getExportSymbols(); } + unsigned getHashValue() const { return hash_combine(Scope, Name); } @@ -723,6 +771,7 @@ template <> struct MDNodeKeyImpl<DIModule> { MDString *ConfigurationMacros; MDString *IncludePath; MDString *ISysRoot; + MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *ConfigurationMacros, MDString *IncludePath, MDString *ISysRoot) : Scope(Scope), Name(Name), ConfigurationMacros(ConfigurationMacros), @@ -738,6 +787,7 @@ template <> struct MDNodeKeyImpl<DIModule> { IncludePath == RHS->getRawIncludePath() && ISysRoot == RHS->getRawISysRoot(); } + unsigned getHashValue() const { return hash_combine(Scope, Name, ConfigurationMacros, IncludePath, ISysRoot); @@ -755,6 +805,7 @@ template <> struct MDNodeKeyImpl<DITemplateTypeParameter> { bool isKeyOf(const DITemplateTypeParameter *RHS) const { return Name == RHS->getRawName() && Type == RHS->getRawType(); } + unsigned getHashValue() const { return hash_combine(Name, Type); } }; @@ -774,6 +825,7 @@ template <> struct MDNodeKeyImpl<DITemplateValueParameter> { return Tag == RHS->getTag() && Name == RHS->getRawName() && Type == RHS->getRawType() && Value == RHS->getValue(); } + unsigned getHashValue() const { return hash_combine(Tag, Name, Type, Value); } }; @@ -816,6 +868,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariable> { RHS->getRawStaticDataMemberDeclaration() && AlignInBits == RHS->getAlignInBits(); } + unsigned getHashValue() const { // We do not use AlignInBits in hashing function here on purpose: // in most cases this param for local variable is zero (for function param @@ -856,6 +909,7 @@ template <> struct MDNodeKeyImpl<DILocalVariable> { Type == RHS->getRawType() && Arg == RHS->getArg() && Flags == RHS->getFlags() && AlignInBits == RHS->getAlignInBits(); } + unsigned getHashValue() const { // We do not use AlignInBits in hashing function here on purpose: // in most cases this param for local variable is zero (for function param @@ -877,6 +931,7 @@ template <> struct MDNodeKeyImpl<DIExpression> { bool isKeyOf(const DIExpression *RHS) const { return Elements == RHS->getElements(); } + unsigned getHashValue() const { return hash_combine_range(Elements.begin(), Elements.end()); } @@ -895,6 +950,7 @@ template <> struct MDNodeKeyImpl<DIGlobalVariableExpression> { return Variable == RHS->getRawVariable() && Expression == RHS->getRawExpression(); } + unsigned getHashValue() const { return hash_combine(Variable, Expression); } }; @@ -923,6 +979,7 @@ template <> struct MDNodeKeyImpl<DIObjCProperty> { SetterName == RHS->getRawSetterName() && Attributes == RHS->getAttributes() && Type == RHS->getRawType(); } + unsigned getHashValue() const { return hash_combine(Name, File, Line, GetterName, SetterName, Attributes, Type); @@ -948,6 +1005,7 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> { Entity == RHS->getRawEntity() && Line == RHS->getLine() && Name == RHS->getRawName(); } + unsigned getHashValue() const { return hash_combine(Tag, Scope, Entity, Line, Name); } @@ -969,6 +1027,7 @@ template <> struct MDNodeKeyImpl<DIMacro> { return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && Name == RHS->getRawName() && Value == RHS->getRawValue(); } + unsigned getHashValue() const { return hash_combine(MIType, Line, Name, Value); } @@ -991,6 +1050,7 @@ template <> struct MDNodeKeyImpl<DIMacroFile> { return MIType == RHS->getMacinfoType() && Line == RHS->getLine() && File == RHS->getRawFile() && Elements == RHS->getRawElements(); } + unsigned getHashValue() const { return hash_combine(MIType, Line, File, Elements); } @@ -998,23 +1058,29 @@ template <> struct MDNodeKeyImpl<DIMacroFile> { /// \brief DenseMapInfo for MDNode subclasses. template <class NodeTy> struct MDNodeInfo { - typedef MDNodeKeyImpl<NodeTy> KeyTy; - typedef MDNodeSubsetEqualImpl<NodeTy> SubsetEqualTy; + using KeyTy = MDNodeKeyImpl<NodeTy>; + using SubsetEqualTy = MDNodeSubsetEqualImpl<NodeTy>; + static inline NodeTy *getEmptyKey() { return DenseMapInfo<NodeTy *>::getEmptyKey(); } + static inline NodeTy *getTombstoneKey() { return DenseMapInfo<NodeTy *>::getTombstoneKey(); } + static unsigned getHashValue(const KeyTy &Key) { return Key.getHashValue(); } + static unsigned getHashValue(const NodeTy *N) { return KeyTy(N).getHashValue(); } + static bool isEqual(const KeyTy &LHS, const NodeTy *RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey()) return false; return SubsetEqualTy::isSubsetEqual(LHS, RHS) || LHS.isKeyOf(RHS); } + static bool isEqual(const NodeTy *LHS, const NodeTy *RHS) { if (LHS == RHS) return true; @@ -1024,7 +1090,7 @@ template <class NodeTy> struct MDNodeInfo { } }; -#define HANDLE_MDNODE_LEAF(CLASS) typedef MDNodeInfo<CLASS> CLASS##Info; +#define HANDLE_MDNODE_LEAF(CLASS) using CLASS##Info = MDNodeInfo<CLASS>; #include "llvm/IR/Metadata.def" /// \brief Map-like storage for metadata attachments. @@ -1097,24 +1163,24 @@ public: /// will be automatically deleted if this context is deleted. SmallPtrSet<Module*, 4> OwnedModules; - LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler; - void *InlineAsmDiagContext; + LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler = nullptr; + void *InlineAsmDiagContext = nullptr; - LLVMContext::DiagnosticHandlerTy DiagnosticHandler; - void *DiagnosticContext; - bool RespectDiagnosticFilters; - bool DiagnosticHotnessRequested; + LLVMContext::DiagnosticHandlerTy DiagnosticHandler = nullptr; + void *DiagnosticContext = nullptr; + bool RespectDiagnosticFilters = false; + bool DiagnosticHotnessRequested = false; std::unique_ptr<yaml::Output> DiagnosticsOutputFile; - LLVMContext::YieldCallbackTy YieldCallback; - void *YieldOpaqueHandle; + LLVMContext::YieldCallbackTy YieldCallback = nullptr; + void *YieldOpaqueHandle = nullptr; - typedef DenseMap<APInt, std::unique_ptr<ConstantInt>, DenseMapAPIntKeyInfo> - IntMapTy; + using IntMapTy = + DenseMap<APInt, std::unique_ptr<ConstantInt>, DenseMapAPIntKeyInfo>; IntMapTy IntConstants; - typedef DenseMap<APFloat, std::unique_ptr<ConstantFP>, DenseMapAPFloatKeyInfo> - FPMapTy; + using FPMapTy = + DenseMap<APFloat, std::unique_ptr<ConstantFP>, DenseMapAPFloatKeyInfo>; FPMapTy FPConstants; FoldingSet<AttributeImpl> AttrsSet; @@ -1142,13 +1208,13 @@ public: DenseMap<Type *, std::unique_ptr<ConstantAggregateZero>> CAZConstants; - typedef ConstantUniqueMap<ConstantArray> ArrayConstantsTy; + using ArrayConstantsTy = ConstantUniqueMap<ConstantArray>; ArrayConstantsTy ArrayConstants; - typedef ConstantUniqueMap<ConstantStruct> StructConstantsTy; + using StructConstantsTy = ConstantUniqueMap<ConstantStruct>; StructConstantsTy StructConstants; - typedef ConstantUniqueMap<ConstantVector> VectorConstantsTy; + using VectorConstantsTy = ConstantUniqueMap<ConstantVector>; VectorConstantsTy VectorConstants; DenseMap<PointerType *, std::unique_ptr<ConstantPointerNull>> CPNConstants; @@ -1163,8 +1229,8 @@ public: ConstantUniqueMap<InlineAsm> InlineAsms; - ConstantInt *TheTrueVal; - ConstantInt *TheFalseVal; + ConstantInt *TheTrueVal = nullptr; + ConstantInt *TheFalseVal = nullptr; std::unique_ptr<ConstantTokenNone> TheNoneToken; @@ -1172,7 +1238,6 @@ public: Type VoidTy, LabelTy, HalfTy, FloatTy, DoubleTy, MetadataTy, TokenTy; Type X86_FP80Ty, FP128Ty, PPC_FP128Ty, X86_MMXTy; IntegerType Int1Ty, Int8Ty, Int16Ty, Int32Ty, Int64Ty, Int128Ty; - /// TypeAllocator - All dynamically allocated types are allocated from this. /// They live forever until the context is torn down. @@ -1180,23 +1245,22 @@ public: DenseMap<unsigned, IntegerType*> IntegerTypes; - typedef DenseSet<FunctionType *, FunctionTypeKeyInfo> FunctionTypeSet; + using FunctionTypeSet = DenseSet<FunctionType *, FunctionTypeKeyInfo>; FunctionTypeSet FunctionTypes; - typedef DenseSet<StructType *, AnonStructTypeKeyInfo> StructTypeSet; + using StructTypeSet = DenseSet<StructType *, AnonStructTypeKeyInfo>; StructTypeSet AnonStructTypes; StringMap<StructType*> NamedStructTypes; - unsigned NamedStructTypesUniqueID; + unsigned NamedStructTypesUniqueID = 0; DenseMap<std::pair<Type *, uint64_t>, ArrayType*> ArrayTypes; DenseMap<std::pair<Type *, unsigned>, VectorType*> VectorTypes; DenseMap<Type*, PointerType*> PointerTypes; // Pointers in AddrSpace = 0 DenseMap<std::pair<Type*, unsigned>, PointerType*> ASPointerTypes; - /// ValueHandles - This map keeps track of all of the value handles that are /// watching a Value*. The Value::HasValueHandle bit is used to know /// whether or not a value has an entry in this map. - typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy; + using ValueHandlesTy = DenseMap<Value *, ValueHandleBase *>; ValueHandlesTy ValueHandles; /// CustomMDKindNames - Map to hold the metadata string to ID mapping. @@ -1254,6 +1318,6 @@ public: OptBisect &getOptBisect(); }; -} +} // end namespace llvm -#endif +#endif // LLVM_LIB_IR_LLVMCONTEXTIMPL_H diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp index 92e5798dcf214..ac02ff76c8436 100644 --- a/lib/IR/Metadata.cpp +++ b/lib/IR/Metadata.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/Metadata.h" #include "LLVMContextImpl.h" #include "MetadataImpl.h" #include "SymbolTableListTraitsImpl.h" @@ -27,6 +26,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/IR/Argument.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -39,6 +39,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/TrackingMDRef.h" #include "llvm/IR/Type.h" @@ -53,6 +54,7 @@ #include <cstdint> #include <iterator> #include <tuple> +#include <type_traits> #include <utility> #include <vector> @@ -233,7 +235,7 @@ void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) { return; // Copy out uses since UseMap will get touched below. - typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy; + using UseTy = std::pair<void *, std::pair<OwnerTy, uint64_t>>; SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end()); std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) { return L.second.second < R.second.second; @@ -286,7 +288,7 @@ void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { } // Copy out uses since UseMap could get touched below. - typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy; + using UseTy = std::pair<void *, std::pair<OwnerTy, uint64_t>>; SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end()); std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) { return L.second.second < R.second.second; @@ -758,8 +760,8 @@ static T *uniquifyImpl(T *N, DenseSet<T *, InfoT> &Store) { } template <class NodeTy> struct MDNode::HasCachedHash { - typedef char Yes[1]; - typedef char No[2]; + using Yes = char[1]; + using No = char[2]; template <class U, U Val> struct SFINAE {}; template <class U> @@ -1484,7 +1486,7 @@ void GlobalObject::addTypeMetadata(unsigned Offset, Metadata *TypeID) { addMetadata( LLVMContext::MD_type, *MDTuple::get(getContext(), - {ConstantAsMetadata::get(llvm::ConstantInt::get( + {ConstantAsMetadata::get(ConstantInt::get( Type::getInt64Ty(getContext()), Offset)), TypeID})); } diff --git a/lib/IR/Statepoint.cpp b/lib/IR/Statepoint.cpp index 8c3f0f208cc67..18efee2177c34 100644 --- a/lib/IR/Statepoint.cpp +++ b/lib/IR/Statepoint.cpp @@ -44,10 +44,22 @@ bool llvm::isGCRelocate(ImmutableCallSite CS) { return CS.getInstruction() && isa<GCRelocateInst>(CS.getInstruction()); } +bool llvm::isGCRelocate(const Value *V) { + if (auto CS = ImmutableCallSite(V)) + return isGCRelocate(CS); + return false; +} + bool llvm::isGCResult(ImmutableCallSite CS) { return CS.getInstruction() && isa<GCResultInst>(CS.getInstruction()); } +bool llvm::isGCResult(const Value *V) { + if (auto CS = ImmutableCallSite(V)) + return isGCResult(CS); + return false; +} + bool llvm::isStatepointDirectiveAttr(Attribute Attr) { return Attr.hasAttribute("statepoint-id") || Attr.hasAttribute("statepoint-num-patch-bytes"); |