diff --git a/llvm/include/llvm/ADT/PointerSumType.h b/llvm/include/llvm/ADT/PointerSumType.h --- a/llvm/include/llvm/ADT/PointerSumType.h +++ b/llvm/include/llvm/ADT/PointerSumType.h @@ -9,8 +9,8 @@ #ifndef LLVM_ADT_POINTERSUMTYPE_H #define LLVM_ADT_POINTERSUMTYPE_H -#include "llvm/ADT/bit.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/bit.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include #include @@ -22,10 +22,13 @@ /// indexes within a sum type. Also allows the user to specify a particular /// traits class for pointer types with custom behavior such as over-aligned /// allocation. -template > struct PointerSumTypeMember { - enum { Tag = N }; + static_assert(std::is_integral::value || std::is_enum::value, + "Tag type must be integral"); + + static constexpr TagT Tag = N; using PointerT = PointerArgT; using TraitsT = TraitsArgT; }; @@ -101,7 +104,7 @@ void *V = HelperT::template Lookup::TraitsT::getAsVoidPointer(Pointer); assert((reinterpret_cast(V) & HelperT::TagMask) == 0 && "Pointer is insufficiently aligned to store the discriminant!"); - Storage.Value = reinterpret_cast(V) | N; + Storage.Value = reinterpret_cast(V) | static_cast(N); } /// A typed constructor for a specific tagged member of the sum type. @@ -210,13 +213,13 @@ // the matching member for a tag using type deduction during overload // resolution. template - static PointerSumTypeMember - LookupOverload(PointerSumTypeMember *); - template static void LookupOverload(...); + static PointerSumTypeMember + lookupOverload(PointerSumTypeMember *); + template static void lookupOverload(...); template struct Lookup { // Compute a particular member type by resolving the lookup helper overload. using MemberT = decltype( - LookupOverload(static_cast(nullptr))); + lookupOverload(static_cast(nullptr))); /// The Nth member's pointer type. using PointerT = typename MemberT::PointerT; @@ -238,7 +241,7 @@ // Also compute the smallest discriminant and various masks for convenience. constexpr static TagT MinTag = - static_cast(Min::value); + static_cast(Min(MemberTs::Tag)...>::value); enum : uint64_t { PointerMask = static_cast(-1) << NumTagBits, TagMask = ~PointerMask @@ -248,11 +251,11 @@ // member. template struct Checker : Checker { - static_assert(MemberT::Tag < (1 << NumTagBits), + static_assert(static_cast(MemberT::Tag) < (1 << NumTagBits), "This discriminant value requires too many bits!"); }; template struct Checker : std::true_type { - static_assert(MemberT::Tag < (1 << NumTagBits), + static_assert(static_cast(MemberT::Tag) < (1 << NumTagBits), "This discriminant value requires too many bits!"); }; static_assert(Checker::value, diff --git a/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h --- a/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -115,10 +115,10 @@ }; using ValueTy = PointerSumType< - DepType, PointerSumTypeMember, - PointerSumTypeMember, - PointerSumTypeMember, - PointerSumTypeMember>>; + DepType, PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember>>; ValueTy Value; explicit MemDepResult(ValueTy V) : Value(V) {} @@ -316,7 +316,7 @@ /// local dependencies. DenseMap, NonLocalDepResult> NonLocalDefsCache; using ReverseNonLocalDefsCacheTy = - DenseMap>; + DenseMap>; ReverseNonLocalDefsCacheTy ReverseNonLocalDefsCache; /// This map stores the cached results of doing a pointer lookup at the @@ -506,7 +506,8 @@ using Result = MemoryDependenceResults; MemoryDependenceAnalysis(); - MemoryDependenceAnalysis(unsigned DefaultBlockScanLimit) : DefaultBlockScanLimit(DefaultBlockScanLimit) { } + MemoryDependenceAnalysis(unsigned DefaultBlockScanLimit) + : DefaultBlockScanLimit(DefaultBlockScanLimit) {} MemoryDependenceResults run(Function &F, FunctionAnalysisManager &AM); }; diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -70,69 +70,69 @@ /// otherwise easily derivable from the IR text. /// enum CommentFlag { - ReloadReuse = 0x1, // higher bits are reserved for target dep comments. + ReloadReuse = 0x1, // higher bits are reserved for target dep comments. NoSchedComment = 0x2, - TAsmComments = 0x4 // Target Asm comments should start from this value. + TAsmComments = 0x4 // Target Asm comments should start from this value. }; enum MIFlag { - NoFlags = 0, - FrameSetup = 1 << 0, // Instruction is used as a part of - // function frame setup code. - FrameDestroy = 1 << 1, // Instruction is used as a part of - // function frame destruction code. - BundledPred = 1 << 2, // Instruction has bundled predecessors. - BundledSucc = 1 << 3, // Instruction has bundled successors. - FmNoNans = 1 << 4, // Instruction does not support Fast - // math nan values. - FmNoInfs = 1 << 5, // Instruction does not support Fast - // math infinity values. - FmNsz = 1 << 6, // Instruction is not required to retain - // signed zero values. - FmArcp = 1 << 7, // Instruction supports Fast math - // reciprocal approximations. - FmContract = 1 << 8, // Instruction supports Fast math - // contraction operations like fma. - FmAfn = 1 << 9, // Instruction may map to Fast math - // instrinsic approximation. - FmReassoc = 1 << 10, // Instruction supports Fast math - // reassociation of operand order. - NoUWrap = 1 << 11, // Instruction supports binary operator - // no unsigned wrap. - NoSWrap = 1 << 12, // Instruction supports binary operator - // no signed wrap. - IsExact = 1 << 13, // Instruction supports division is - // known to be exact. - NoFPExcept = 1 << 14, // Instruction does not raise - // floatint-point exceptions. - NoMerge = 1 << 15, // Passes that drop source location info - // (e.g. branch folding) should skip - // this instruction. + NoFlags = 0, + FrameSetup = 1 << 0, // Instruction is used as a part of + // function frame setup code. + FrameDestroy = 1 << 1, // Instruction is used as a part of + // function frame destruction code. + BundledPred = 1 << 2, // Instruction has bundled predecessors. + BundledSucc = 1 << 3, // Instruction has bundled successors. + FmNoNans = 1 << 4, // Instruction does not support Fast + // math nan values. + FmNoInfs = 1 << 5, // Instruction does not support Fast + // math infinity values. + FmNsz = 1 << 6, // Instruction is not required to retain + // signed zero values. + FmArcp = 1 << 7, // Instruction supports Fast math + // reciprocal approximations. + FmContract = 1 << 8, // Instruction supports Fast math + // contraction operations like fma. + FmAfn = 1 << 9, // Instruction may map to Fast math + // instrinsic approximation. + FmReassoc = 1 << 10, // Instruction supports Fast math + // reassociation of operand order. + NoUWrap = 1 << 11, // Instruction supports binary operator + // no unsigned wrap. + NoSWrap = 1 << 12, // Instruction supports binary operator + // no signed wrap. + IsExact = 1 << 13, // Instruction supports division is + // known to be exact. + NoFPExcept = 1 << 14, // Instruction does not raise + // floatint-point exceptions. + NoMerge = 1 << 15, // Passes that drop source location info + // (e.g. branch folding) should skip + // this instruction. }; private: - const MCInstrDesc *MCID; // Instruction descriptor. - MachineBasicBlock *Parent = nullptr; // Pointer to the owning basic block. + const MCInstrDesc *MCID; // Instruction descriptor. + MachineBasicBlock *Parent = nullptr; // Pointer to the owning basic block. // Operands are allocated by an ArrayRecycler. - MachineOperand *Operands = nullptr; // Pointer to the first operand. - unsigned NumOperands = 0; // Number of operands on instruction. + MachineOperand *Operands = nullptr; // Pointer to the first operand. + unsigned NumOperands = 0; // Number of operands on instruction. - uint16_t Flags = 0; // Various bits of additional - // information about machine - // instruction. + uint16_t Flags = 0; // Various bits of additional + // information about machine + // instruction. - uint8_t AsmPrinterFlags = 0; // Various bits of information used by - // the AsmPrinter to emit helpful - // comments. This is *not* semantic - // information. Do not use this for - // anything other than to convey comment - // information to AsmPrinter. + uint8_t AsmPrinterFlags = 0; // Various bits of information used by + // the AsmPrinter to emit helpful + // comments. This is *not* semantic + // information. Do not use this for + // anything other than to convey comment + // information to AsmPrinter. // OperandCapacity has uint8_t size, so it should be next to AsmPrinterFlags // to properly pack. using OperandCapacity = ArrayRecycler::Capacity; - OperandCapacity CapOperands; // Capacity of the Operands array. + OperandCapacity CapOperands; // Capacity of the Operands array. /// Internal implementation detail class that provides out-of-line storage for /// extra info used by the machine instruction when this info cannot be stored @@ -240,14 +240,17 @@ // We work to optimize this common case by storing it inline here rather than // requiring a separate allocation, but we fall back to an allocation when // multiple pointers are needed. - PointerSumType, - PointerSumTypeMember, - PointerSumTypeMember, - PointerSumTypeMember> + PointerSumType< + ExtraInfoInlineKinds, + PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember> Info; - DebugLoc debugLoc; // Source line information. + DebugLoc debugLoc; // Source line information. // Intrusive list support friend struct ilist_traits; @@ -277,8 +280,8 @@ // Use MachineFunction::DeleteMachineInstr() instead. ~MachineInstr() = delete; - const MachineBasicBlock* getParent() const { return Parent; } - MachineBasicBlock* getParent() { return Parent; } + const MachineBasicBlock *getParent() const { return Parent; } + MachineBasicBlock *getParent() { return Parent; } /// Move the instruction before \p MovePos. void moveBefore(MachineInstr *MovePos); @@ -306,29 +309,19 @@ } /// Set a flag for the AsmPrinter. - void setAsmPrinterFlag(uint8_t Flag) { - AsmPrinterFlags |= Flag; - } + void setAsmPrinterFlag(uint8_t Flag) { AsmPrinterFlags |= Flag; } /// Clear specific AsmPrinter flags. - void clearAsmPrinterFlag(CommentFlag Flag) { - AsmPrinterFlags &= ~Flag; - } + void clearAsmPrinterFlag(CommentFlag Flag) { AsmPrinterFlags &= ~Flag; } /// Return the MI flags bitvector. - uint16_t getFlags() const { - return Flags; - } + uint16_t getFlags() const { return Flags; } /// Return whether an MI flag is set. - bool getFlag(MIFlag Flag) const { - return Flags & Flag; - } + bool getFlag(MIFlag Flag) const { return Flags & Flag; } /// Set a MI flag. - void setFlag(MIFlag Flag) { - Flags |= (uint16_t)Flag; - } + void setFlag(MIFlag Flag) { Flags |= (uint16_t)Flag; } void setFlags(unsigned flags) { // Filter out the automatically maintained flags. @@ -337,9 +330,7 @@ } /// clearFlag - Clear a MI flag. - void clearFlag(MIFlag Flag) { - Flags &= ~((uint16_t)Flag); - } + void clearFlag(MIFlag Flag) { Flags &= ~((uint16_t)Flag); } /// Return true if MI is in a bundle (but not the first MI in a bundle). /// @@ -376,15 +367,11 @@ /// ---------------- /// The first instruction has the special opcode "BUNDLE". It's not "inside" /// a bundle, but the next three MIs are. - bool isInsideBundle() const { - return getFlag(BundledPred); - } + bool isInsideBundle() const { return getFlag(BundledPred); } /// Return true if this instruction part of a bundle. This is true /// if either itself or its following instruction is marked "InsideBundle". - bool isBundled() const { - return isBundledWithPred() || isBundledWithSucc(); - } + bool isBundled() const { return isBundledWithPred() || isBundledWithSucc(); } /// Return true if this instruction is part of a bundle, and it is not the /// first instruction in the bundle. @@ -466,11 +453,11 @@ return std::distance(debug_operands().begin(), debug_operands().end()); } - const MachineOperand& getOperand(unsigned i) const { + const MachineOperand &getOperand(unsigned i) const { assert(i < getNumOperands() && "getOperand() out of range!"); return Operands[i]; } - MachineOperand& getOperand(unsigned i) { + MachineOperand &getOperand(unsigned i) { assert(i < getNumOperands() && "getOperand() out of range!"); return Operands[i]; } @@ -514,8 +501,8 @@ /// Returns true if the instruction has implicit definition. bool hasImplicitDef() const { - for (unsigned I = getNumExplicitOperands(), E = getNumOperands(); - I != E; ++I) { + for (unsigned I = getNumExplicitOperands(), E = getNumOperands(); I != E; + ++I) { const MachineOperand &MO = getOperand(I); if (MO.isDef() && MO.isImplicit()) return true; @@ -703,9 +690,9 @@ /// queries but they are bundle aware. enum QueryType { - IgnoreBundle, // Ignore bundles - AnyInBundle, // Return true if any instruction in bundle has property - AllInBundle // Return true if all instructions in bundle have property + IgnoreBundle, // Ignore bundles + AnyInBundle, // Return true if any instruction in bundle has property + AllInBundle // Return true if all instructions in bundle have property }; /// Return true if the instruction (or in the case of a bundle, @@ -823,8 +810,8 @@ /// values. There are various methods in TargetInstrInfo that can be used to /// control and modify the predicate in this instruction. bool isPredicable(QueryType Type = AllInBundle) const { - // If it's a bundle than all bundled instructions must be predicable for this - // to return true. + // If it's a bundle than all bundled instructions must be predicable for + // this to return true. return hasProperty(MCID::Predicable, Type); } @@ -1078,10 +1065,10 @@ } enum MICheckType { - CheckDefs, // Check all operands for equality - CheckKillDead, // Check all operands including kill / dead markers - IgnoreDefs, // Ignore all definitions - IgnoreVRegDefs // Ignore virtual register definitions + CheckDefs, // Check all operands for equality + CheckKillDead, // Check all operands including kill / dead markers + IgnoreDefs, // Ignore all definitions + IgnoreVRegDefs // Ignore virtual register definitions }; /// Return true if this instruction is identical to \p Other. @@ -1171,7 +1158,9 @@ getOpcode() == TargetOpcode::G_PHI; } bool isKill() const { return getOpcode() == TargetOpcode::KILL; } - bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } + bool isImplicitDef() const { + return getOpcode() == TargetOpcode::IMPLICIT_DEF; + } bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM || getOpcode() == TargetOpcode::INLINEASM_BR; @@ -1198,13 +1187,9 @@ return getOpcode() == TargetOpcode::REG_SEQUENCE; } - bool isBundle() const { - return getOpcode() == TargetOpcode::BUNDLE; - } + bool isBundle() const { return getOpcode() == TargetOpcode::BUNDLE; } - bool isCopy() const { - return getOpcode() == TargetOpcode::COPY; - } + bool isCopy() const { return getOpcode() == TargetOpcode::COPY; } bool isFullCopy() const { return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg(); @@ -1216,14 +1201,12 @@ /// Return true if the instruction behaves like a copy. /// This does not include native copy instructions. - bool isCopyLike() const { - return isCopy() || isSubregToReg(); - } + bool isCopyLike() const { return isCopy() || isSubregToReg(); } /// Return true is the instruction is an identity copy. bool isIdentityCopy() const { return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() && - getOperand(0).getSubReg() == getOperand(1).getSubReg(); + getOperand(0).getSubReg() == getOperand(1).getSubReg(); } /// Return true if this instruction doesn't produce any output in the form of @@ -1252,7 +1235,8 @@ switch (getOpcode()) { default: return isMetaInstruction(); - // Copy-like instructions are usually eliminated during register allocation. + // Copy-like instructions are usually eliminated during register + // allocation. case TargetOpcode::PHI: case TargetOpcode::G_PHI: case TargetOpcode::COPY: @@ -1290,8 +1274,9 @@ /// Return a pair of bools (reads, writes) indicating if this instruction /// reads or writes Reg. This also considers partial defines. /// If Ops is not null, all operand indices for Reg are added. - std::pair readsWritesVirtualRegister(Register Reg, - SmallVectorImpl *Ops = nullptr) const; + std::pair + readsWritesVirtualRegister(Register Reg, + SmallVectorImpl *Ops = nullptr) const; /// Return true if the MachineInstr kills the specified register. /// If TargetRegisterInfo is passed, then it also checks if there is @@ -1337,17 +1322,18 @@ /// Wrapper for findRegisterUseOperandIdx, it returns /// a pointer to the MachineOperand rather than an index. - MachineOperand *findRegisterUseOperand(Register Reg, bool isKill = false, - const TargetRegisterInfo *TRI = nullptr) { + MachineOperand * + findRegisterUseOperand(Register Reg, bool isKill = false, + const TargetRegisterInfo *TRI = nullptr) { int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); return (Idx == -1) ? nullptr : &getOperand(Idx); } - const MachineOperand *findRegisterUseOperand( - Register Reg, bool isKill = false, - const TargetRegisterInfo *TRI = nullptr) const { - return const_cast(this)-> - findRegisterUseOperand(Reg, isKill, TRI); + const MachineOperand * + findRegisterUseOperand(Register Reg, bool isKill = false, + const TargetRegisterInfo *TRI = nullptr) const { + return const_cast(this)->findRegisterUseOperand(Reg, isKill, + TRI); } /// Returns the operand index that is a def of the specified register or @@ -1356,8 +1342,8 @@ /// overlap the specified register. If TargetRegisterInfo is non-null, /// then it also checks if there is a def of a super-register. /// This may also return a register mask operand when Overlap is true. - int findRegisterDefOperandIdx(Register Reg, - bool isDead = false, bool Overlap = false, + int findRegisterDefOperandIdx(Register Reg, bool isDead = false, + bool Overlap = false, const TargetRegisterInfo *TRI = nullptr) const; /// Wrapper for findRegisterDefOperandIdx, it returns @@ -1400,9 +1386,8 @@ /// /// Returns NULL if the static register class constraint cannot be /// determined. - const TargetRegisterClass* - getRegClassConstraint(unsigned OpIdx, - const TargetInstrInfo *TII, + const TargetRegisterClass * + getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const; /// Applies the constraints (def/use) implied by this MI on \p Reg to @@ -1585,8 +1570,7 @@ Optional getRestoreSize(const TargetInstrInfo *TII) const; /// Return a valid size if the instruction is a folded restore instruction. - Optional - getFoldedRestoreSize(const TargetInstrInfo *TII) const; + Optional getFoldedRestoreSize(const TargetInstrInfo *TII) const; /// Copy implicit register operands from specified /// instruction to this instruction. @@ -1726,7 +1710,7 @@ /// Return the MIFlags which represent both MachineInstrs. This /// should be used when merging two MachineInstrs into one. This routine does /// not modify the MIFlags of this MachineInstr. - uint16_t mergeFlagsWith(const MachineInstr& Other) const; + uint16_t mergeFlagsWith(const MachineInstr &Other) const; static uint16_t copyFlagsFromInstruction(const Instruction &I); @@ -1778,12 +1762,12 @@ /// Unlink all of the register operands in this instruction from their /// respective use lists. This requires that the operands already be on their /// use lists. - void RemoveRegOperandsFromUseLists(MachineRegisterInfo&); + void RemoveRegOperandsFromUseLists(MachineRegisterInfo &); /// Add all of the register operands in this instruction from their /// respective use lists. This requires that the operands not be on their /// use lists yet. - void AddRegOperandsToUseLists(MachineRegisterInfo&); + void AddRegOperandsToUseLists(MachineRegisterInfo &); /// Slow path for hasProperty when we're dealing with a bundle. bool hasPropertyInBundle(uint64_t Mask, QueryType Type) const; @@ -1806,19 +1790,17 @@ /// instruction rather than by pointer value. /// The hashing and equality testing functions ignore definitions so this is /// useful for CSE, etc. -struct MachineInstrExpressionTrait : DenseMapInfo { - static inline MachineInstr *getEmptyKey() { - return nullptr; - } +struct MachineInstrExpressionTrait : DenseMapInfo { + static inline MachineInstr *getEmptyKey() { return nullptr; } static inline MachineInstr *getTombstoneKey() { - return reinterpret_cast(-1); + return reinterpret_cast(-1); } - static unsigned getHashValue(const MachineInstr* const &MI); + static unsigned getHashValue(const MachineInstr *const &MI); - static bool isEqual(const MachineInstr* const &LHS, - const MachineInstr* const &RHS) { + static bool isEqual(const MachineInstr *const &LHS, + const MachineInstr *const &RHS) { if (RHS == getEmptyKey() || RHS == getTombstoneKey() || LHS == getEmptyKey() || LHS == getTombstoneKey()) return LHS == RHS; @@ -1829,7 +1811,7 @@ //===----------------------------------------------------------------------===// // Debugging Support -inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) { +inline raw_ostream &operator<<(raw_ostream &OS, const MachineInstr &MI) { MI.print(OS); return OS; } diff --git a/llvm/unittests/ADT/PointerSumTypeTest.cpp b/llvm/unittests/ADT/PointerSumTypeTest.cpp --- a/llvm/unittests/ADT/PointerSumTypeTest.cpp +++ b/llvm/unittests/ADT/PointerSumTypeTest.cpp @@ -17,9 +17,9 @@ float f; int i1, i2; - typedef PointerSumType, - PointerSumTypeMember, - PointerSumTypeMember> + typedef PointerSumType, + PointerSumTypeMember, + PointerSumTypeMember> SumType; SumType a, b, c, n; @@ -108,5 +108,15 @@ EXPECT_EQ(nullptr, n.get()); } +TEST_F(PointerSumTypeTest, ScopedEnum) { + enum class ScopedKind { Float, Int1, Int2 }; + using ScopedSumType = PointerSumType< + ScopedKind, PointerSumTypeMember, + PointerSumTypeMember, + PointerSumTypeMember>; + ScopedSumType SumType(ScopedSumType::create(&f)); + EXPECT_TRUE(SumType); + EXPECT_EQ(ScopedKind::Float, SumType.getTag()); +} } // end anonymous namespace