diff options
Diffstat (limited to 'include/llvm/Support')
69 files changed, 2832 insertions, 5086 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h new file mode 100644 index 0000000..69732fc --- /dev/null +++ b/include/llvm/Support/ARMBuildAttributes.h @@ -0,0 +1,189 @@ +//===-- ARMBuildAttributes.h - ARM Build Attributes -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains enumerations and support routines for ARM build attributes +// as defined in ARM ABI addenda document (ABI release 2.08). +// +// ELF for the ARM Architecture r2.09 - November 30, 2012 +// +// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H +#define LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H + +namespace llvm { +class StringRef; + +namespace ARMBuildAttrs { + +enum SpecialAttr { + // This is for the .cpu asm attr. It translates into one or more + // AttrType (below) entries in the .ARM.attributes section in the ELF. + SEL_CPU +}; + +enum AttrType { + // Rest correspond to ELF/.ARM.attributes + File = 1, + CPU_raw_name = 4, + CPU_name = 5, + CPU_arch = 6, + CPU_arch_profile = 7, + ARM_ISA_use = 8, + THUMB_ISA_use = 9, + FP_arch = 10, + WMMX_arch = 11, + Advanced_SIMD_arch = 12, + PCS_config = 13, + ABI_PCS_R9_use = 14, + ABI_PCS_RW_data = 15, + ABI_PCS_RO_data = 16, + ABI_PCS_GOT_use = 17, + ABI_PCS_wchar_t = 18, + ABI_FP_rounding = 19, + ABI_FP_denormal = 20, + ABI_FP_exceptions = 21, + ABI_FP_user_exceptions = 22, + ABI_FP_number_model = 23, + ABI_align_needed = 24, + ABI_align_preserved = 25, + ABI_enum_size = 26, + ABI_HardFP_use = 27, + ABI_VFP_args = 28, + ABI_WMMX_args = 29, + ABI_optimization_goals = 30, + ABI_FP_optimization_goals = 31, + compatibility = 32, + CPU_unaligned_access = 34, + FP_HP_extension = 36, + ABI_FP_16bit_format = 38, + MPextension_use = 42, // recoded from 70 (ABI r2.08) + DIV_use = 44, + also_compatible_with = 65, + conformance = 67, + Virtualization_use = 68, + + /// Legacy Tags + Section = 2, // deprecated (ABI r2.09) + Symbol = 3, // deprecated (ABI r2.09) + ABI_align8_needed = 24, // renamed to ABI_align_needed (ABI r2.09) + ABI_align8_preserved = 25, // renamed to ABI_align_preserved (ABI r2.09) + nodefaults = 64, // deprecated (ABI r2.09) + T2EE_use = 66, // deprecated (ABI r2.09) + MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08) +}; + +StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix = true); +StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true); +int AttrTypeFromString(StringRef Tag); + +// Magic numbers for .ARM.attributes +enum AttrMagic { + Format_Version = 0x41 +}; + +// Legal Values for CPU_arch, (=6), uleb128 +enum CPUArch { + Pre_v4 = 0, + v4 = 1, // e.g. SA110 + v4T = 2, // e.g. ARM7TDMI + v5T = 3, // e.g. ARM9TDMI + v5TE = 4, // e.g. ARM946E_S + v5TEJ = 5, // e.g. ARM926EJ_S + v6 = 6, // e.g. ARM1136J_S + v6KZ = 7, // e.g. ARM1176JZ_S + v6T2 = 8, // e.g. ARM1156T2F_S + v6K = 9, // e.g. ARM1136J_S + v7 = 10, // e.g. Cortex A8, Cortex M3 + v6_M = 11, // e.g. Cortex M1 + v6S_M = 12, // v6_M with the System extensions + v7E_M = 13, // v7_M with DSP extensions + v8 = 14 // v8, AArch32 +}; + +enum CPUArchProfile { // (=7), uleb128 + Not_Applicable = 0, // pre v7, or cross-profile code + ApplicationProfile = (0x41), // 'A' (e.g. for Cortex A8) + RealTimeProfile = (0x52), // 'R' (e.g. for Cortex R4) + MicroControllerProfile = (0x4D), // 'M' (e.g. for Cortex M3) + SystemProfile = (0x53) // 'S' Application or real-time profile +}; + +// The following have a lot of common use cases +enum { + Not_Allowed = 0, + Allowed = 1, + + // Tag_ARM_ISA_use (=8), uleb128 + + // Tag_THUMB_ISA_use, (=9), uleb128 + AllowThumb32 = 2, // 32-bit Thumb (implies 16-bit instructions) + + // Tag_FP_arch (=10), uleb128 (formerly Tag_VFP_arch = 10) + AllowFPv2 = 2, // v2 FP ISA permitted (implies use of the v1 FP ISA) + AllowFPv3A = 3, // v3 FP ISA permitted (implies use of the v2 FP ISA) + AllowFPv3B = 4, // v3 FP ISA permitted, but only D0-D15, S0-S31 + AllowFPv4A = 5, // v4 FP ISA permitted (implies use of v3 FP ISA) + AllowFPv4B = 6, // v4 FP ISA was permitted, but only D0-D15, S0-S31 + AllowFPARMv8A = 7, // Use of the ARM v8-A FP ISA was permitted + AllowFPARMv8B = 8, // Use of the ARM v8-A FP ISA was permitted, but only + // D0-D15, S0-S31 + + // Tag_WMMX_arch, (=11), uleb128 + AllowWMMXv1 = 1, // The user permitted this entity to use WMMX v1 + AllowWMMXv2 = 2, // The user permitted this entity to use WMMX v2 + + // Tag_Advanced_SIMD_arch, (=12), uleb128 + AllowNeon = 1, // SIMDv1 was permitted + AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations) + AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted + + // Tag_ABI_FP_denormal, (=20), uleb128 + PreserveFPSign = 2, // sign when flushed-to-zero is preserved + + // Tag_ABI_FP_number_model, (=23), uleb128 + AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI]) + AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings + + // Tag_ABI_HardFP_use, (=27), uleb128 + HardFPImplied = 0, // FP use should be implied by Tag_FP_arch + HardFPSinglePrecision = 1, // Single-precision only + + // Tag_ABI_VFP_args, (=28), uleb128 + BaseAAPCS = 0, + HardFPAAPCS = 1, + + // Tag_FP_HP_extension, (=36), uleb128 + AllowHPFP = 1, // Allow use of Half Precision FP + + // Tag_MPextension_use, (=42), uleb128 + AllowMP = 1, // Allow use of MP extensions + + // Tag_DIV_use, (=44), uleb128 + // Note: AllowDIVExt must be emitted if and only if the permission to use + // hardware divide cannot be conveyed using AllowDIVIfExists or DisallowDIV + AllowDIVIfExists = 0, // Allow hardware divide if available in arch, or no + // info exists. + DisallowDIV = 1, // Hardware divide explicitly disallowed. + AllowDIVExt = 2, // Allow hardware divide as optional architecture + // extension above the base arch specified by + // Tag_CPU_arch and Tag_CPU_arch_profile. + + // Tag_Virtualization_use, (=68), uleb128 + AllowTZ = 1, + AllowVirtualization = 2, + AllowTZVirtualization = 3 +}; + +} // namespace ARMBuildAttrs +} // namespace llvm + +#endif // LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h new file mode 100644 index 0000000..c7ac54a --- /dev/null +++ b/include/llvm/Support/ARMEHABI.h @@ -0,0 +1,134 @@ +//===--- ARMEHABI.h - ARM Exception Handling ABI ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the constants for the ARM unwind opcodes and exception +// handling table entry kinds. +// +// The enumerations and constants in this file reflect the ARM EHABI +// Specification as published by ARM. +// +// Exception Handling ABI for the ARM Architecture r2.09 - November 30, 2012 +// +// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ARM_EHABI_H +#define LLVM_SUPPORT_ARM_EHABI_H + +namespace llvm { +namespace ARM { +namespace EHABI { + /// ARM exception handling table entry kinds + enum EHTEntryKind { + EHT_GENERIC = 0x00, + EHT_COMPACT = 0x80 + }; + + enum { + /// Special entry for the function never unwind + EXIDX_CANTUNWIND = 0x1 + }; + + /// ARM-defined frame unwinding opcodes + enum UnwindOpcodes { + // Format: 00xxxxxx + // Purpose: vsp = vsp + ((x << 2) + 4) + UNWIND_OPCODE_INC_VSP = 0x00, + + // Format: 01xxxxxx + // Purpose: vsp = vsp - ((x << 2) + 4) + UNWIND_OPCODE_DEC_VSP = 0x40, + + // Format: 10000000 00000000 + // Purpose: refuse to unwind + UNWIND_OPCODE_REFUSE = 0x8000, + + // Format: 1000xxxx xxxxxxxx + // Purpose: pop r[15:12], r[11:4] + // Constraint: x != 0 + UNWIND_OPCODE_POP_REG_MASK_R4 = 0x8000, + + // Format: 1001xxxx + // Purpose: vsp = r[x] + // Constraint: x != 13 && x != 15 + UNWIND_OPCODE_SET_VSP = 0x90, + + // Format: 10100xxx + // Purpose: pop r[(4+x):4] + UNWIND_OPCODE_POP_REG_RANGE_R4 = 0xa0, + + // Format: 10101xxx + // Purpose: pop r14, r[(4+x):4] + UNWIND_OPCODE_POP_REG_RANGE_R4_R14 = 0xa8, + + // Format: 10110000 + // Purpose: finish + UNWIND_OPCODE_FINISH = 0xb0, + + // Format: 10110001 0000xxxx + // Purpose: pop r[3:0] + // Constraint: x != 0 + UNWIND_OPCODE_POP_REG_MASK = 0xb100, + + // Format: 10110010 x(uleb128) + // Purpose: vsp = vsp + ((x << 2) + 0x204) + UNWIND_OPCODE_INC_VSP_ULEB128 = 0xb2, + + // Format: 10110011 xxxxyyyy + // Purpose: pop d[(x+y):x] + UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX = 0xb300, + + // Format: 10111xxx + // Purpose: pop d[(8+x):8] + UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDX_D8 = 0xb8, + + // Format: 11000xxx + // Purpose: pop wR[(10+x):10] + UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE_WR10 = 0xc0, + + // Format: 11000110 xxxxyyyy + // Purpose: pop wR[(x+y):x] + UNWIND_OPCODE_POP_WIRELESS_MMX_REG_RANGE = 0xc600, + + // Format: 11000111 0000xxxx + // Purpose: pop wCGR[3:0] + // Constraint: x != 0 + UNWIND_OPCODE_POP_WIRELESS_MMX_REG_MASK = 0xc700, + + // Format: 11001000 xxxxyyyy + // Purpose: pop d[(16+x+y):(16+x)] + UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16 = 0xc800, + + // Format: 11001001 xxxxyyyy + // Purpose: pop d[(x+y):x] + UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD = 0xc900, + + // Format: 11010xxx + // Purpose: pop d[(8+x):8] + UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D8 = 0xd0 + }; + + /// ARM-defined Personality Routine Index + enum PersonalityRoutineIndex { + // To make the exception handling table become more compact, ARM defined + // several personality routines in EHABI. There are 3 different + // personality routines in ARM EHABI currently. It is possible to have 16 + // pre-defined personality routines at most. + AEABI_UNWIND_CPP_PR0 = 0, + AEABI_UNWIND_CPP_PR1 = 1, + AEABI_UNWIND_CPP_PR2 = 2, + + NUM_PERSONALITY_INDEX + }; +} +} +} + +#endif // ARM_UNWIND_OP_H diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index bba3424..061d5ac 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -170,19 +170,22 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128) namespace detail { template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char, - typename T5 = char, typename T6 = char, typename T7 = char> + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> class AlignerImpl { - T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; + T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10; AlignerImpl(); // Never defined or instantiated. }; template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char, - typename T5 = char, typename T6 = char, typename T7 = char> + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> union SizerImpl { char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)], - arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)]; + arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)], + arr9[sizeof(T9)], arr10[sizeof(T10)]; }; } // end namespace detail @@ -195,10 +198,13 @@ union SizerImpl { /// be added at the cost of more boiler plate. template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char, - typename T5 = char, typename T6 = char, typename T7 = char> + typename T5 = char, typename T6 = char, typename T7 = char, + typename T8 = char, typename T9 = char, typename T10 = char> struct AlignedCharArrayUnion : llvm::AlignedCharArray< - AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment, - sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> { + AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, + T6, T7, T8, T9, T10> >::Alignment, + sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, + T6, T7, T8, T9, T10>)> { }; } // end namespace llvm #endif diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index 397f50f..0641322 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -17,14 +17,19 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Memory.h" #include <algorithm> #include <cassert> #include <cstddef> #include <cstdlib> namespace llvm { -template <typename T> struct ReferenceAdder { typedef T& result; }; -template <typename T> struct ReferenceAdder<T&> { typedef T result; }; +template <typename T> struct ReferenceAdder { + typedef T &result; +}; +template <typename T> struct ReferenceAdder<T &> { + typedef T result; +}; class MallocAllocator { public: @@ -35,15 +40,15 @@ public: void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } - template <typename T> - T *Allocate() { return static_cast<T*>(malloc(sizeof(T))); } + template <typename T> T *Allocate() { + return static_cast<T *>(malloc(sizeof(T))); + } - template <typename T> - T *Allocate(size_t Num) { - return static_cast<T*>(malloc(sizeof(T)*Num)); + template <typename T> T *Allocate(size_t Num) { + return static_cast<T *>(malloc(sizeof(T) * Num)); } - void Deallocate(const void *Ptr) { free(const_cast<void*>(Ptr)); } + void Deallocate(const void *Ptr) { free(const_cast<void *>(Ptr)); } void PrintStats() const {} }; @@ -77,128 +82,224 @@ class MallocSlabAllocator : public SlabAllocator { MallocAllocator Allocator; public: - MallocSlabAllocator() : Allocator() { } + MallocSlabAllocator() : Allocator() {} virtual ~MallocSlabAllocator(); - virtual MemSlab *Allocate(size_t Size) LLVM_OVERRIDE; - virtual void Deallocate(MemSlab *Slab) LLVM_OVERRIDE; + MemSlab *Allocate(size_t Size) override; + void Deallocate(MemSlab *Slab) override; }; -/// BumpPtrAllocator - This allocator is useful for containers that need -/// very simple memory allocation strategies. In particular, this just keeps -/// allocating memory, and never deletes it until the entire block is dead. This -/// makes allocation speedy, but must only be used when the trade-off is ok. -class BumpPtrAllocator { - BumpPtrAllocator(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION; - void operator=(const BumpPtrAllocator &) LLVM_DELETED_FUNCTION; - - /// SlabSize - Allocate data into slabs of this size unless we get an - /// allocation above SizeThreshold. - size_t SlabSize; - - /// SizeThreshold - For any allocation larger than this threshold, we should - /// allocate a separate slab. - size_t SizeThreshold; - - /// \brief the default allocator used if one is not provided - MallocSlabAllocator DefaultSlabAllocator; +/// \brief Non-templated base class for the \c BumpPtrAllocatorImpl template. +class BumpPtrAllocatorBase { +public: + void Deallocate(const void * /*Ptr*/) {} + void PrintStats() const; - /// Allocator - The underlying allocator we use to get slabs of memory. This - /// defaults to MallocSlabAllocator, which wraps malloc, but it could be - /// changed to use a custom allocator. - SlabAllocator &Allocator; + /// \brief Returns the total physical memory allocated by this allocator. + size_t getTotalMemory() const; - /// CurSlab - The slab that we are currently allocating into. - /// +protected: + /// \brief The slab that we are currently allocating into. MemSlab *CurSlab; - /// CurPtr - The current pointer into the current slab. This points to the - /// next free byte in the slab. - char *CurPtr; - - /// End - The end of the current slab. + /// \brief How many bytes we've allocated. /// - char *End; - - /// BytesAllocated - This field tracks how many bytes we've allocated, so - /// that we can compute how much space was wasted. + /// Used so that we can compute how much space was wasted. size_t BytesAllocated; - /// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should - /// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and - /// AlignPtr(8, 4) == 8. - static char *AlignPtr(char *Ptr, size_t Alignment); - - /// StartNewSlab - Allocate a new slab and move the bump pointers over into - /// the new slab. Modifies CurPtr and End. - void StartNewSlab(); + BumpPtrAllocatorBase() : CurSlab(0), BytesAllocated(0) {} +}; - /// DeallocateSlabs - Deallocate all memory slabs after and including this - /// one. - void DeallocateSlabs(MemSlab *Slab); +/// \brief Allocate memory in an ever growing pool, as if by bump-pointer. +/// +/// This isn't strictly a bump-pointer allocator as it uses backing slabs of +/// memory rather than relying on boundless contiguous heap. However, it has +/// bump-pointer semantics in that is a monotonically growing pool of memory +/// where every allocation is found by merely allocating the next N bytes in +/// the slab, or the next N bytes in the next slab. +/// +/// Note that this also has a threshold for forcing allocations above a certain +/// size into their own slab. +template <size_t SlabSize = 4096, size_t SizeThreshold = SlabSize> +class BumpPtrAllocatorImpl : public BumpPtrAllocatorBase { + BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION; + void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION; - template<typename T> friend class SpecificBumpPtrAllocator; public: - BumpPtrAllocator(size_t size = 4096, size_t threshold = 4096); - BumpPtrAllocator(size_t size, size_t threshold, SlabAllocator &allocator); - ~BumpPtrAllocator(); - - /// Reset - Deallocate all but the current slab and reset the current pointer + static_assert(SizeThreshold <= SlabSize, + "The SizeThreshold must be at most the SlabSize to ensure " + "that objects larger than a slab go into their own memory " + "allocation."); + + BumpPtrAllocatorImpl() + : Allocator(DefaultSlabAllocator), NumSlabs(0) {} + BumpPtrAllocatorImpl(SlabAllocator &Allocator) + : Allocator(Allocator), NumSlabs(0) {} + ~BumpPtrAllocatorImpl() { DeallocateSlabs(CurSlab); } + + /// \brief Deallocate all but the current slab and reset the current pointer /// to the beginning of it, freeing all memory allocated so far. - void Reset(); + void Reset() { + if (!CurSlab) + return; + DeallocateSlabs(CurSlab->NextPtr); + CurSlab->NextPtr = 0; + CurPtr = (char *)(CurSlab + 1); + End = ((char *)CurSlab) + CurSlab->Size; + BytesAllocated = 0; + } - /// Allocate - Allocate space at the specified alignment. - /// - void *Allocate(size_t Size, size_t Alignment); + /// \brief Allocate space at the specified alignment. + void *Allocate(size_t Size, size_t Alignment) { + if (!CurSlab) // Start a new slab if we haven't allocated one already. + StartNewSlab(); + + // Keep track of how many bytes we've allocated. + BytesAllocated += Size; + + // 0-byte alignment means 1-byte alignment. + if (Alignment == 0) + Alignment = 1; + + // Allocate the aligned space, going forwards from CurPtr. + char *Ptr = alignPtr(CurPtr, Alignment); + + // Check if we can hold it. + if (Ptr + Size <= End) { + CurPtr = Ptr + Size; + // Update the allocation point of this memory block in MemorySanitizer. + // Without this, MemorySanitizer messages for values originated from here + // will point to the allocation of the entire slab. + __msan_allocated_memory(Ptr, Size); + return Ptr; + } - /// Allocate space, but do not construct, one object. - /// - template <typename T> - T *Allocate() { - return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment)); + // If Size is really big, allocate a separate slab for it. + size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1; + if (PaddedSize > SizeThreshold) { + ++NumSlabs; + MemSlab *NewSlab = Allocator.Allocate(PaddedSize); + + // Put the new slab after the current slab, since we are not allocating + // into it. + NewSlab->NextPtr = CurSlab->NextPtr; + CurSlab->NextPtr = NewSlab; + + Ptr = alignPtr((char *)(NewSlab + 1), Alignment); + assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size); + __msan_allocated_memory(Ptr, Size); + return Ptr; + } + + // Otherwise, start a new slab and try again. + StartNewSlab(); + Ptr = alignPtr(CurPtr, Alignment); + CurPtr = Ptr + Size; + assert(CurPtr <= End && "Unable to allocate memory!"); + __msan_allocated_memory(Ptr, Size); + return Ptr; } - /// Allocate space for an array of objects. This does not construct the - /// objects though. - template <typename T> - T *Allocate(size_t Num) { - return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment)); + /// \brief Allocate space for one object without constructing it. + template <typename T> T *Allocate() { + return static_cast<T *>(Allocate(sizeof(T), AlignOf<T>::Alignment)); } - /// Allocate space for a specific count of elements and with a specified - /// alignment. - template <typename T> - T *Allocate(size_t Num, size_t Alignment) { + /// \brief Allocate space for an array of objects without constructing them. + template <typename T> T *Allocate(size_t Num) { + return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment)); + } + + /// \brief Allocate space for an array of objects with the specified alignment + /// and without constructing them. + template <typename T> T *Allocate(size_t Num, size_t Alignment) { // Round EltSize up to the specified alignment. - size_t EltSize = (sizeof(T)+Alignment-1)&(-Alignment); - return static_cast<T*>(Allocate(Num * EltSize, Alignment)); + size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment); + return static_cast<T *>(Allocate(Num * EltSize, Alignment)); } - void Deallocate(const void * /*Ptr*/) {} + size_t GetNumSlabs() const { return NumSlabs; } - unsigned GetNumSlabs() const; +private: + /// \brief The default allocator used if one is not provided. + MallocSlabAllocator DefaultSlabAllocator; - void PrintStats() const; - - /// Compute the total physical memory allocated by this allocator. - size_t getTotalMemory() const; + /// \brief The underlying allocator we use to get slabs of memory. + /// + /// This defaults to MallocSlabAllocator, which wraps malloc, but it could be + /// changed to use a custom allocator. + SlabAllocator &Allocator; + + /// \brief The current pointer into the current slab. + /// + /// This points to the next free byte in the slab. + char *CurPtr; + + /// \brief The end of the current slab. + char *End; + + /// \brief How many slabs we've allocated. + /// + /// Used to scale the size of each slab and reduce the number of allocations + /// for extremely heavy memory use scenarios. + size_t NumSlabs; + + /// \brief Allocate a new slab and move the bump pointers over into the new + /// slab, modifying CurPtr and End. + void StartNewSlab() { + ++NumSlabs; + // Scale the actual allocated slab size based on the number of slabs + // allocated. Every 128 slabs allocated, we double the allocated size to + // reduce allocation frequency, but saturate at multiplying the slab size by + // 2^30. + // FIXME: Currently, this count includes special slabs for objects above the + // size threshold. That will be fixed in a subsequent commit to make the + // growth even more predictable. + size_t AllocatedSlabSize = + SlabSize * ((size_t)1 << std::min<size_t>(30, NumSlabs / 128)); + + MemSlab *NewSlab = Allocator.Allocate(AllocatedSlabSize); + NewSlab->NextPtr = CurSlab; + CurSlab = NewSlab; + CurPtr = (char *)(CurSlab + 1); + End = ((char *)CurSlab) + CurSlab->Size; + } + + /// \brief Deallocate all memory slabs after and including this one. + void DeallocateSlabs(MemSlab *Slab) { + while (Slab) { + MemSlab *NextSlab = Slab->NextPtr; +#ifndef NDEBUG + // Poison the memory so stale pointers crash sooner. Note we must + // preserve the Size and NextPtr fields at the beginning. + sys::Memory::setRangeWritable(Slab + 1, Slab->Size - sizeof(MemSlab)); + memset(Slab + 1, 0xCD, Slab->Size - sizeof(MemSlab)); +#endif + Allocator.Deallocate(Slab); + Slab = NextSlab; + --NumSlabs; + } + } + + template <typename T> friend class SpecificBumpPtrAllocator; }; -/// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only -/// elements of one type to be allocated. This allows calling the destructor -/// in DestroyAll() and when the allocator is destroyed. -template <typename T> -class SpecificBumpPtrAllocator { +/// \brief The standard BumpPtrAllocator which just uses the default template +/// paramaters. +typedef BumpPtrAllocatorImpl<> BumpPtrAllocator; + +/// \brief A BumpPtrAllocator that allows only elements of a specific type to be +/// allocated. +/// +/// This allows calling the destructor in DestroyAll() and when the allocator is +/// destroyed. +template <typename T> class SpecificBumpPtrAllocator { BumpPtrAllocator Allocator; + public: - SpecificBumpPtrAllocator(size_t size = 4096, size_t threshold = 4096) - : Allocator(size, threshold) {} - SpecificBumpPtrAllocator(size_t size, size_t threshold, - SlabAllocator &allocator) - : Allocator(size, threshold, allocator) {} - - ~SpecificBumpPtrAllocator() { - DestroyAll(); - } + SpecificBumpPtrAllocator() : Allocator() {} + SpecificBumpPtrAllocator(SlabAllocator &allocator) : Allocator(allocator) {} + + ~SpecificBumpPtrAllocator() { DestroyAll(); } /// Call the destructor of each allocated object and deallocate all but the /// current slab and reset the current pointer to the beginning of it, freeing @@ -206,27 +307,28 @@ public: void DestroyAll() { MemSlab *Slab = Allocator.CurSlab; while (Slab) { - char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr : - (char *)Slab + Slab->Size; - for (char *Ptr = (char*)(Slab+1); Ptr < End; Ptr += sizeof(T)) { - Ptr = Allocator.AlignPtr(Ptr, alignOf<T>()); + char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr + : (char *)Slab + Slab->Size; + for (char *Ptr = (char *)(Slab + 1); Ptr < End; Ptr += sizeof(T)) { + Ptr = alignPtr(Ptr, alignOf<T>()); if (Ptr + sizeof(T) <= End) - reinterpret_cast<T*>(Ptr)->~T(); + reinterpret_cast<T *>(Ptr)->~T(); } Slab = Slab->NextPtr; } Allocator.Reset(); } - /// Allocate space for a specific count of elements. - T *Allocate(size_t num = 1) { - return Allocator.Allocate<T>(num); - } + /// \brief Allocate space for an array of objects without constructing them. + T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); } }; } // end namespace llvm -inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { +template <size_t SlabSize, size_t SizeThreshold> +void * +operator new(size_t Size, + llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &Allocator) { struct S { char c; union { @@ -236,10 +338,12 @@ inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) { void *P; } x; }; - return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size), - offsetof(S, x))); + return Allocator.Allocate( + Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x))); } -inline void operator delete(void *, llvm::BumpPtrAllocator &) {} +template <size_t SlabSize, size_t SizeThreshold> +void operator delete(void *, + llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &) {} #endif // LLVM_SUPPORT_ALLOCATOR_H diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h index c7e0cba..e974332 100644 --- a/include/llvm/Support/ArrayRecycler.h +++ b/include/llvm/Support/ArrayRecycler.h @@ -16,12 +16,11 @@ #define LLVM_SUPPORT_ARRAYRECYCLER_H #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/MathExtras.h" namespace llvm { -class BumpPtrAllocator; - /// Recycle small arrays allocated from a BumpPtrAllocator. /// /// Arrays are allocated in a small number of fixed sizes. For each supported @@ -35,6 +34,9 @@ class ArrayRecycler { FreeList *Next; }; + static_assert(Align >= AlignOf<FreeList>::Alignment, "Object underaligned"); + static_assert(sizeof(T) >= sizeof(FreeList), "Objects are too small"); + // Keep a free list for each array size. SmallVector<FreeList*, 8> Bucket; @@ -53,8 +55,6 @@ class ArrayRecycler { // Add an entry to the free list at Bucket[Idx]. void push(unsigned Idx, T *Ptr) { assert(Ptr && "Cannot recycle NULL pointer"); - assert(sizeof(T) >= sizeof(FreeList) && "Objects are too small"); - assert(Align >= AlignOf<FreeList>::Alignment && "Object underaligned"); FreeList *Entry = reinterpret_cast<FreeList*>(Ptr); if (Idx >= Bucket.size()) Bucket.resize(size_t(Idx) + 1); diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h index 21879e7..dae520b 100644 --- a/include/llvm/Support/BlockFrequency.h +++ b/include/llvm/Support/BlockFrequency.h @@ -25,7 +25,6 @@ class BranchProbability; class BlockFrequency { uint64_t Frequency; - static const int64_t ENTRY_FREQ = 1 << 14; /// \brief Scale the given BlockFrequency by N/D. Return the remainder from /// the division by D. Upon overflow, the routine will saturate and @@ -35,9 +34,6 @@ class BlockFrequency { public: BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { } - /// \brief Returns the frequency of the entry block of the function. - static uint64_t getEntryFrequency() { return ENTRY_FREQ; } - /// \brief Returns the maximum possible frequency, the saturation value. static uint64_t getMaxFrequency() { return -1ULL; } @@ -59,6 +55,9 @@ public: BlockFrequency &operator+=(const BlockFrequency &Freq); const BlockFrequency operator+(const BlockFrequency &Freq) const; + /// \brief Shift block frequency to the right by count digits saturating to 1. + BlockFrequency &operator>>=(const unsigned count); + /// \brief Scale the given BlockFrequency by N/D. Return the remainder from /// the division by D. Upon overflow, the routine will saturate. uint32_t scale(const BranchProbability &Prob); @@ -78,12 +77,8 @@ public: bool operator>=(const BlockFrequency &RHS) const { return Frequency >= RHS.Frequency; } - - void print(raw_ostream &OS) const; }; -raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq); - } #endif diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h deleted file mode 100644 index 74ec726..0000000 --- a/include/llvm/Support/CFG.h +++ /dev/null @@ -1,365 +0,0 @@ -//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines specializations of GraphTraits that allow Function and -// BasicBlock graphs to be treated as proper graphs for generic algorithms. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_CFG_H -#define LLVM_SUPPORT_CFG_H - -#include "llvm/ADT/GraphTraits.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/InstrTypes.h" - -namespace llvm { - -//===----------------------------------------------------------------------===// -// BasicBlock pred_iterator definition -//===----------------------------------------------------------------------===// - -template <class Ptr, class USE_iterator> // Predecessor Iterator -class PredIterator : public std::iterator<std::forward_iterator_tag, - Ptr, ptrdiff_t, Ptr*, Ptr*> { - typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, - Ptr*> super; - typedef PredIterator<Ptr, USE_iterator> Self; - USE_iterator It; - - inline void advancePastNonTerminators() { - // Loop to ignore non terminator uses (for example BlockAddresses). - while (!It.atEnd() && !isa<TerminatorInst>(*It)) - ++It; - } - -public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; - - PredIterator() {} - explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { - advancePastNonTerminators(); - } - inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {} - - inline bool operator==(const Self& x) const { return It == x.It; } - inline bool operator!=(const Self& x) const { return !operator==(x); } - - inline reference operator*() const { - assert(!It.atEnd() && "pred_iterator out of range!"); - return cast<TerminatorInst>(*It)->getParent(); - } - inline pointer *operator->() const { return &operator*(); } - - inline Self& operator++() { // Preincrement - assert(!It.atEnd() && "pred_iterator out of range!"); - ++It; advancePastNonTerminators(); - return *this; - } - - inline Self operator++(int) { // Postincrement - Self tmp = *this; ++*this; return tmp; - } - - /// getOperandNo - Return the operand number in the predecessor's - /// terminator of the successor. - unsigned getOperandNo() const { - return It.getOperandNo(); - } - - /// getUse - Return the operand Use in the predecessor's terminator - /// of the successor. - Use &getUse() const { - return It.getUse(); - } -}; - -typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator; -typedef PredIterator<const BasicBlock, - Value::const_use_iterator> const_pred_iterator; - -inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); } -inline const_pred_iterator pred_begin(const BasicBlock *BB) { - return const_pred_iterator(BB); -} -inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);} -inline const_pred_iterator pred_end(const BasicBlock *BB) { - return const_pred_iterator(BB, true); -} - - - -//===----------------------------------------------------------------------===// -// BasicBlock succ_iterator definition -//===----------------------------------------------------------------------===// - -template <class Term_, class BB_> // Successor Iterator -class SuccIterator : public std::iterator<std::bidirectional_iterator_tag, - BB_, ptrdiff_t, BB_*, BB_*> { - const Term_ Term; - unsigned idx; - typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t, BB_*, - BB_*> super; - typedef SuccIterator<Term_, BB_> Self; - - inline bool index_is_valid(int idx) { - return idx >= 0 && (unsigned) idx < Term->getNumSuccessors(); - } - -public: - typedef typename super::pointer pointer; - typedef typename super::reference reference; - // TODO: This can be random access iterator, only operator[] missing. - - explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator - } - inline SuccIterator(Term_ T, bool) // end iterator - : Term(T) { - if (Term) - idx = Term->getNumSuccessors(); - else - // Term == NULL happens, if a basic block is not fully constructed and - // consequently getTerminator() returns NULL. In this case we construct a - // SuccIterator which describes a basic block that has zero successors. - // Defining SuccIterator for incomplete and malformed CFGs is especially - // useful for debugging. - idx = 0; - } - - inline const Self &operator=(const Self &I) { - assert(Term == I.Term &&"Cannot assign iterators to two different blocks!"); - idx = I.idx; - return *this; - } - - /// getSuccessorIndex - This is used to interface between code that wants to - /// operate on terminator instructions directly. - unsigned getSuccessorIndex() const { return idx; } - - inline bool operator==(const Self& x) const { return idx == x.idx; } - inline bool operator!=(const Self& x) const { return !operator==(x); } - - inline reference operator*() const { return Term->getSuccessor(idx); } - inline pointer operator->() const { return operator*(); } - - inline Self& operator++() { ++idx; return *this; } // Preincrement - - inline Self operator++(int) { // Postincrement - Self tmp = *this; ++*this; return tmp; - } - - inline Self& operator--() { --idx; return *this; } // Predecrement - inline Self operator--(int) { // Postdecrement - Self tmp = *this; --*this; return tmp; - } - - inline bool operator<(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx < x.idx; - } - - inline bool operator<=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx <= x.idx; - } - inline bool operator>=(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx >= x.idx; - } - - inline bool operator>(const Self& x) const { - assert(Term == x.Term && "Cannot compare iterators of different blocks!"); - return idx > x.idx; - } - - inline Self& operator+=(int Right) { - unsigned new_idx = idx + Right; - assert(index_is_valid(new_idx) && "Iterator index out of bound"); - idx = new_idx; - return *this; - } - - inline Self operator+(int Right) { - Self tmp = *this; - tmp += Right; - return tmp; - } - - inline Self& operator-=(int Right) { - return operator+=(-Right); - } - - inline Self operator-(int Right) { - return operator+(-Right); - } - - inline int operator-(const Self& x) { - assert(Term == x.Term && "Cannot work on iterators of different blocks!"); - int distance = idx - x.idx; - return distance; - } - - // This works for read access, however write access is difficult as changes - // to Term are only possible with Term->setSuccessor(idx). Pointers that can - // be modified are not available. - // - // inline pointer operator[](int offset) { - // Self tmp = *this; - // tmp += offset; - // return tmp.operator*(); - // } - - /// Get the source BB of this iterator. - inline BB_ *getSource() { - assert(Term && "Source not available, if basic block was malformed"); - return Term->getParent(); - } -}; - -typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator; -typedef SuccIterator<const TerminatorInst*, - const BasicBlock> succ_const_iterator; - -inline succ_iterator succ_begin(BasicBlock *BB) { - return succ_iterator(BB->getTerminator()); -} -inline succ_const_iterator succ_begin(const BasicBlock *BB) { - return succ_const_iterator(BB->getTerminator()); -} -inline succ_iterator succ_end(BasicBlock *BB) { - return succ_iterator(BB->getTerminator(), true); -} -inline succ_const_iterator succ_end(const BasicBlock *BB) { - return succ_const_iterator(BB->getTerminator(), true); -} - -template <typename T, typename U> struct isPodLike<SuccIterator<T, U> > { - static const bool value = isPodLike<T>::value; -}; - - - -//===--------------------------------------------------------------------===// -// GraphTraits specializations for basic block graphs (CFGs) -//===--------------------------------------------------------------------===// - -// Provide specializations of GraphTraits to be able to treat a function as a -// graph of basic blocks... - -template <> struct GraphTraits<BasicBlock*> { - typedef BasicBlock NodeType; - typedef succ_iterator ChildIteratorType; - - static NodeType *getEntryNode(BasicBlock *BB) { return BB; } - static inline ChildIteratorType child_begin(NodeType *N) { - return succ_begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return succ_end(N); - } -}; - -template <> struct GraphTraits<const BasicBlock*> { - typedef const BasicBlock NodeType; - typedef succ_const_iterator ChildIteratorType; - - static NodeType *getEntryNode(const BasicBlock *BB) { return BB; } - - static inline ChildIteratorType child_begin(NodeType *N) { - return succ_begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return succ_end(N); - } -}; - -// Provide specializations of GraphTraits to be able to treat a function as a -// graph of basic blocks... and to walk it in inverse order. Inverse order for -// a function is considered to be when traversing the predecessor edges of a BB -// instead of the successor edges. -// -template <> struct GraphTraits<Inverse<BasicBlock*> > { - typedef BasicBlock NodeType; - typedef pred_iterator ChildIteratorType; - static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; } - static inline ChildIteratorType child_begin(NodeType *N) { - return pred_begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return pred_end(N); - } -}; - -template <> struct GraphTraits<Inverse<const BasicBlock*> > { - typedef const BasicBlock NodeType; - typedef const_pred_iterator ChildIteratorType; - static NodeType *getEntryNode(Inverse<const BasicBlock*> G) { - return G.Graph; - } - static inline ChildIteratorType child_begin(NodeType *N) { - return pred_begin(N); - } - static inline ChildIteratorType child_end(NodeType *N) { - return pred_end(N); - } -}; - - - -//===--------------------------------------------------------------------===// -// GraphTraits specializations for function basic block graphs (CFGs) -//===--------------------------------------------------------------------===// - -// Provide specializations of GraphTraits to be able to treat a function as a -// graph of basic blocks... these are the same as the basic block iterators, -// except that the root node is implicitly the first node of the function. -// -template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> { - static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); } - - // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef Function::iterator nodes_iterator; - static nodes_iterator nodes_begin(Function *F) { return F->begin(); } - static nodes_iterator nodes_end (Function *F) { return F->end(); } - static size_t size (Function *F) { return F->size(); } -}; -template <> struct GraphTraits<const Function*> : - public GraphTraits<const BasicBlock*> { - static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();} - - // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - typedef Function::const_iterator nodes_iterator; - static nodes_iterator nodes_begin(const Function *F) { return F->begin(); } - static nodes_iterator nodes_end (const Function *F) { return F->end(); } - static size_t size (const Function *F) { return F->size(); } -}; - - -// Provide specializations of GraphTraits to be able to treat a function as a -// graph of basic blocks... and to walk it in inverse order. Inverse order for -// a function is considered to be when traversing the predecessor edges of a BB -// instead of the successor edges. -// -template <> struct GraphTraits<Inverse<Function*> > : - public GraphTraits<Inverse<BasicBlock*> > { - static NodeType *getEntryNode(Inverse<Function*> G) { - return &G.Graph->getEntryBlock(); - } -}; -template <> struct GraphTraits<Inverse<const Function*> > : - public GraphTraits<Inverse<const BasicBlock*> > { - static NodeType *getEntryNode(Inverse<const Function *> G) { - return &G.Graph->getEntryBlock(); - } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index 9cc3989..dca7fc6 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -30,6 +30,9 @@ namespace llvm { namespace COFF { + // The maximum number of sections that a COFF object can have (inclusive). + const int MaxNumberOfSections = 65299; + // The PE signature bytes that follows the DOS stub header. static const char PEMagic[] = { 'P', 'E', '\0', '\0' }; @@ -59,7 +62,7 @@ namespace COFF { IMAGE_FILE_MACHINE_AM33 = 0x13, IMAGE_FILE_MACHINE_AMD64 = 0x8664, IMAGE_FILE_MACHINE_ARM = 0x1C0, - IMAGE_FILE_MACHINE_ARMV7 = 0x1C4, + IMAGE_FILE_MACHINE_ARMNT = 0x1C4, IMAGE_FILE_MACHINE_EBC = 0xEBC, IMAGE_FILE_MACHINE_I386 = 0x14C, IMAGE_FILE_MACHINE_IA64 = 0x200, @@ -138,8 +141,8 @@ namespace COFF { }; enum SymbolSectionNumber { - IMAGE_SYM_DEBUG = -2, - IMAGE_SYM_ABSOLUTE = -1, + IMAGE_SYM_DEBUG = 0xFFFE, + IMAGE_SYM_ABSOLUTE = 0xFFFF, IMAGE_SYM_UNDEFINED = 0 }; @@ -209,6 +212,10 @@ namespace COFF { SCT_COMPLEX_TYPE_SHIFT = 4 }; + enum AuxSymbolType { + IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF = 1 + }; + struct section { char Name[NameSize]; uint32_t VirtualSize; @@ -222,7 +229,7 @@ namespace COFF { uint32_t Characteristics; }; - enum SectionCharacteristics LLVM_ENUM_INT_TYPE(uint32_t) { + enum SectionCharacteristics : uint32_t { SC_Invalid = 0xffffffff, IMAGE_SCN_TYPE_NO_PAD = 0x00000008, @@ -334,7 +341,7 @@ namespace COFF { uint32_t TotalSize; uint32_t PointerToLinenumber; uint32_t PointerToNextFunction; - uint8_t unused[2]; + char unused[2]; }; struct AuxiliarybfAndefSymbol { @@ -369,7 +376,14 @@ namespace COFF { uint32_t CheckSum; uint16_t Number; uint8_t Selection; - uint8_t unused[3]; + char unused[3]; + }; + + struct AuxiliaryCLRToken { + uint8_t AuxType; + uint8_t unused1; + uint32_t SymbolTableIndex; + char unused2[12]; }; union Auxiliary { @@ -450,7 +464,12 @@ namespace COFF { uint32_t AddressOfNewExeHeader; }; - struct PEHeader { + struct PE32Header { + enum { + PE32 = 0x10b, + PE32_PLUS = 0x20b + }; + uint16_t Magic; uint8_t MajorLinkerVersion; uint8_t MinorLinkerVersion; @@ -460,7 +479,7 @@ namespace COFF { uint32_t AddressOfEntryPoint; // RVA uint32_t BaseOfCode; // RVA uint32_t BaseOfData; // RVA - uint64_t ImageBase; + uint32_t ImageBase; uint32_t SectionAlignment; uint32_t FileAlignment; uint16_t MajorOperatingSystemVersion; @@ -475,10 +494,10 @@ namespace COFF { uint32_t CheckSum; uint16_t Subsystem; uint16_t DLLCharacteristics; - uint64_t SizeOfStackReserve; - uint64_t SizeOfStackCommit; - uint64_t SizeOfHeapReserve; - uint64_t SizeOfHeapCommit; + uint32_t SizeOfStackReserve; + uint32_t SizeOfStackCommit; + uint32_t SizeOfHeapReserve; + uint32_t SizeOfHeapCommit; uint32_t LoaderFlags; uint32_t NumberOfRvaAndSize; }; @@ -526,6 +545,8 @@ namespace COFF { }; enum DLLCharacteristics { + /// ASLR with 64 bit address space. + IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020, /// DLL can be relocated at load time. IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE = 0x0040, /// Code integrity checks are enforced. @@ -611,6 +632,17 @@ namespace COFF { } }; + enum CodeViewLineTableIdentifiers { + DEBUG_SECTION_MAGIC = 0x4, + DEBUG_LINE_TABLE_SUBSECTION = 0xF2, + DEBUG_STRING_TABLE_SUBSECTION = 0xF3, + DEBUG_INDEX_SUBSECTION = 0xF4 + }; + + inline bool isReservedSectionNumber(int N) { + return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections; + } + } // End namespace COFF. } // End namespace llvm. diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h deleted file mode 100644 index 2a1c5ca..0000000 --- a/include/llvm/Support/CallSite.h +++ /dev/null @@ -1,330 +0,0 @@ -//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the CallSite class, which is a handy wrapper for code that -// wants to treat Call and Invoke instructions in a generic way. When in non- -// mutation context (e.g. an analysis) ImmutableCallSite should be used. -// Finally, when some degree of customization is necessary between these two -// extremes, CallSiteBase<> can be supplied with fine-tuned parameters. -// -// NOTE: These classes are supposed to have "value semantics". So they should be -// passed by value, not by reference; they should not be "new"ed or "delete"d. -// They are efficiently copyable, assignable and constructable, with cost -// equivalent to copying a pointer (notice that they have only a single data -// member). The internal representation carries a flag which indicates which of -// the two variants is enclosed. This allows for cheaper checks when various -// accessors of CallSite are employed. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_CALLSITE_H -#define LLVM_SUPPORT_CALLSITE_H - -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/IR/Attributes.h" -#include "llvm/IR/CallingConv.h" -#include "llvm/IR/Instructions.h" - -namespace llvm { - -class CallInst; -class InvokeInst; - -template <typename FunTy = const Function, - typename ValTy = const Value, - typename UserTy = const User, - typename InstrTy = const Instruction, - typename CallTy = const CallInst, - typename InvokeTy = const InvokeInst, - typename IterTy = User::const_op_iterator> -class CallSiteBase { -protected: - PointerIntPair<InstrTy*, 1, bool> I; -public: - CallSiteBase() : I(0, false) {} - CallSiteBase(CallTy *CI) : I(CI, true) { assert(CI); } - CallSiteBase(InvokeTy *II) : I(II, false) { assert(II); } - CallSiteBase(ValTy *II) { *this = get(II); } -protected: - /// CallSiteBase::get - This static method is sort of like a constructor. It - /// will create an appropriate call site for a Call or Invoke instruction, but - /// it can also create a null initialized CallSiteBase object for something - /// which is NOT a call site. - /// - static CallSiteBase get(ValTy *V) { - if (InstrTy *II = dyn_cast<InstrTy>(V)) { - if (II->getOpcode() == Instruction::Call) - return CallSiteBase(static_cast<CallTy*>(II)); - else if (II->getOpcode() == Instruction::Invoke) - return CallSiteBase(static_cast<InvokeTy*>(II)); - } - return CallSiteBase(); - } -public: - /// isCall - true if a CallInst is enclosed. - /// Note that !isCall() does not mean it is an InvokeInst enclosed, - /// it also could signify a NULL Instruction pointer. - bool isCall() const { return I.getInt(); } - - /// isInvoke - true if a InvokeInst is enclosed. - /// - bool isInvoke() const { return getInstruction() && !I.getInt(); } - - InstrTy *getInstruction() const { return I.getPointer(); } - InstrTy *operator->() const { return I.getPointer(); } - LLVM_EXPLICIT operator bool() const { return I.getPointer(); } - - /// getCalledValue - Return the pointer to function that is being called. - /// - ValTy *getCalledValue() const { - assert(getInstruction() && "Not a call or invoke instruction!"); - return *getCallee(); - } - - /// getCalledFunction - Return the function being called if this is a direct - /// call, otherwise return null (if it's an indirect call). - /// - FunTy *getCalledFunction() const { - return dyn_cast<FunTy>(getCalledValue()); - } - - /// setCalledFunction - Set the callee to the specified value. - /// - void setCalledFunction(Value *V) { - assert(getInstruction() && "Not a call or invoke instruction!"); - *getCallee() = V; - } - - /// isCallee - Determine whether the passed iterator points to the - /// callee operand's Use. - /// - bool isCallee(value_use_iterator<UserTy> UI) const { - return getCallee() == &UI.getUse(); - } - - ValTy *getArgument(unsigned ArgNo) const { - assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); - return *(arg_begin() + ArgNo); - } - - void setArgument(unsigned ArgNo, Value* newVal) { - assert(getInstruction() && "Not a call or invoke instruction!"); - assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!"); - getInstruction()->setOperand(ArgNo, newVal); - } - - /// Given a value use iterator, returns the argument that corresponds to it. - /// Iterator must actually correspond to an argument. - unsigned getArgumentNo(value_use_iterator<UserTy> I) const { - assert(getInstruction() && "Not a call or invoke instruction!"); - assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end() - && "Argument # out of range!"); - return &I.getUse() - arg_begin(); - } - - /// arg_iterator - The type of iterator to use when looping over actual - /// arguments at this call site. - typedef IterTy arg_iterator; - - /// arg_begin/arg_end - Return iterators corresponding to the actual argument - /// list for a call site. - IterTy arg_begin() const { - assert(getInstruction() && "Not a call or invoke instruction!"); - // Skip non-arguments - return (*this)->op_begin(); - } - - IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); } - bool arg_empty() const { return arg_end() == arg_begin(); } - unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); } - - /// getType - Return the type of the instruction that generated this call site - /// - Type *getType() const { return (*this)->getType(); } - - /// getCaller - Return the caller function for this call site - /// - FunTy *getCaller() const { return (*this)->getParent()->getParent(); } - -#define CALLSITE_DELEGATE_GETTER(METHOD) \ - InstrTy *II = getInstruction(); \ - return isCall() \ - ? cast<CallInst>(II)->METHOD \ - : cast<InvokeInst>(II)->METHOD - -#define CALLSITE_DELEGATE_SETTER(METHOD) \ - InstrTy *II = getInstruction(); \ - if (isCall()) \ - cast<CallInst>(II)->METHOD; \ - else \ - cast<InvokeInst>(II)->METHOD - - /// getCallingConv/setCallingConv - get or set the calling convention of the - /// call. - CallingConv::ID getCallingConv() const { - CALLSITE_DELEGATE_GETTER(getCallingConv()); - } - void setCallingConv(CallingConv::ID CC) { - CALLSITE_DELEGATE_SETTER(setCallingConv(CC)); - } - - /// getAttributes/setAttributes - get or set the parameter attributes of - /// the call. - const AttributeSet &getAttributes() const { - CALLSITE_DELEGATE_GETTER(getAttributes()); - } - void setAttributes(const AttributeSet &PAL) { - CALLSITE_DELEGATE_SETTER(setAttributes(PAL)); - } - - /// \brief Return true if this function has the given attribute. - bool hasFnAttr(Attribute::AttrKind A) const { - CALLSITE_DELEGATE_GETTER(hasFnAttr(A)); - } - - /// \brief Return true if the call or the callee has the given attribute. - bool paramHasAttr(unsigned i, Attribute::AttrKind A) const { - CALLSITE_DELEGATE_GETTER(paramHasAttr(i, A)); - } - - /// @brief Extract the alignment for a call or parameter (0=unknown). - uint16_t getParamAlignment(uint16_t i) const { - CALLSITE_DELEGATE_GETTER(getParamAlignment(i)); - } - - /// \brief Return true if the call should not be treated as a call to a - /// builtin. - bool isNoBuiltin() const { - CALLSITE_DELEGATE_GETTER(isNoBuiltin()); - } - - /// @brief Return true if the call should not be inlined. - bool isNoInline() const { - CALLSITE_DELEGATE_GETTER(isNoInline()); - } - void setIsNoInline(bool Value = true) { - CALLSITE_DELEGATE_SETTER(setIsNoInline(Value)); - } - - /// @brief Determine if the call does not access memory. - bool doesNotAccessMemory() const { - CALLSITE_DELEGATE_GETTER(doesNotAccessMemory()); - } - void setDoesNotAccessMemory() { - CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory()); - } - - /// @brief Determine if the call does not access or only reads memory. - bool onlyReadsMemory() const { - CALLSITE_DELEGATE_GETTER(onlyReadsMemory()); - } - void setOnlyReadsMemory() { - CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory()); - } - - /// @brief Determine if the call cannot return. - bool doesNotReturn() const { - CALLSITE_DELEGATE_GETTER(doesNotReturn()); - } - void setDoesNotReturn() { - CALLSITE_DELEGATE_SETTER(setDoesNotReturn()); - } - - /// @brief Determine if the call cannot unwind. - bool doesNotThrow() const { - CALLSITE_DELEGATE_GETTER(doesNotThrow()); - } - void setDoesNotThrow() { - CALLSITE_DELEGATE_SETTER(setDoesNotThrow()); - } - -#undef CALLSITE_DELEGATE_GETTER -#undef CALLSITE_DELEGATE_SETTER - - /// @brief Determine whether this argument is not captured. - bool doesNotCapture(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::NoCapture); - } - - /// @brief Determine whether this argument is passed by value. - bool isByValArgument(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ByVal); - } - - bool doesNotAccessMemory(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ReadNone); - } - - bool onlyReadsMemory(unsigned ArgNo) const { - return paramHasAttr(ArgNo + 1, Attribute::ReadOnly) || - paramHasAttr(ArgNo + 1, Attribute::ReadNone); - } - - /// hasArgument - Returns true if this CallSite passes the given Value* as an - /// argument to the called function. - bool hasArgument(const Value *Arg) const { - for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; - ++AI) - if (AI->get() == Arg) - return true; - return false; - } - -private: - unsigned getArgumentEndOffset() const { - if (isCall()) - return 1; // Skip Callee - else - return 3; // Skip BB, BB, Callee - } - - IterTy getCallee() const { - if (isCall()) // Skip Callee - return cast<CallInst>(getInstruction())->op_end() - 1; - else // Skip BB, BB, Callee - return cast<InvokeInst>(getInstruction())->op_end() - 3; - } -}; - -class CallSite : public CallSiteBase<Function, Value, User, Instruction, - CallInst, InvokeInst, User::op_iterator> { - typedef CallSiteBase<Function, Value, User, Instruction, - CallInst, InvokeInst, User::op_iterator> Base; -public: - CallSite() {} - CallSite(Base B) : Base(B) {} - CallSite(Value* V) : Base(V) {} - CallSite(CallInst *CI) : Base(CI) {} - CallSite(InvokeInst *II) : Base(II) {} - CallSite(Instruction *II) : Base(II) {} - - bool operator==(const CallSite &CS) const { return I == CS.I; } - bool operator!=(const CallSite &CS) const { return I != CS.I; } - bool operator<(const CallSite &CS) const { - return getInstruction() < CS.getInstruction(); - } - -private: - User::op_iterator getCallee() const; -}; - -/// ImmutableCallSite - establish a view to a call site for examination -class ImmutableCallSite : public CallSiteBase<> { - typedef CallSiteBase<> Base; -public: - ImmutableCallSite(const Value* V) : Base(V) {} - ImmutableCallSite(const CallInst *CI) : Base(CI) {} - ImmutableCallSite(const InvokeInst *II) : Base(II) {} - ImmutableCallSite(const Instruction *II) : Base(II) {} - ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {} -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index d70acbf..689f590 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_CASTING_H #define LLVM_SUPPORT_CASTING_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include <cassert> @@ -58,11 +59,8 @@ struct isa_impl { /// \brief Always allow upcasts, and perform no dynamic check for them. template <typename To, typename From> -struct isa_impl<To, From, - typename enable_if< - llvm::is_base_of<To, From> - >::type - > { +struct isa_impl< + To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> { static inline bool doit(const From &) { return true; } }; @@ -131,7 +129,7 @@ struct isa_impl_wrap<To, FromTy, FromTy> { // if (isa<Type>(myVal)) { ... } // template <class X, class Y> -inline bool isa(const Y &Val) { +LLVM_ATTRIBUTE_UNUSED_RESULT inline bool isa(const Y &Val) { return isa_impl_wrap<X, const Y, typename simplify_type<const Y>::SimpleType>::doit(Val); } @@ -208,7 +206,7 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { template <class X> struct is_simple_type { static const bool value = - is_same<X, typename simplify_type<X>::SimpleType>::value; + std::is_same<X, typename simplify_type<X>::SimpleType>::value; }; // cast<X> - Return the argument parameter cast to the specified type. This @@ -219,8 +217,8 @@ template <class X> struct is_simple_type { // cast<Instruction>(myVal)->getParent() // template <class X, class Y> -inline typename enable_if_c<!is_simple_type<Y>::value, - typename cast_retty<X, const Y>::ret_type>::type +inline typename std::enable_if<!is_simple_type<Y>::value, + typename cast_retty<X, const Y>::ret_type>::type cast(const Y &Val) { assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!"); return cast_convert_val< @@ -245,7 +243,8 @@ inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) { // accepted. // template <class X, class Y> -inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type +cast_or_null(Y *Val) { if (Val == 0) return 0; assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!"); return cast<X>(Val); @@ -261,19 +260,21 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) { // template <class X, class Y> -inline typename enable_if_c<!is_simple_type<Y>::value, - typename cast_retty<X, const Y>::ret_type>::type +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< + !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type dyn_cast(const Y &Val) { return isa<X>(Val) ? cast<X>(Val) : 0; } template <class X, class Y> -inline typename cast_retty<X, Y>::ret_type dyn_cast(Y &Val) { +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type +dyn_cast(Y &Val) { return isa<X>(Val) ? cast<X>(Val) : 0; } template <class X, class Y> -inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type +dyn_cast(Y *Val) { return isa<X>(Val) ? cast<X>(Val) : 0; } @@ -281,7 +282,8 @@ inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) { // value is accepted. // template <class X, class Y> -inline typename cast_retty<X, Y*>::ret_type dyn_cast_or_null(Y *Val) { +LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type +dyn_cast_or_null(Y *Val) { return (Val && isa<X>(Val)) ? cast<X>(Val) : 0; } diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 4efb6a6..e49a97e 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -21,10 +21,9 @@ #define LLVM_SUPPORT_COMMANDLINE_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Twine.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/type_traits.h" #include <cassert> #include <climits> #include <cstdarg> @@ -149,8 +148,8 @@ private: public: OptionCategory(const char *const Name, const char *const Description = 0) : Name(Name), Description(Description) { registerCategory(); } - const char *getName() { return Name; } - const char *getDescription() { return Description; } + const char *getName() const { return Name; } + const char *getDescription() const { return Description; } }; // The general Option Category (used as default category). @@ -249,6 +248,12 @@ public: // void addArgument(); + /// Unregisters this option from the CommandLine system. + /// + /// This option must have been the last option registered. + /// For testing purposes only. + void removeArgument(); + Option *getNextRegisteredOption() const { return NextRegistered; } // Return the width of the option tag for printing... @@ -374,7 +379,9 @@ struct OptionValueBase : public GenericOptionValue { bool compare(const DataType &/*V*/) const { return false; } - virtual bool compare(const GenericOptionValue& /*V*/) const { return false; } + bool compare(const GenericOptionValue& /*V*/) const override { + return false; + } }; // Simple copy of the option value. @@ -398,7 +405,7 @@ public: return Valid && (Value != V); } - virtual bool compare(const GenericOptionValue &V) const { + bool compare(const GenericOptionValue &V) const override { const OptionValueCopy<DataType> &VC = static_cast< const OptionValueCopy<DataType>& >(V); if (!VC.hasValue()) return false; @@ -414,7 +421,7 @@ struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { // Top-level option class. template<class DataType> -struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> { +struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> { OptionValue() {} OptionValue(const DataType& V) { @@ -444,7 +451,7 @@ struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> { return *this; } private: - virtual void anchor(); + void anchor() override; }; template<> @@ -461,7 +468,7 @@ struct OptionValue<std::string> : OptionValueCopy<std::string> { return *this; } private: - virtual void anchor(); + void anchor() override; }; //===----------------------------------------------------------------------===// @@ -640,14 +647,14 @@ public: typedef DataType parser_data_type; // Implement virtual functions needed by generic_parser_base - unsigned getNumOptions() const { return unsigned(Values.size()); } - const char *getOption(unsigned N) const { return Values[N].Name; } - const char *getDescription(unsigned N) const { + unsigned getNumOptions() const override { return unsigned(Values.size()); } + const char *getOption(unsigned N) const override { return Values[N].Name; } + const char *getDescription(unsigned N) const override { return Values[N].HelpStr; } // getOptionValue - Return the value of option name N. - virtual const GenericOptionValue &getOptionValue(unsigned N) const { + const GenericOptionValue &getOptionValue(unsigned N) const override { return Values[N].V; } @@ -756,13 +763,13 @@ public: } // getValueName - Do not print =<value> at all. - virtual const char *getValueName() const { return 0; } + const char *getValueName() const override { return 0; } void printOptionDiff(const Option &O, bool V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); @@ -780,13 +787,13 @@ public: } // getValueName - Do not print =<value> at all. - virtual const char *getValueName() const { return 0; } + const char *getValueName() const override { return 0; } void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>); @@ -801,13 +808,13 @@ public: bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val); // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "int"; } + const char *getValueName() const override { return "int"; } void printOptionDiff(const Option &O, int V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>); @@ -823,13 +830,13 @@ public: bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val); // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "uint"; } + const char *getValueName() const override { return "uint"; } void printOptionDiff(const Option &O, unsigned V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>); @@ -845,13 +852,13 @@ public: unsigned long long &Val); // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "uint"; } + const char *getValueName() const override { return "uint"; } void printOptionDiff(const Option &O, unsigned long long V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>); @@ -866,13 +873,13 @@ public: bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val); // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "number"; } + const char *getValueName() const override { return "number"; } void printOptionDiff(const Option &O, double V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>); @@ -887,13 +894,13 @@ public: bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val); // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "number"; } + const char *getValueName() const override { return "number"; } void printOptionDiff(const Option &O, float V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>); @@ -911,13 +918,13 @@ public: } // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "string"; } + const char *getValueName() const override { return "string"; } void printOptionDiff(const Option &O, StringRef V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>); @@ -935,13 +942,13 @@ public: } // getValueName - Overload in subclass to provide a better default value. - virtual const char *getValueName() const { return "char"; } + const char *getValueName() const override { return "char"; } void printOptionDiff(const Option &O, char V, OptVal Default, size_t GlobalWidth) const; // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); + void anchor() override; }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>); @@ -1020,8 +1027,8 @@ template<> struct applicator<const char*> { }; template<> struct applicator<NumOccurrencesFlag> { - static void opt(NumOccurrencesFlag NO, Option &O) { - O.setNumOccurrencesFlag(NO); + static void opt(NumOccurrencesFlag N, Option &O) { + O.setNumOccurrencesFlag(N); } }; template<> struct applicator<ValueExpected> { @@ -1055,7 +1062,7 @@ class opt_storage { DataType *Location; // Where to store the object... OptionValue<DataType> Default; - void check() const { + void check_location() const { assert(Location != 0 && "cl::location(...) not specified for a command " "line option with external storage, " "or cl::init specified before cl::location()!!"); @@ -1073,14 +1080,14 @@ public: template<class T> void setValue(const T &V, bool initial = false) { - check(); + check_location(); *Location = V; if (initial) Default = V; } - DataType &getValue() { check(); return *Location; } - const DataType &getValue() const { check(); return *Location; } + DataType &getValue() { check_location(); return *Location; } + const DataType &getValue() const { check_location(); return *Location; } operator DataType() const { return this->getValue(); } @@ -1148,11 +1155,11 @@ template <class DataType, bool ExternalStorage = false, class ParserClass = parser<DataType> > class opt : public Option, public opt_storage<DataType, ExternalStorage, - is_class<DataType>::value> { + std::is_class<DataType>::value> { ParserClass Parser; - virtual bool handleOccurrence(unsigned pos, StringRef ArgName, - StringRef Arg) { + bool handleOccurrence(unsigned pos, StringRef ArgName, + StringRef Arg) override { typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -1162,20 +1169,20 @@ class opt : public Option, return false; } - virtual enum ValueExpected getValueExpectedFlagDefault() const { + enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } // Forward printing stuff to the parser... - virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);} - virtual void printOptionInfo(size_t GlobalWidth) const { + size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } - virtual void printOptionValue(size_t GlobalWidth, bool Force) const { + void printOptionValue(size_t GlobalWidth, bool Force) const override { if (Force || this->getDefault().compare(this->getValue())) { cl::printOptionDiff<ParserClass>( *this, Parser, this->getValue(), this->getDefault(), GlobalWidth); @@ -1322,14 +1329,15 @@ class list : public Option, public list_storage<DataType, Storage> { std::vector<unsigned> Positions; ParserClass Parser; - virtual enum ValueExpected getValueExpectedFlagDefault() const { + enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } - virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){ + bool handleOccurrence(unsigned pos, StringRef ArgName, + StringRef Arg) override { typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -1341,13 +1349,14 @@ class list : public Option, public list_storage<DataType, Storage> { } // Forward printing stuff to the parser... - virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);} - virtual void printOptionInfo(size_t GlobalWidth) const { + size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } // Unimplemented: list options don't currently store their default value. - virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + void printOptionValue(size_t /*GlobalWidth*/, + bool /*Force*/) const override {} void done() { addArgument(); @@ -1524,14 +1533,15 @@ class bits : public Option, public bits_storage<DataType, Storage> { std::vector<unsigned> Positions; ParserClass Parser; - virtual enum ValueExpected getValueExpectedFlagDefault() const { + enum ValueExpected getValueExpectedFlagDefault() const override { return Parser.getValueExpectedFlagDefault(); } - virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) { + void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override { return Parser.getExtraOptionNames(OptionNames); } - virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){ + bool handleOccurrence(unsigned pos, StringRef ArgName, + StringRef Arg) override { typename ParserClass::parser_data_type Val = typename ParserClass::parser_data_type(); if (Parser.parse(*this, ArgName, Arg, Val)) @@ -1543,13 +1553,14 @@ class bits : public Option, public bits_storage<DataType, Storage> { } // Forward printing stuff to the parser... - virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);} - virtual void printOptionInfo(size_t GlobalWidth) const { + size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);} + void printOptionInfo(size_t GlobalWidth) const override { Parser.printOptionInfo(*this, GlobalWidth); } // Unimplemented: bits options don't currently store their default values. - virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + void printOptionValue(size_t /*GlobalWidth*/, + bool /*Force*/) const override {} void done() { addArgument(); @@ -1634,17 +1645,21 @@ public: class alias : public Option { Option *AliasFor; - virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, - StringRef Arg) LLVM_OVERRIDE { + bool handleOccurrence(unsigned pos, StringRef /*ArgName*/, + StringRef Arg) override { return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); } // Handle printing stuff... - virtual size_t getOptionWidth() const LLVM_OVERRIDE; - virtual void printOptionInfo(size_t GlobalWidth) const LLVM_OVERRIDE; + size_t getOptionWidth() const override; + void printOptionInfo(size_t GlobalWidth) const override; // Aliases do not need to print their values. - virtual void printOptionValue(size_t /*GlobalWidth*/, - bool /*Force*/) const LLVM_OVERRIDE {} + void printOptionValue(size_t /*GlobalWidth*/, + bool /*Force*/) const override {} + + ValueExpected getValueExpectedFlagDefault() const override { + return AliasFor->getValueExpectedFlag(); + } void done() { if (!hasArgStr()) diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 860f43e..1edcd45 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -21,6 +21,10 @@ # define __has_feature(x) 0 #endif +#ifndef __has_extension +# define __has_extension(x) 0 +#endif + #ifndef __has_attribute # define __has_attribute(x) 0 #endif @@ -40,15 +44,21 @@ # endif #endif -/// \brief Does the compiler support r-value references? -/// This implies that <utility> provides the one-argument std::move; it -/// does not imply the existence of any other C++ library features. -#if (__has_feature(cxx_rvalue_references) \ - || defined(__GXX_EXPERIMENTAL_CXX0X__) \ - || (defined(_MSC_VER) && _MSC_VER >= 1600)) -#define LLVM_HAS_RVALUE_REFERENCES 1 +/// \macro LLVM_MSC_PREREQ +/// \brief Is the compiler MSVC of at least the specified version? +/// The common \param version values to check for are: +/// * 1700: Microsoft Visual Studio 2012 / 11.0 +/// * 1800: Microsoft Visual Studio 2013 / 12.0 +#ifdef _MSC_VER +#define LLVM_MSC_PREREQ(version) (_MSC_VER >= (version)) + +// We require at least MSVC 2012. +#if !LLVM_MSC_PREREQ(1700) +#error LLVM requires at least MSVC 2012. +#endif + #else -#define LLVM_HAS_RVALUE_REFERENCES 0 +#define LLVM_MSC_PREREQ(version) 0 #endif /// \brief Does the compiler support r-value reference *this? @@ -63,51 +73,16 @@ #define LLVM_HAS_RVALUE_REFERENCE_THIS 0 #endif -/// \macro LLVM_HAS_CXX11_TYPETRAITS -/// \brief Does the compiler have the C++11 type traits. -/// -/// #include <type_traits> -/// -/// * enable_if -/// * {true,false}_type -/// * is_constructible -/// * etc... -#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ - || (defined(_MSC_VER) && _MSC_VER >= 1700) -#define LLVM_HAS_CXX11_TYPETRAITS 1 -#else -#define LLVM_HAS_CXX11_TYPETRAITS 0 -#endif - -/// \macro LLVM_HAS_CXX11_STDLIB -/// \brief Does the compiler have the C++11 standard library. -/// -/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS -#if defined(__GXX_EXPERIMENTAL_CXX0X__) \ - || (defined(_MSC_VER) && _MSC_VER >= 1700) -#define LLVM_HAS_CXX11_STDLIB 1 -#else -#define LLVM_HAS_CXX11_STDLIB 0 -#endif - /// \macro LLVM_HAS_VARIADIC_TEMPLATES /// \brief Does this compiler support variadic templates. /// /// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward. -#if __has_feature(cxx_variadic_templates) +#if __has_feature(cxx_variadic_templates) || LLVM_MSC_PREREQ(1800) # define LLVM_HAS_VARIADIC_TEMPLATES 1 #else # define LLVM_HAS_VARIADIC_TEMPLATES 0 #endif -/// llvm_move - Expands to ::std::move if the compiler supports -/// r-value references; otherwise, expands to the argument. -#if LLVM_HAS_RVALUE_REFERENCES -#define llvm_move(value) (::std::move(value)) -#else -#define llvm_move(value) (value) -#endif - /// Expands to '&' if r-value references are supported. /// /// This can be used to provide l-value/r-value overrides of member functions. @@ -129,32 +104,13 @@ /// public: /// ... /// }; -#if (__has_feature(cxx_deleted_functions) \ - || defined(__GXX_EXPERIMENTAL_CXX0X__)) - // No version of MSVC currently supports this. +#if __has_feature(cxx_deleted_functions) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800) #define LLVM_DELETED_FUNCTION = delete #else #define LLVM_DELETED_FUNCTION #endif -/// LLVM_FINAL - Expands to 'final' if the compiler supports it. -/// Use to mark classes or virtual methods as final. -#if __has_feature(cxx_override_control) \ - || (defined(_MSC_VER) && _MSC_VER >= 1700) -#define LLVM_FINAL final -#else -#define LLVM_FINAL -#endif - -/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it. -/// Use to mark virtual methods as overriding a base class method. -#if __has_feature(cxx_override_control) \ - || (defined(_MSC_VER) && _MSC_VER >= 1700) -#define LLVM_OVERRIDE override -#else -#define LLVM_OVERRIDE -#endif - #if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__) # define LLVM_CONSTEXPR constexpr #else @@ -335,19 +291,15 @@ # define LLVM_FUNCTION_NAME __func__ #endif -#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H) -# include <sanitizer/msan_interface.h> -#else -# define __msan_allocated_memory(p, size) -# define __msan_unpoison(p, size) -#endif - /// \macro LLVM_MEMORY_SANITIZER_BUILD /// \brief Whether LLVM itself is built with MemorySanitizer instrumentation. #if __has_feature(memory_sanitizer) # define LLVM_MEMORY_SANITIZER_BUILD 1 +# include <sanitizer/msan_interface.h> #else # define LLVM_MEMORY_SANITIZER_BUILD 0 +# define __msan_allocated_memory(p, size) +# define __msan_unpoison(p, size) #endif /// \macro LLVM_ADDRESS_SANITIZER_BUILD @@ -374,41 +326,30 @@ /// \macro LLVM_EXPLICIT /// \brief Expands to explicit on compilers which support explicit conversion /// operators. Otherwise expands to nothing. -#if (__has_feature(cxx_explicit_conversions) \ - || defined(__GXX_EXPERIMENTAL_CXX0X__)) +#if __has_feature(cxx_explicit_conversions) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || LLVM_MSC_PREREQ(1800) #define LLVM_EXPLICIT explicit #else #define LLVM_EXPLICIT #endif -/// \macro LLVM_STATIC_ASSERT -/// \brief Expands to C/C++'s static_assert on compilers which support it. -#if __has_feature(cxx_static_assert) -# define LLVM_STATIC_ASSERT(expr, msg) static_assert(expr, msg) -#elif __has_feature(c_static_assert) -# define LLVM_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg) -#else -# define LLVM_STATIC_ASSERT(expr, msg) -#endif - -/// \macro LLVM_ENUM_INT_TYPE -/// \brief Expands to colon followed by the given integral type on compilers -/// which support C++11 strong enums. This can be used to make enums unsigned -/// with MSVC. -#if __has_feature(cxx_strong_enums) -# define LLVM_ENUM_INT_TYPE(intty) : intty -#elif defined(_MSC_VER) && _MSC_VER >= 1600 // Added in MSVC 2010. -# define LLVM_ENUM_INT_TYPE(intty) : intty -#else -# define LLVM_ENUM_INT_TYPE(intty) -#endif - /// \brief Does the compiler support generalized initializers (using braced -/// lists and std::initializer_list). -#if __has_feature(cxx_generalized_initializers) +/// lists and std::initializer_list). While clang may claim it supports general +/// initializers, if we're using MSVC's headers, we might not have a usable +/// std::initializer list type from the STL. Disable this for now. +#if __has_feature(cxx_generalized_initializers) && !defined(_MSC_VER) #define LLVM_HAS_INITIALIZER_LISTS 1 #else #define LLVM_HAS_INITIALIZER_LISTS 0 #endif +/// \brief Mark debug helper function definitions like dump() that should not be +/// stripped from debug builds. +// FIXME: Move this to a private config.h as it's not usable in public headers. +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED +#else +#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE +#endif + #endif diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h index bef9146..80eff5c 100644 --- a/include/llvm/Support/Compression.h +++ b/include/llvm/Support/Compression.h @@ -15,11 +15,11 @@ #define LLVM_SUPPORT_COMPRESSION_H #include "llvm/Support/DataTypes.h" +#include <memory> namespace llvm { class MemoryBuffer; -template<typename T> class OwningPtr; class StringRef; namespace zlib { @@ -33,21 +33,21 @@ enum CompressionLevel { enum Status { StatusOK, - StatusUnsupported, // zlib is unavaliable - StatusOutOfMemory, // there was not enough memory - StatusBufferTooShort, // there was not enough room in the output buffer - StatusInvalidArg, // invalid input parameter - StatusInvalidData // data was corrupted or incomplete + StatusUnsupported, // zlib is unavailable + StatusOutOfMemory, // there was not enough memory + StatusBufferTooShort, // there was not enough room in the output buffer + StatusInvalidArg, // invalid input parameter + StatusInvalidData // data was corrupted or incomplete }; bool isAvailable(); Status compress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &CompressedBuffer, + std::unique_ptr<MemoryBuffer> &CompressedBuffer, CompressionLevel Level = DefaultCompression); Status uncompress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &UncompressedBuffer, + std::unique_ptr<MemoryBuffer> &UncompressedBuffer, size_t UncompressedSize); uint32_t crc32(StringRef Buffer); diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h deleted file mode 100644 index 4aad952..0000000 --- a/include/llvm/Support/ConstantFolder.h +++ /dev/null @@ -1,238 +0,0 @@ -//===-- llvm/Support/ConstantFolder.h - Constant folding helper -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the ConstantFolder class, a helper for IRBuilder. -// It provides IRBuilder with a set of methods for creating constants -// with minimal folding. For general constant creation and folding, -// use ConstantExpr and the routines in llvm/Analysis/ConstantFolding.h. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_CONSTANTFOLDER_H -#define LLVM_SUPPORT_CONSTANTFOLDER_H - -#include "llvm/IR/Constants.h" -#include "llvm/IR/InstrTypes.h" - -namespace llvm { - -/// ConstantFolder - Create constants with minimum, target independent, folding. -class ConstantFolder { -public: - explicit ConstantFolder() {} - - //===--------------------------------------------------------------------===// - // Binary Operators - //===--------------------------------------------------------------------===// - - Constant *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW); - } - Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getFAdd(LHS, RHS); - } - Constant *CreateSub(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW); - } - Constant *CreateFSub(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getFSub(LHS, RHS); - } - Constant *CreateMul(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW); - } - Constant *CreateFMul(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getFMul(LHS, RHS); - } - Constant *CreateUDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getUDiv(LHS, RHS, isExact); - } - Constant *CreateSDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getSDiv(LHS, RHS, isExact); - } - Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getFDiv(LHS, RHS); - } - Constant *CreateURem(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getURem(LHS, RHS); - } - Constant *CreateSRem(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getSRem(LHS, RHS); - } - Constant *CreateFRem(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getFRem(LHS, RHS); - } - Constant *CreateShl(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW); - } - Constant *CreateLShr(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getLShr(LHS, RHS, isExact); - } - Constant *CreateAShr(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getAShr(LHS, RHS, isExact); - } - Constant *CreateAnd(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getAnd(LHS, RHS); - } - Constant *CreateOr(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getOr(LHS, RHS); - } - Constant *CreateXor(Constant *LHS, Constant *RHS) const { - return ConstantExpr::getXor(LHS, RHS); - } - - Constant *CreateBinOp(Instruction::BinaryOps Opc, - Constant *LHS, Constant *RHS) const { - return ConstantExpr::get(Opc, LHS, RHS); - } - - //===--------------------------------------------------------------------===// - // Unary Operators - //===--------------------------------------------------------------------===// - - Constant *CreateNeg(Constant *C, - bool HasNUW = false, bool HasNSW = false) const { - return ConstantExpr::getNeg(C, HasNUW, HasNSW); - } - Constant *CreateFNeg(Constant *C) const { - return ConstantExpr::getFNeg(C); - } - Constant *CreateNot(Constant *C) const { - return ConstantExpr::getNot(C); - } - - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); - } - Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return ConstantExpr::getGetElementPtr(C, Idx); - } - Constant *CreateGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); - } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return ConstantExpr::getInBoundsGetElementPtr(C, Idx); - } - Constant *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); - } - - //===--------------------------------------------------------------------===// - // Cast/Conversion Operators - //===--------------------------------------------------------------------===// - - Constant *CreateCast(Instruction::CastOps Op, Constant *C, - Type *DestTy) const { - return ConstantExpr::getCast(Op, C, DestTy); - } - Constant *CreatePointerCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getPointerCast(C, DestTy); - } - Constant *CreateIntCast(Constant *C, Type *DestTy, - bool isSigned) const { - return ConstantExpr::getIntegerCast(C, DestTy, isSigned); - } - Constant *CreateFPCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getFPCast(C, DestTy); - } - - Constant *CreateBitCast(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::BitCast, C, DestTy); - } - Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::IntToPtr, C, DestTy); - } - Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::PtrToInt, C, DestTy); - } - Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getZExtOrBitCast(C, DestTy); - } - Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getSExtOrBitCast(C, DestTy); - } - - Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { - return ConstantExpr::getTruncOrBitCast(C, DestTy); - } - - //===--------------------------------------------------------------------===// - // Compare Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS, - Constant *RHS) const { - return ConstantExpr::getCompare(P, LHS, RHS); - } - Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS, - Constant *RHS) const { - return ConstantExpr::getCompare(P, LHS, RHS); - } - - //===--------------------------------------------------------------------===// - // Other Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const { - return ConstantExpr::getSelect(C, True, False); - } - - Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const { - return ConstantExpr::getExtractElement(Vec, Idx); - } - - Constant *CreateInsertElement(Constant *Vec, Constant *NewElt, - Constant *Idx) const { - return ConstantExpr::getInsertElement(Vec, NewElt, Idx); - } - - Constant *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const { - return ConstantExpr::getShuffleVector(V1, V2, Mask); - } - - Constant *CreateExtractValue(Constant *Agg, - ArrayRef<unsigned> IdxList) const { - return ConstantExpr::getExtractValue(Agg, IdxList); - } - - Constant *CreateInsertValue(Constant *Agg, Constant *Val, - ArrayRef<unsigned> IdxList) const { - return ConstantExpr::getInsertValue(Agg, Val, IdxList); - } -}; - -} - -#endif diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h deleted file mode 100644 index f757c6e..0000000 --- a/include/llvm/Support/ConstantRange.h +++ /dev/null @@ -1,277 +0,0 @@ -//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Represent a range of possible values that may occur when the program is run -// for an integral value. This keeps track of a lower and upper bound for the -// constant, which MAY wrap around the end of the numeric range. To do this, it -// keeps track of a [lower, upper) bound, which specifies an interval just like -// STL iterators. When used with boolean values, the following are important -// ranges: : -// -// [F, F) = {} = Empty set -// [T, F) = {T} -// [F, T) = {F} -// [T, T) = {F, T} = Full set -// -// The other integral ranges use min/max values for special range values. For -// example, for 8-bit types, it uses: -// [0, 0) = {} = Empty set -// [255, 255) = {0..255} = Full Set -// -// Note that ConstantRange can be used to represent either signed or -// unsigned ranges. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_CONSTANTRANGE_H -#define LLVM_SUPPORT_CONSTANTRANGE_H - -#include "llvm/ADT/APInt.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { - -/// ConstantRange - This class represents an range of values. -/// -class ConstantRange { - APInt Lower, Upper; - -#if LLVM_HAS_RVALUE_REFERENCES - // If we have move semantics, pass APInts by value and move them into place. - typedef APInt APIntMoveTy; -#else - // Otherwise pass by const ref to save one copy. - typedef const APInt &APIntMoveTy; -#endif - -public: - /// Initialize a full (the default) or empty set for the specified bit width. - /// - explicit ConstantRange(uint32_t BitWidth, bool isFullSet = true); - - /// Initialize a range to hold the single specified value. - /// - ConstantRange(APIntMoveTy Value); - - /// @brief Initialize a range of values explicitly. This will assert out if - /// Lower==Upper and Lower != Min or Max value for its type. It will also - /// assert out if the two APInt's are not the same bit width. - ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper); - - /// makeICmpRegion - Produce the smallest range that contains all values that - /// might satisfy the comparison specified by Pred when compared to any value - /// contained within Other. - /// - /// Solves for range X in 'for all x in X, there exists a y in Y such that - /// icmp op x, y is true'. Every value that might make the comparison true - /// is included in the resulting range. - static ConstantRange makeICmpRegion(unsigned Pred, - const ConstantRange &Other); - - /// getLower - Return the lower value for this range... - /// - const APInt &getLower() const { return Lower; } - - /// getUpper - Return the upper value for this range... - /// - const APInt &getUpper() const { return Upper; } - - /// getBitWidth - get the bit width of this ConstantRange - /// - uint32_t getBitWidth() const { return Lower.getBitWidth(); } - - /// isFullSet - Return true if this set contains all of the elements possible - /// for this data-type - /// - bool isFullSet() const; - - /// isEmptySet - Return true if this set contains no members. - /// - bool isEmptySet() const; - - /// isWrappedSet - Return true if this set wraps around the top of the range, - /// for example: [100, 8) - /// - bool isWrappedSet() const; - - /// isSignWrappedSet - Return true if this set wraps around the INT_MIN of - /// its bitwidth, for example: i8 [120, 140). - /// - bool isSignWrappedSet() const; - - /// contains - Return true if the specified value is in the set. - /// - bool contains(const APInt &Val) const; - - /// contains - Return true if the other range is a subset of this one. - /// - bool contains(const ConstantRange &CR) const; - - /// getSingleElement - If this set contains a single element, return it, - /// otherwise return null. - /// - const APInt *getSingleElement() const { - if (Upper == Lower + 1) - return &Lower; - return 0; - } - - /// isSingleElement - Return true if this set contains exactly one member. - /// - bool isSingleElement() const { return getSingleElement() != 0; } - - /// getSetSize - Return the number of elements in this set. - /// - APInt getSetSize() const; - - /// getUnsignedMax - Return the largest unsigned value contained in the - /// ConstantRange. - /// - APInt getUnsignedMax() const; - - /// getUnsignedMin - Return the smallest unsigned value contained in the - /// ConstantRange. - /// - APInt getUnsignedMin() const; - - /// getSignedMax - Return the largest signed value contained in the - /// ConstantRange. - /// - APInt getSignedMax() const; - - /// getSignedMin - Return the smallest signed value contained in the - /// ConstantRange. - /// - APInt getSignedMin() const; - - /// operator== - Return true if this range is equal to another range. - /// - bool operator==(const ConstantRange &CR) const { - return Lower == CR.Lower && Upper == CR.Upper; - } - bool operator!=(const ConstantRange &CR) const { - return !operator==(CR); - } - - /// subtract - Subtract the specified constant from the endpoints of this - /// constant range. - ConstantRange subtract(const APInt &CI) const; - - /// \brief Subtract the specified range from this range (aka relative - /// complement of the sets). - ConstantRange difference(const ConstantRange &CR) const; - - /// intersectWith - Return the range that results from the intersection of - /// this range with another range. The resultant range is guaranteed to - /// include all elements contained in both input ranges, and to have the - /// smallest possible set size that does so. Because there may be two - /// intersections with the same set size, A.intersectWith(B) might not - /// be equal to B.intersectWith(A). - /// - ConstantRange intersectWith(const ConstantRange &CR) const; - - /// unionWith - Return the range that results from the union of this range - /// with another range. The resultant range is guaranteed to include the - /// elements of both sets, but may contain more. For example, [3, 9) union - /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included - /// in either set before. - /// - ConstantRange unionWith(const ConstantRange &CR) const; - - /// zeroExtend - Return a new range in the specified integer type, which must - /// be strictly larger than the current type. The returned range will - /// correspond to the possible range of values if the source range had been - /// zero extended to BitWidth. - ConstantRange zeroExtend(uint32_t BitWidth) const; - - /// signExtend - Return a new range in the specified integer type, which must - /// be strictly larger than the current type. The returned range will - /// correspond to the possible range of values if the source range had been - /// sign extended to BitWidth. - ConstantRange signExtend(uint32_t BitWidth) const; - - /// truncate - Return a new range in the specified integer type, which must be - /// strictly smaller than the current type. The returned range will - /// correspond to the possible range of values if the source range had been - /// truncated to the specified type. - ConstantRange truncate(uint32_t BitWidth) const; - - /// zextOrTrunc - make this range have the bit width given by \p BitWidth. The - /// value is zero extended, truncated, or left alone to make it that width. - ConstantRange zextOrTrunc(uint32_t BitWidth) const; - - /// sextOrTrunc - make this range have the bit width given by \p BitWidth. The - /// value is sign extended, truncated, or left alone to make it that width. - ConstantRange sextOrTrunc(uint32_t BitWidth) const; - - /// add - Return a new range representing the possible values resulting - /// from an addition of a value in this range and a value in \p Other. - ConstantRange add(const ConstantRange &Other) const; - - /// sub - Return a new range representing the possible values resulting - /// from a subtraction of a value in this range and a value in \p Other. - ConstantRange sub(const ConstantRange &Other) const; - - /// multiply - Return a new range representing the possible values resulting - /// from a multiplication of a value in this range and a value in \p Other. - /// TODO: This isn't fully implemented yet. - ConstantRange multiply(const ConstantRange &Other) const; - - /// smax - Return a new range representing the possible values resulting - /// from a signed maximum of a value in this range and a value in \p Other. - ConstantRange smax(const ConstantRange &Other) const; - - /// umax - Return a new range representing the possible values resulting - /// from an unsigned maximum of a value in this range and a value in \p Other. - ConstantRange umax(const ConstantRange &Other) const; - - /// udiv - Return a new range representing the possible values resulting - /// from an unsigned division of a value in this range and a value in - /// \p Other. - ConstantRange udiv(const ConstantRange &Other) const; - - /// binaryAnd - return a new range representing the possible values resulting - /// from a binary-and of a value in this range by a value in \p Other. - ConstantRange binaryAnd(const ConstantRange &Other) const; - - /// binaryOr - return a new range representing the possible values resulting - /// from a binary-or of a value in this range by a value in \p Other. - ConstantRange binaryOr(const ConstantRange &Other) const; - - /// shl - Return a new range representing the possible values resulting - /// from a left shift of a value in this range by a value in \p Other. - /// TODO: This isn't fully implemented yet. - ConstantRange shl(const ConstantRange &Other) const; - - /// lshr - Return a new range representing the possible values resulting - /// from a logical right shift of a value in this range and a value in - /// \p Other. - ConstantRange lshr(const ConstantRange &Other) const; - - /// inverse - Return a new range that is the logical not of the current set. - /// - ConstantRange inverse() const; - - /// print - Print out the bounds to a stream... - /// - void print(raw_ostream &OS) const; - - /// dump - Allow printing from a debugger easily... - /// - void dump() const; -}; - -inline raw_ostream &operator<<(raw_ostream &OS, const ConstantRange &CR) { - CR.print(OS); - return OS; -} - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 4c0a5e2..4500efe 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -46,6 +46,17 @@ class CrashRecoveryContext { void *Impl; CrashRecoveryContextCleanup *head; + /// An adaptor to convert an arbitrary functor into a void(void*), void* pair. + template<typename T> struct FunctorAdaptor { + T Fn; + static void invoke(void *Data) { + return static_cast<FunctorAdaptor<T>*>(Data)->Fn(); + } + typedef void Callback(void*); + Callback *fn() { return &invoke; } + void *arg() { return this; } + }; + public: CrashRecoveryContext() : Impl(0), head(0) {} ~CrashRecoveryContext(); @@ -76,6 +87,11 @@ public: /// RunSafely has returned false. Clients can use getBacktrace() to retrieve /// the backtrace of the crash on failures. bool RunSafely(void (*Fn)(void*), void *UserData); + template<typename Functor> + bool RunSafely(Functor Fn) { + FunctorAdaptor<Functor> Adaptor = { Fn }; + return RunSafely(Adaptor.fn(), Adaptor.arg()); + } /// \brief Execute the provide callback function (with the given arguments) in /// a protected context which is run in another thread (optionally with a @@ -84,6 +100,11 @@ public: /// See RunSafely() and llvm_execute_on_thread(). bool RunSafelyOnThread(void (*Fn)(void*), void *UserData, unsigned RequestedStackSize = 0); + template<typename Functor> + bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) { + FunctorAdaptor<Functor> Adaptor = { Fn }; + return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize); + } /// \brief Explicitly trigger a crash recovery in the current process, and /// return failure from RunSafely(). This function does not return. diff --git a/include/llvm/Support/DataFlow.h b/include/llvm/Support/DataFlow.h deleted file mode 100644 index a09ccaa..0000000 --- a/include/llvm/Support/DataFlow.h +++ /dev/null @@ -1,103 +0,0 @@ -//===-- llvm/Support/DataFlow.h - dataflow as graphs ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines specializations of GraphTraits that allows Use-Def and -// Def-Use relations to be treated as proper graphs for generic algorithms. -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_DATAFLOW_H -#define LLVM_SUPPORT_DATAFLOW_H - -#include "llvm/ADT/GraphTraits.h" -#include "llvm/IR/User.h" - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Provide specializations of GraphTraits to be able to treat def-use/use-def -// chains as graphs - -template <> struct GraphTraits<const Value*> { - typedef const Value NodeType; - typedef Value::const_use_iterator ChildIteratorType; - - static NodeType *getEntryNode(const Value *G) { - return G; - } - - static inline ChildIteratorType child_begin(NodeType *N) { - return N->use_begin(); - } - - static inline ChildIteratorType child_end(NodeType *N) { - return N->use_end(); - } -}; - -template <> struct GraphTraits<Value*> { - typedef Value NodeType; - typedef Value::use_iterator ChildIteratorType; - - static NodeType *getEntryNode(Value *G) { - return G; - } - - static inline ChildIteratorType child_begin(NodeType *N) { - return N->use_begin(); - } - - static inline ChildIteratorType child_end(NodeType *N) { - return N->use_end(); - } -}; - -template <> struct GraphTraits<Inverse<const User*> > { - typedef const Value NodeType; - typedef User::const_op_iterator ChildIteratorType; - - static NodeType *getEntryNode(Inverse<const User*> G) { - return G.Graph; - } - - static inline ChildIteratorType child_begin(NodeType *N) { - if (const User *U = dyn_cast<User>(N)) - return U->op_begin(); - return NULL; - } - - static inline ChildIteratorType child_end(NodeType *N) { - if(const User *U = dyn_cast<User>(N)) - return U->op_end(); - return NULL; - } -}; - -template <> struct GraphTraits<Inverse<User*> > { - typedef Value NodeType; - typedef User::op_iterator ChildIteratorType; - - static NodeType *getEntryNode(Inverse<User*> G) { - return G.Graph; - } - - static inline ChildIteratorType child_begin(NodeType *N) { - if (User *U = dyn_cast<User>(N)) - return U->op_begin(); - return NULL; - } - - static inline ChildIteratorType child_end(NodeType *N) { - if (User *U = dyn_cast<User>(N)) - return U->op_end(); - return NULL; - } -}; - -} -#endif diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h deleted file mode 100644 index 05f31d7..0000000 --- a/include/llvm/Support/DebugLoc.h +++ /dev/null @@ -1,114 +0,0 @@ -//===---- llvm/Support/DebugLoc.h - Debug Location Information --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a number of light weight data structures used -// to describe and track debug location information. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_DEBUGLOC_H -#define LLVM_SUPPORT_DEBUGLOC_H - -#include "llvm/Support/DataTypes.h"
- -namespace llvm { - template <typename T> struct DenseMapInfo; - class MDNode; - class LLVMContext; - - /// DebugLoc - Debug location id. This is carried by Instruction, SDNode, - /// and MachineInstr to compactly encode file/line/scope information for an - /// operation. - class DebugLoc { - friend struct DenseMapInfo<DebugLoc>; - - /// getEmptyKey() - A private constructor that returns an unknown that is - /// not equal to the tombstone key or DebugLoc(). - static DebugLoc getEmptyKey() { - DebugLoc DL; - DL.LineCol = 1; - return DL; - } - - /// getTombstoneKey() - A private constructor that returns an unknown that - /// is not equal to the empty key or DebugLoc(). - static DebugLoc getTombstoneKey() { - DebugLoc DL; - DL.LineCol = 2; - return DL; - } - - /// LineCol - This 32-bit value encodes the line and column number for the - /// location, encoded as 24-bits for line and 8 bits for col. A value of 0 - /// for either means unknown. - uint32_t LineCol; - - /// ScopeIdx - This is an opaque ID# for Scope/InlinedAt information, - /// decoded by LLVMContext. 0 is unknown. - int ScopeIdx; - public: - DebugLoc() : LineCol(0), ScopeIdx(0) {} // Defaults to unknown. - - /// get - Get a new DebugLoc that corresponds to the specified line/col - /// scope/inline location. - static DebugLoc get(unsigned Line, unsigned Col, - MDNode *Scope, MDNode *InlinedAt = 0); - - /// getFromDILocation - Translate the DILocation quad into a DebugLoc. - static DebugLoc getFromDILocation(MDNode *N); - - /// getFromDILexicalBlock - Translate the DILexicalBlock into a DebugLoc. - static DebugLoc getFromDILexicalBlock(MDNode *N); - - /// isUnknown - Return true if this is an unknown location. - bool isUnknown() const { return ScopeIdx == 0; } - - unsigned getLine() const { - return (LineCol << 8) >> 8; // Mask out column. - } - - unsigned getCol() const { - return LineCol >> 24; - } - - /// getScope - This returns the scope pointer for this DebugLoc, or null if - /// invalid. - MDNode *getScope(const LLVMContext &Ctx) const; - - /// getInlinedAt - This returns the InlinedAt pointer for this DebugLoc, or - /// null if invalid or not present. - MDNode *getInlinedAt(const LLVMContext &Ctx) const; - - /// getScopeAndInlinedAt - Return both the Scope and the InlinedAt values. - void getScopeAndInlinedAt(MDNode *&Scope, MDNode *&IA, - const LLVMContext &Ctx) const; - - - /// getAsMDNode - This method converts the compressed DebugLoc node into a - /// DILocation compatible MDNode. - MDNode *getAsMDNode(const LLVMContext &Ctx) const; - - bool operator==(const DebugLoc &DL) const { - return LineCol == DL.LineCol && ScopeIdx == DL.ScopeIdx; - } - bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } - - void dump(const LLVMContext &Ctx) const; - }; - - template <> - struct DenseMapInfo<DebugLoc> { - static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); } - static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); } - static unsigned getHashValue(const DebugLoc &Key); - static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; } - }; -} // end namespace llvm - -#endif /* LLVM_SUPPORT_DEBUGLOC_H */ diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 23bbd1c..ca31644 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -24,7 +24,7 @@ namespace llvm { //===----------------------------------------------------------------------===// // Debug info constants. -enum LLVM_ENUM_INT_TYPE(uint32_t) { +enum : uint32_t { LLVMDebugVersion = (12 << 16), // Current version of debug information. LLVMDebugVersion11 = (11 << 16), // Constant for version 11. LLVMDebugVersion10 = (10 << 16), // Constant for version 10. @@ -41,13 +41,13 @@ namespace dwarf { //===----------------------------------------------------------------------===// // Dwarf constants as gleaned from the DWARF Debugging Information Format V.4 -// reference manual http://dwarf.freestandards.org. +// reference manual http://www.dwarfstd.org/. // // Do not mix the following two enumerations sets. DW_TAG_invalid changes the // enumeration base type. -enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) { +enum LLVMConstants : uint32_t { // llvm mock tags DW_TAG_invalid = ~0U, // Tag for invalid results. @@ -68,7 +68,7 @@ enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) { const uint32_t DW_CIE_ID = UINT32_MAX; const uint64_t DW64_CIE_ID = UINT64_MAX; -enum Tag LLVM_ENUM_INT_TYPE(uint16_t) { +enum Tag : uint16_t { DW_TAG_array_type = 0x01, DW_TAG_class_type = 0x02, DW_TAG_entry_point = 0x03, @@ -129,6 +129,12 @@ enum Tag LLVM_ENUM_INT_TYPE(uint16_t) { DW_TAG_type_unit = 0x41, DW_TAG_rvalue_reference_type = 0x42, DW_TAG_template_alias = 0x43, + + // New in DWARF 5: + DW_TAG_coarray_type = 0x44, + DW_TAG_generic_subrange = 0x45, + DW_TAG_dynamic_type = 0x46, + DW_TAG_MIPS_loop = 0x4081, DW_TAG_format_label = 0x4101, DW_TAG_function_template = 0x4102, @@ -169,7 +175,7 @@ inline bool isType(Tag T) { } } -enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) { +enum Attribute : uint16_t { // Attributes DW_AT_sibling = 0x01, DW_AT_location = 0x02, @@ -264,6 +270,18 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) { DW_AT_enum_class = 0x6d, DW_AT_linkage_name = 0x6e, + // New in DWARF 5: + DW_AT_string_length_bit_size = 0x6f, + DW_AT_string_length_byte_size = 0x70, + DW_AT_rank = 0x71, + DW_AT_str_offsets_base = 0x72, + DW_AT_addr_base = 0x73, + DW_AT_ranges_base = 0x74, + DW_AT_dwo_id = 0x75, + DW_AT_dwo_name = 0x76, + DW_AT_reference = 0x77, + DW_AT_rvalue_reference = 0x78, + DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, @@ -323,7 +341,7 @@ enum Attribute LLVM_ENUM_INT_TYPE(uint16_t) { DW_AT_APPLE_property = 0x3fed }; -enum Form LLVM_ENUM_INT_TYPE(uint16_t) { +enum Form : uint16_t { // Attribute form encodings DW_FORM_addr = 0x01, DW_FORM_block2 = 0x03, @@ -605,7 +623,16 @@ enum SourceLanguage { DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, + // New in DWARF 5: DW_LANG_Python = 0x0014, + DW_LANG_OpenCL = 0x0015, + DW_LANG_Go = 0x0016, + DW_LANG_Modula3 = 0x0017, + DW_LANG_Haskell = 0x0018, + DW_LANG_C_plus_plus_03 = 0x0019, + DW_LANG_C_plus_plus_11 = 0x001a, + DW_LANG_OCaml = 0x001b, + DW_LANG_lo_user = 0x8000, DW_LANG_Mips_Assembler = 0x8001, DW_LANG_hi_user = 0xffff @@ -744,6 +771,15 @@ enum Constants { DW_EH_PE_indirect = 0x80 }; +// Constants for debug_loc.dwo in the DWARF5 Split Debug Info Proposal +enum LocationListEntry : unsigned char { + DW_LLE_end_of_list_entry, + DW_LLE_base_address_selection_entry, + DW_LLE_start_end_entry, + DW_LLE_start_length_entry, + DW_LLE_offset_pair_entry +}; + enum ApplePropertyAttributes { // Apple Objective-C Property Attributes DW_APPLE_PROPERTY_readonly = 0x01, diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 2868f35..7b10ebd 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -651,7 +651,7 @@ enum { }; // ARM Specific e_flags -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { EF_ARM_SOFT_FLOAT = 0x00000200U, EF_ARM_VFP_FLOAT = 0x00000400U, EF_ARM_EABI_UNKNOWN = 0x00000000U, @@ -801,10 +801,12 @@ enum { }; // Mips Specific e_flags -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions EF_MIPS_PIC = 0x00000002, // Position independent code EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code + EF_MIPS_ABI2 = 0x00000020, + EF_MIPS_32BITMODE = 0x00000100, EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI //ARCH_ASE @@ -837,7 +839,6 @@ enum { R_MIPS_GPREL16 = 7, R_MIPS_LITERAL = 8, R_MIPS_GOT16 = 9, - R_MIPS_GOT = 9, R_MIPS_PC16 = 10, R_MIPS_CALL16 = 11, R_MIPS_GPREL32 = 12, @@ -879,6 +880,9 @@ enum { R_MIPS_TLS_TPREL_HI16 = 49, R_MIPS_TLS_TPREL_LO16 = 50, R_MIPS_GLOB_DAT = 51, + R_MIPS16_GOT16 = 102, + R_MIPS16_HI16 = 104, + R_MIPS16_LO16 = 105, R_MIPS_COPY = 126, R_MIPS_JUMP_SLOT = 127, R_MICROMIPS_26_S1 = 133, @@ -890,11 +894,14 @@ enum { R_MICROMIPS_GOT_DISP = 145, R_MICROMIPS_GOT_PAGE = 146, R_MICROMIPS_GOT_OFST = 147, + R_MICROMIPS_TLS_GD = 162, + R_MICROMIPS_TLS_LDM = 163, R_MICROMIPS_TLS_DTPREL_HI16 = 164, R_MICROMIPS_TLS_DTPREL_LO16 = 165, R_MICROMIPS_TLS_TPREL_HI16 = 169, R_MICROMIPS_TLS_TPREL_LO16 = 170, - R_MIPS_NUM = 218 + R_MIPS_NUM = 218, + R_MIPS_PC32 = 248 }; // Special values for the st_other field in the symbol table entry for MIPS. @@ -1087,6 +1094,94 @@ enum { R_390_IRELATIVE = 61 }; +// ELF Relocation type for Sparc. +enum { + R_SPARC_NONE = 0, + R_SPARC_8 = 1, + R_SPARC_16 = 2, + R_SPARC_32 = 3, + R_SPARC_DISP8 = 4, + R_SPARC_DISP16 = 5, + R_SPARC_DISP32 = 6, + R_SPARC_WDISP30 = 7, + R_SPARC_WDISP22 = 8, + R_SPARC_HI22 = 9, + R_SPARC_22 = 10, + R_SPARC_13 = 11, + R_SPARC_LO10 = 12, + R_SPARC_GOT10 = 13, + R_SPARC_GOT13 = 14, + R_SPARC_GOT22 = 15, + R_SPARC_PC10 = 16, + R_SPARC_PC22 = 17, + R_SPARC_WPLT30 = 18, + R_SPARC_COPY = 19, + R_SPARC_GLOB_DAT = 20, + R_SPARC_JMP_SLOT = 21, + R_SPARC_RELATIVE = 22, + R_SPARC_UA32 = 23, + R_SPARC_PLT32 = 24, + R_SPARC_HIPLT22 = 25, + R_SPARC_LOPLT10 = 26, + R_SPARC_PCPLT32 = 27, + R_SPARC_PCPLT22 = 28, + R_SPARC_PCPLT10 = 29, + R_SPARC_10 = 30, + R_SPARC_11 = 31, + R_SPARC_64 = 32, + R_SPARC_OLO10 = 33, + R_SPARC_HH22 = 34, + R_SPARC_HM10 = 35, + R_SPARC_LM22 = 36, + R_SPARC_PC_HH22 = 37, + R_SPARC_PC_HM10 = 38, + R_SPARC_PC_LM22 = 39, + R_SPARC_WDISP16 = 40, + R_SPARC_WDISP19 = 41, + R_SPARC_7 = 43, + R_SPARC_5 = 44, + R_SPARC_6 = 45, + R_SPARC_DISP64 = 46, + R_SPARC_PLT64 = 47, + R_SPARC_HIX22 = 48, + R_SPARC_LOX10 = 49, + R_SPARC_H44 = 50, + R_SPARC_M44 = 51, + R_SPARC_L44 = 52, + R_SPARC_REGISTER = 53, + R_SPARC_UA64 = 54, + R_SPARC_UA16 = 55, + R_SPARC_TLS_GD_HI22 = 56, + R_SPARC_TLS_GD_LO10 = 57, + R_SPARC_TLS_GD_ADD = 58, + R_SPARC_TLS_GD_CALL = 59, + R_SPARC_TLS_LDM_HI22 = 60, + R_SPARC_TLS_LDM_LO10 = 61, + R_SPARC_TLS_LDM_ADD = 62, + R_SPARC_TLS_LDM_CALL = 63, + R_SPARC_TLS_LDO_HIX22 = 64, + R_SPARC_TLS_LDO_LOX10 = 65, + R_SPARC_TLS_LDO_ADD = 66, + R_SPARC_TLS_IE_HI22 = 67, + R_SPARC_TLS_IE_LO10 = 68, + R_SPARC_TLS_IE_LD = 69, + R_SPARC_TLS_IE_LDX = 70, + R_SPARC_TLS_IE_ADD = 71, + R_SPARC_TLS_LE_HIX22 = 72, + R_SPARC_TLS_LE_LOX10 = 73, + R_SPARC_TLS_DTPMOD32 = 74, + R_SPARC_TLS_DTPMOD64 = 75, + R_SPARC_TLS_DTPOFF32 = 76, + R_SPARC_TLS_DTPOFF64 = 77, + R_SPARC_TLS_TPOFF32 = 78, + R_SPARC_TLS_TPOFF64 = 79, + R_SPARC_GOTDATA_HIX22 = 80, + R_SPARC_GOTDATA_LOX22 = 81, + R_SPARC_GOTDATA_OP_HIX22 = 82, + R_SPARC_GOTDATA_OP_LOX22 = 83, + R_SPARC_GOTDATA_OP = 84 +}; + // Section header. struct Elf32_Shdr { Elf32_Word sh_name; // Section name (index into string table) @@ -1130,7 +1225,7 @@ enum { }; // Section types. -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { SHT_NULL = 0, // No associated section (inactive entry). SHT_PROGBITS = 1, // Program-defined contents. SHT_SYMTAB = 2, // Symbol table. @@ -1178,7 +1273,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) { }; // Section flags. -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { // Section data should be writable during execution. SHF_WRITE = 0x1, @@ -1270,7 +1365,7 @@ enum LLVM_ENUM_INT_TYPE(unsigned) { }; // Section Group Flags -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { GRP_COMDAT = 0x1, GRP_MASKOS = 0x0ff00000, GRP_MASKPROC = 0xf0000000 @@ -1492,7 +1587,7 @@ enum { }; // Segment flag bits. -enum LLVM_ENUM_INT_TYPE(unsigned) { +enum : unsigned { PF_X = 1, // Execute PF_W = 2, // Write PF_R = 4, // Read diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index 0d35849..2c5ab74 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -17,7 +17,6 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/type_traits.h" namespace llvm { namespace support { @@ -35,6 +34,7 @@ namespace detail { } // end namespace detail namespace endian { +/// Swap the bytes of value to match the given endianness. template<typename value_type, endianness endian> inline value_type byte_swap(value_type value) { if (endian != native && sys::IsBigEndianHost != (endian == big)) @@ -42,6 +42,7 @@ inline value_type byte_swap(value_type value) { return value; } +/// Read a value of a particular endianness from memory. template<typename value_type, endianness endian, std::size_t alignment> @@ -55,6 +56,16 @@ inline value_type read(const void *memory) { return byte_swap<value_type, endian>(ret); } +/// Read a value of a particular endianness from a buffer, and increment the +/// buffer past that value. +template<typename value_type, endianness endian, std::size_t alignment> +inline value_type readNext(const unsigned char *&memory) { + value_type ret = read<value_type, endian, alignment>(memory); + memory += sizeof(value_type); + return ret; +} + +/// Write a value to memory with a particular endianness. template<typename value_type, endianness endian, std::size_t alignment> diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h new file mode 100644 index 0000000..89c66d3 --- /dev/null +++ b/include/llvm/Support/EndianStream.h @@ -0,0 +1,39 @@ +//===- EndianStream.h - Stream ops with endian specific data ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities for operating on streams that have endian +// specific data. +// +//===----------------------------------------------------------------------===// + +#ifndef _LLVM_SUPPORT_ENDIAN_STREAM_H_ +#define _LLVM_SUPPORT_ENDIAN_STREAM_H_ + +#include <llvm/Support/Endian.h> +#include <llvm/Support/raw_ostream.h> + +namespace llvm { +namespace support { + +namespace endian { +/// Adapter to write values to a stream in a particular byte order. +template <endianness endian> struct Writer { + raw_ostream &OS; + Writer(raw_ostream &OS) : OS(OS) {} + template <typename value_type> void write(value_type Val) { + Val = byte_swap<value_type, endian>(Val); + OS.write((const char *)&Val, sizeof(value_type)); + } +}; +} // end namespace endian + +} // end namespace support +} // end namespace llvm + +#endif // _LLVM_SUPPORT_ENDIAN_STREAM_H_ diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index d5b11cb..becd957 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -19,15 +19,10 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/system_error.h" -#include "llvm/Support/type_traits.h" - #include <cassert> -#if LLVM_HAS_CXX11_TYPETRAITS #include <type_traits> -#endif namespace llvm { -#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES template<class T, class V> typename std::enable_if< std::is_constructible<T, V>::value , typename std::remove_reference<V>::type>::type && @@ -41,12 +36,6 @@ typename std::enable_if< !std::is_constructible<T, V>::value moveIfMoveConstructible(V &Val) { return Val; } -#else -template<class T, class V> -V &moveIfMoveConstructible(V &Val) { - return Val; -} -#endif /// \brief Stores a reference that can be changed. template <typename T> @@ -71,11 +60,10 @@ public: /// It is used like the following. /// \code /// ErrorOr<Buffer> getBuffer(); -/// void handleError(error_code ec); /// /// auto buffer = getBuffer(); -/// if (!buffer) -/// handleError(buffer); +/// if (error_code ec = buffer.getError()) +/// return ec; /// buffer->write("adena"); /// \endcode /// @@ -93,35 +81,32 @@ public: template<class T> class ErrorOr { template <class OtherT> friend class ErrorOr; - static const bool isRef = is_reference<T>::value; - typedef ReferenceStorage<typename remove_reference<T>::type> wrap; + static const bool isRef = std::is_reference<T>::value; + typedef ReferenceStorage<typename std::remove_reference<T>::type> wrap; public: - typedef typename - conditional< isRef - , wrap - , T - >::type storage_type; + typedef typename std::conditional<isRef, wrap, T>::type storage_type; private: - typedef typename remove_reference<T>::type &reference; - typedef typename remove_reference<T>::type *pointer; + typedef typename std::remove_reference<T>::type &reference; + typedef const typename std::remove_reference<T>::type &const_reference; + typedef typename std::remove_reference<T>::type *pointer; public: template <class E> - ErrorOr(E ErrorCode, typename enable_if_c<is_error_code_enum<E>::value || - is_error_condition_enum<E>::value, - void *>::type = 0) + ErrorOr(E ErrorCode, typename std::enable_if<is_error_code_enum<E>::value || + is_error_condition_enum<E>::value, + void *>::type = 0) : HasError(true) { - new (getError()) error_code(make_error_code(ErrorCode)); + new (getErrorStorage()) error_code(make_error_code(ErrorCode)); } ErrorOr(llvm::error_code EC) : HasError(true) { - new (getError()) error_code(EC); + new (getErrorStorage()) error_code(EC); } ErrorOr(T Val) : HasError(false) { - new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val)); + new (getStorage()) storage_type(moveIfMoveConstructible<storage_type>(Val)); } ErrorOr(const ErrorOr &Other) { @@ -144,7 +129,6 @@ public: return *this; } -#if LLVM_HAS_RVALUE_REFERENCES ErrorOr(ErrorOr &&Other) { moveConstruct(std::move(Other)); } @@ -164,31 +148,30 @@ public: moveAssign(std::move(Other)); return *this; } -#endif ~ErrorOr() { if (!HasError) - get()->~storage_type(); + getStorage()->~storage_type(); } - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true() {} - /// \brief Return false if there is an error. - operator unspecified_bool_type() const { - return HasError ? 0 : unspecified_bool_true; + LLVM_EXPLICIT operator bool() const { + return !HasError; } - operator llvm::error_code() const { - return HasError ? *getError() : llvm::error_code::success(); + reference get() { return *getStorage(); } + const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); } + + error_code getError() const { + return HasError ? *getErrorStorage() : error_code::success(); } pointer operator ->() { - return toPointer(get()); + return toPointer(getStorage()); } reference operator *() { - return *get(); + return *getStorage(); } private: @@ -197,11 +180,11 @@ private: if (!Other.HasError) { // Get the other value. HasError = false; - new (get()) storage_type(*Other.get()); + new (getStorage()) storage_type(*Other.getStorage()); } else { // Get other's error. HasError = true; - new (getError()) error_code(Other); + new (getErrorStorage()) error_code(Other.getError()); } } @@ -224,17 +207,16 @@ private: new (this) ErrorOr(Other); } -#if LLVM_HAS_RVALUE_REFERENCES template <class OtherT> void moveConstruct(ErrorOr<OtherT> &&Other) { if (!Other.HasError) { // Get the other value. HasError = false; - new (get()) storage_type(std::move(*Other.get())); + new (getStorage()) storage_type(std::move(*Other.getStorage())); } else { // Get other's error. HasError = true; - new (getError()) error_code(Other); + new (getErrorStorage()) error_code(Other.getError()); } } @@ -246,7 +228,6 @@ private: this->~ErrorOr(); new (this) ErrorOr(std::move(Other)); } -#endif pointer toPointer(pointer Val) { return Val; @@ -256,23 +237,23 @@ private: return &Val->get(); } - storage_type *get() { + storage_type *getStorage() { assert(!HasError && "Cannot get value when an error exists!"); return reinterpret_cast<storage_type*>(TStorage.buffer); } - const storage_type *get() const { + const storage_type *getStorage() const { assert(!HasError && "Cannot get value when an error exists!"); return reinterpret_cast<const storage_type*>(TStorage.buffer); } - error_code *getError() { + error_code *getErrorStorage() { assert(HasError && "Cannot get error when a value exists!"); return reinterpret_cast<error_code*>(ErrorStorage.buffer); } - const error_code *getError() const { - return const_cast<ErrorOr<T> *>(this)->getError(); + const error_code *getErrorStorage() const { + return const_cast<ErrorOr<T> *>(this)->getErrorStorage(); } @@ -284,8 +265,8 @@ private: }; template<class T, class E> -typename enable_if_c<is_error_code_enum<E>::value || - is_error_condition_enum<E>::value, bool>::type +typename std::enable_if<is_error_code_enum<E>::value || + is_error_condition_enum<E>::value, bool>::type operator ==(ErrorOr<T> &Err, E Code) { return error_code(Err) == Code; } diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h index cbc9c46..1884a24 100644 --- a/include/llvm/Support/FileOutputBuffer.h +++ b/include/llvm/Support/FileOutputBuffer.h @@ -43,6 +43,9 @@ public: static error_code create(StringRef FilePath, size_t Size, OwningPtr<FileOutputBuffer> &Result, unsigned Flags = 0); + static error_code create(StringRef FilePath, size_t Size, + std::unique_ptr<FileOutputBuffer> &Result, + unsigned Flags = 0); /// Returns a pointer to the start of the buffer. uint8_t *getBufferStart() { @@ -83,7 +86,7 @@ private: FileOutputBuffer(llvm::sys::fs::mapped_file_region *R, StringRef Path, StringRef TempPath); - OwningPtr<llvm::sys::fs::mapped_file_region> Region; + std::unique_ptr<llvm::sys::fs::mapped_file_region> Region; SmallString<128> FinalPath; SmallString<128> TempPath; }; diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index d301f84..b511a8e 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -28,7 +28,6 @@ #define LLVM_SUPPORT_FILESYSTEM_H #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/DataTypes.h" @@ -39,6 +38,7 @@ #include <iterator> #include <stack> #include <string> +#include <tuple> #include <vector> #ifdef HAVE_SYS_STAT_H @@ -49,10 +49,9 @@ namespace llvm { namespace sys { namespace fs { -/// file_type - An "enum class" enumeration for the file system's view of the -/// type. +/// An "enum class" enumeration for the file system's view of the type. struct file_type { - enum _ { + enum Impl { status_error, file_not_found, regular_file, @@ -65,12 +64,11 @@ struct file_type { type_unknown }; - file_type(_ v) : v_(v) {} - explicit file_type(int v) : v_(_(v)) {} - operator int() const {return v_;} + file_type(Impl V) : V(V) {} + operator Impl() const { return V; } private: - int v_; + Impl V; }; /// space_info - Self explanatory. @@ -137,8 +135,7 @@ public: } bool operator!=(const UniqueID &Other) const { return !(*this == Other); } bool operator<(const UniqueID &Other) const { - return Device < Other.Device || - (Device == Other.Device && File < Other.File); + return std::tie(Device, File) < std::tie(Other.Device, Other.File); } uint64_t getDevice() const { return Device; } uint64_t getFile() const { return File; } @@ -272,51 +269,42 @@ private: /// platform specific error_code. error_code make_absolute(SmallVectorImpl<char> &path); +/// @brief Normalize path separators in \a Path +/// +/// If the path contains any '\' separators, they are transformed into '/'. +/// This is particularly useful when cross-compiling Windows on Linux, but is +/// safe to invoke on Windows, which accepts both characters as a path +/// separator. +error_code normalize_separators(SmallVectorImpl<char> &Path); + /// @brief Create all the non-existent directories in path. /// /// @param path Directories to create. -/// @param existed Set to true if \a path already existed, false otherwise. -/// @returns errc::success if is_directory(path) and existed have been set, -/// otherwise a platform specific error_code. -error_code create_directories(const Twine &path, bool &existed); - -/// @brief Convenience function for clients that don't need to know if the -/// directory existed or not. -inline error_code create_directories(const Twine &Path) { - bool Existed; - return create_directories(Path, Existed); -} +/// @returns errc::success if is_directory(path), otherwise a platform +/// specific error_code. If IgnoreExisting is false, also returns +/// error if the directory already existed. +error_code create_directories(const Twine &path, bool IgnoreExisting = true); /// @brief Create the directory in path. /// /// @param path Directory to create. -/// @param existed Set to true if \a path already existed, false otherwise. -/// @returns errc::success if is_directory(path) and existed have been set, -/// otherwise a platform specific error_code. -error_code create_directory(const Twine &path, bool &existed); - -/// @brief Convenience function for clients that don't need to know if the -/// directory existed or not. -inline error_code create_directory(const Twine &Path) { - bool Existed; - return create_directory(Path, Existed); -} +/// @returns errc::success if is_directory(path), otherwise a platform +/// specific error_code. If IgnoreExisting is false, also returns +/// error if the directory already existed. +error_code create_directory(const Twine &path, bool IgnoreExisting = true); -/// @brief Create a hard link from \a from to \a to. +/// @brief Create a link from \a from to \a to. +/// +/// The link may be a soft or a hard link, depending on the platform. The caller +/// may not assume which one. Currently on windows it creates a hard link since +/// soft links require extra privileges. On unix, it creates a soft link since +/// hard links don't work on SMB file systems. /// /// @param to The path to hard link to. /// @param from The path to hard link from. This is created. -/// @returns errc::success if exists(to) && exists(from) && equivalent(to, from) -/// , otherwise a platform specific error_code. -error_code create_hard_link(const Twine &to, const Twine &from); - -/// @brief Create a symbolic link from \a from to \a to. -/// -/// @param to The path to symbolically link to. -/// @param from The path to symbolically link from. This is created. -/// @returns errc::success if exists(to) && exists(from) && is_symlink(from), -/// otherwise a platform specific error_code. -error_code create_symlink(const Twine &to, const Twine &from); +/// @returns errc::success if the link was created, otherwise a platform +/// specific error_code. +error_code create_link(const Twine &to, const Twine &from); /// @brief Get the current path. /// @@ -328,34 +316,10 @@ error_code current_path(SmallVectorImpl<char> &result); /// @brief Remove path. Equivalent to POSIX remove(). /// /// @param path Input path. -/// @param existed Set to true if \a path existed, false if it did not. -/// undefined otherwise. -/// @returns errc::success if path has been removed and existed has been -/// successfully set, otherwise a platform specific error_code. -error_code remove(const Twine &path, bool &existed); - -/// @brief Convenience function for clients that don't need to know if the file -/// existed or not. -inline error_code remove(const Twine &Path) { - bool Existed; - return remove(Path, Existed); -} - -/// @brief Recursively remove all files below \a path, then \a path. Files are -/// removed as if by POSIX remove(). -/// -/// @param path Input path. -/// @param num_removed Number of files removed. -/// @returns errc::success if path has been removed and num_removed has been -/// successfully set, otherwise a platform specific error_code. -error_code remove_all(const Twine &path, uint32_t &num_removed); - -/// @brief Convenience function for clients that don't need to know how many -/// files were removed. -inline error_code remove_all(const Twine &Path) { - uint32_t Removed; - return remove_all(Path, Removed); -} +/// @returns errc::success if path has been removed or didn't exist, otherwise a +/// platform specific error code. If IgnoreNonExisting is false, also +/// returns error if the file didn't exist. +error_code remove(const Twine &path, bool IgnoreNonExisting = true); /// @brief Rename \a from to \a to. Files are renamed as if by POSIX rename(). /// @@ -490,8 +454,7 @@ inline bool is_regular_file(const Twine &Path) { /// directory, regular file, or symlink? /// /// @param status A file_status previously returned from status. -/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) && -/// !is_symlink(s) +/// @returns exists(s) && !is_regular_file(s) && !is_directory(s) bool is_other(file_status status); /// @brief Is path something that exists but is not a directory, @@ -504,21 +467,6 @@ bool is_other(file_status status); /// platform specific error_code. error_code is_other(const Twine &path, bool &result); -/// @brief Does status represent a symlink? -/// -/// @param status A file_status previously returned from stat. -/// @returns status.type() == symlink_file. -bool is_symlink(file_status status); - -/// @brief Is path a symlink? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a symlink, false if it is not. -/// Undefined otherwise. -/// @returns errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_symlink(const Twine &path, bool &result); - /// @brief Get file status as if by POSIX stat(). /// /// @param path Input path. @@ -545,6 +493,11 @@ inline error_code file_size(const Twine &Path, uint64_t &Result) { return error_code::success(); } +/// @brief Set the file modification and access time. +/// +/// @returns errc::success if the file times were successfully set, otherwise a +/// platform specific error_code or errc::not_supported on platforms +/// where the functionality isn't available. error_code setLastModificationAndAccessTime(int FD, TimeValue Time); /// @brief Is status available? @@ -621,9 +574,12 @@ enum OpenFlags { /// with F_Excl. F_Append = 2, - /// F_Binary - The file should be opened in binary mode on platforms that - /// make this distinction. - F_Binary = 4 + /// The file should be opened in text mode on platforms that make this + /// distinction. + F_Text = 4, + + /// Open the file for read and write. + F_RW = 8 }; inline OpenFlags operator|(OpenFlags A, OpenFlags B) { @@ -704,10 +660,8 @@ private: public: typedef char char_type; -#if LLVM_HAS_RVALUE_REFERENCES mapped_file_region(mapped_file_region&&); mapped_file_region &operator =(mapped_file_region&&); -#endif /// Construct a mapped_file_region at \a path starting at \a offset of length /// \a length and with access \a mode. diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h index 79c59e4..873b8df 100644 --- a/include/llvm/Support/FileUtilities.h +++ b/include/llvm/Support/FileUtilities.h @@ -51,8 +51,7 @@ namespace llvm { ~FileRemover() { if (DeleteIt) { // Ignore problems deleting the file. - bool existed; - sys::fs::remove(Filename.str(), existed); + sys::fs::remove(Filename.str()); } } @@ -62,8 +61,7 @@ namespace llvm { void setFile(const Twine& filename, bool deleteIt = true) { if (DeleteIt) { // Ignore problems deleting the file. - bool existed; - sys::fs::remove(Filename.str(), existed); + sys::fs::remove(Filename.str()); } Filename.clear(); diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index aaa54e1..a62801f 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -84,7 +84,7 @@ public: : format_object_base(fmt), Val(val) { } - virtual int snprint(char *Buffer, unsigned BufferSize) const { + int snprint(char *Buffer, unsigned BufferSize) const override { return snprintf(Buffer, BufferSize, Fmt, Val); } }; @@ -102,7 +102,7 @@ public: : format_object_base(fmt), Val1(val1), Val2(val2) { } - virtual int snprint(char *Buffer, unsigned BufferSize) const { + int snprint(char *Buffer, unsigned BufferSize) const override { return snprintf(Buffer, BufferSize, Fmt, Val1, Val2); } }; @@ -121,7 +121,7 @@ public: : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3) { } - virtual int snprint(char *Buffer, unsigned BufferSize) const { + int snprint(char *Buffer, unsigned BufferSize) const override { return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3); } }; @@ -142,7 +142,7 @@ public: : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { } - virtual int snprint(char *Buffer, unsigned BufferSize) const { + int snprint(char *Buffer, unsigned BufferSize) const override { return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); } }; @@ -165,7 +165,7 @@ public: Val5(val5) { } - virtual int snprint(char *Buffer, unsigned BufferSize) const { + int snprint(char *Buffer, unsigned BufferSize) const override { return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); } }; diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h index df1f218..78c4809 100644 --- a/include/llvm/Support/FormattedStream.h +++ b/include/llvm/Support/FormattedStream.h @@ -57,11 +57,11 @@ private: /// const char *Scanned; - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, /// not counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE { + uint64_t current_pos() const override { // Our current position in the stream is all the contents which have been // written to the underlying stream (*not* the current position of the // underlying stream). @@ -129,25 +129,23 @@ public: /// getLine - Return the line number unsigned getLine() { return Position.second; } - - raw_ostream &resetColor() { + + raw_ostream &resetColor() override { TheStream->resetColor(); return *this; } - - raw_ostream &reverseColor() { + + raw_ostream &reverseColor() override { TheStream->reverseColor(); return *this; } - - raw_ostream &changeColor(enum Colors Color, - bool Bold, - bool BG) { + + raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override { TheStream->changeColor(Color, Bold, BG); return *this; } - - bool is_displayed() const { + + bool is_displayed() const override { return TheStream->is_displayed(); } diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 0aa716a..902f2db 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -1,4 +1,4 @@ -//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===// +//===- GCOV.h - LLVM coverage tool ----------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This header provides the interface to read and write coverage files that +// This header provides the interface to read and write coverage files that // use 'gcov' format. // //===----------------------------------------------------------------------===// @@ -16,6 +16,7 @@ #define LLVM_SUPPORT_GCOV_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/MemoryBuffer.h" @@ -28,36 +29,69 @@ class GCOVBlock; class FileInfo; namespace GCOV { - enum GCOVFormat { - InvalidGCOV, - GCNO_402, - GCNO_404, - GCDA_402, - GCDA_404 + enum GCOVVersion { + V402, + V404 }; } // end GCOV namespace +/// GCOVOptions - A struct for passing gcov options between functions. +struct GCOVOptions { + GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U) + : AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F), + PreservePaths(P), UncondBranch(U) {} + + bool AllBlocks; + bool BranchInfo; + bool BranchCount; + bool FuncCoverage; + bool PreservePaths; + bool UncondBranch; +}; + /// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific /// read operations. class GCOVBuffer { public: GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} - /// readGCOVFormat - Read GCOV signature at the beginning of buffer. - GCOV::GCOVFormat readGCOVFormat() { - StringRef Magic = Buffer->getBuffer().slice(0, 12); - Cursor = 12; - if (Magic == "oncg*404MVLL") - return GCOV::GCNO_404; - else if (Magic == "oncg*204MVLL") - return GCOV::GCNO_402; - else if (Magic == "adcg*404MVLL") - return GCOV::GCDA_404; - else if (Magic == "adcg*204MVLL") - return GCOV::GCDA_402; - - Cursor = 0; - return GCOV::InvalidGCOV; + /// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer. + bool readGCNOFormat() { + StringRef File = Buffer->getBuffer().slice(0, 4); + if (File != "oncg") { + errs() << "Unexpected file type: " << File << ".\n"; + return false; + } + Cursor = 4; + return true; + } + + /// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer. + bool readGCDAFormat() { + StringRef File = Buffer->getBuffer().slice(0, 4); + if (File != "adcg") { + errs() << "Unexpected file type: " << File << ".\n"; + return false; + } + Cursor = 4; + return true; + } + + /// readGCOVVersion - Read GCOV version. + bool readGCOVVersion(GCOV::GCOVVersion &Version) { + StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (VersionStr == "*204") { + Cursor += 4; + Version = GCOV::V402; + return true; + } + if (VersionStr == "*404") { + Cursor += 4; + Version = GCOV::V404; + return true; + } + errs() << "Unexpected version: " << VersionStr << ".\n"; + return false; } /// readFunctionTag - If cursor points to a function tag then increment the @@ -170,8 +204,11 @@ public: } bool readString(StringRef &Str) { - uint32_t Len; - if (!readInt(Len)) return false; + uint32_t Len = 0; + // Keep reading until we find a non-zero length. This emulates gcov's + // behaviour, which appears to do the same. + while (Len == 0) + if (!readInt(Len)) return false; Len *= 4; if (Buffer->getBuffer().size() < Cursor+Len) { errs() << "Unexpected end of memory buffer: " << Cursor+Len << ".\n"; @@ -193,67 +230,188 @@ private: /// (.gcno and .gcda). class GCOVFile { public: - GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {} + GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0), + ProgramCount(0) {} ~GCOVFile(); - bool read(GCOVBuffer &Buffer); - void dump(); + bool readGCNO(GCOVBuffer &Buffer); + bool readGCDA(GCOVBuffer &Buffer); + uint32_t getChecksum() const { return Checksum; } + void dump() const; void collectLineCounts(FileInfo &FI); private: + bool GCNOInitialized; + GCOV::GCOVVersion Version; + uint32_t Checksum; SmallVector<GCOVFunction *, 16> Functions; uint32_t RunCount; uint32_t ProgramCount; }; +/// GCOVEdge - Collects edge information. +struct GCOVEdge { + GCOVEdge(GCOVBlock *S, GCOVBlock *D): Src(S), Dst(D), Count(0) {} + + GCOVBlock *Src; + GCOVBlock *Dst; + uint64_t Count; +}; + /// GCOVFunction - Collects function information. class GCOVFunction { public: - GCOVFunction() : Ident(0), LineNumber(0) {} + typedef SmallVectorImpl<GCOVBlock *>::const_iterator BlockIterator; + + GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {} ~GCOVFunction(); - bool read(GCOVBuffer &Buffer, GCOV::GCOVFormat Format); + bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version); + bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version); + StringRef getName() const { return Name; } StringRef getFilename() const { return Filename; } - void dump(); + size_t getNumBlocks() const { return Blocks.size(); } + uint64_t getEntryCount() const; + uint64_t getExitCount() const; + + BlockIterator block_begin() const { return Blocks.begin(); } + BlockIterator block_end() const { return Blocks.end(); } + + void dump() const; void collectLineCounts(FileInfo &FI); private: + GCOVFile &Parent; uint32_t Ident; + uint32_t Checksum; uint32_t LineNumber; StringRef Name; StringRef Filename; SmallVector<GCOVBlock *, 16> Blocks; + SmallVector<GCOVEdge *, 16> Edges; }; /// GCOVBlock - Collects block information. class GCOVBlock { + struct EdgeWeight { + EdgeWeight(GCOVBlock *D): Dst(D), Count(0) {} + + GCOVBlock *Dst; + uint64_t Count; + }; + + struct SortDstEdgesFunctor { + bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) { + return E1->Dst->Number < E2->Dst->Number; + } + }; public: - GCOVBlock(GCOVFunction &P, uint32_t N) : - Parent(P), Number(N), Counter(0), Edges(), Lines() {} + typedef SmallVectorImpl<GCOVEdge *>::const_iterator EdgeIterator; + + GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N), Counter(0), + DstEdgesAreSorted(true), SrcEdges(), DstEdges(), Lines() {} ~GCOVBlock(); - void addEdge(uint32_t N) { Edges.push_back(N); } + const GCOVFunction &getParent() const { return Parent; } void addLine(uint32_t N) { Lines.push_back(N); } - void addCount(uint64_t N) { Counter += N; } - size_t getNumEdges() { return Edges.size(); } - void dump(); + uint32_t getLastLine() const { return Lines.back(); } + void addCount(size_t DstEdgeNo, uint64_t N); + uint64_t getCount() const { return Counter; } + + void addSrcEdge(GCOVEdge *Edge) { + assert(Edge->Dst == this); // up to caller to ensure edge is valid + SrcEdges.push_back(Edge); + } + void addDstEdge(GCOVEdge *Edge) { + assert(Edge->Src == this); // up to caller to ensure edge is valid + // Check if adding this edge causes list to become unsorted. + if (DstEdges.size() && DstEdges.back()->Dst->Number > Edge->Dst->Number) + DstEdgesAreSorted = false; + DstEdges.push_back(Edge); + } + size_t getNumSrcEdges() const { return SrcEdges.size(); } + size_t getNumDstEdges() const { return DstEdges.size(); } + void sortDstEdges(); + + EdgeIterator src_begin() const { return SrcEdges.begin(); } + EdgeIterator src_end() const { return SrcEdges.end(); } + EdgeIterator dst_begin() const { return DstEdges.begin(); } + EdgeIterator dst_end() const { return DstEdges.end(); } + + void dump() const; void collectLineCounts(FileInfo &FI); private: GCOVFunction &Parent; uint32_t Number; uint64_t Counter; - SmallVector<uint32_t, 16> Edges; + bool DstEdgesAreSorted; + SmallVector<GCOVEdge *, 16> SrcEdges; + SmallVector<GCOVEdge *, 16> DstEdges; SmallVector<uint32_t, 16> Lines; }; -typedef DenseMap<uint32_t, uint64_t> LineCounts; class FileInfo { + // It is unlikely--but possible--for multiple functions to be on the same line. + // Therefore this typedef allows LineData.Functions to store multiple functions + // per instance. This is rare, however, so optimize for the common case. + typedef SmallVector<const GCOVFunction *, 1> FunctionVector; + typedef DenseMap<uint32_t, FunctionVector> FunctionLines; + typedef SmallVector<const GCOVBlock *, 4> BlockVector; + typedef DenseMap<uint32_t, BlockVector> BlockLines; + + struct LineData { + BlockLines Blocks; + FunctionLines Functions; + }; + + struct GCOVCoverage { + GCOVCoverage(StringRef Name) : + Name(Name), LogicalLines(0), LinesExec(0), Branches(0), BranchesExec(0), + BranchesTaken(0) {} + + StringRef Name; + + uint32_t LogicalLines; + uint32_t LinesExec; + + uint32_t Branches; + uint32_t BranchesExec; + uint32_t BranchesTaken; + }; public: - void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) { - LineInfo[Filename][Line-1] += Count; + FileInfo(const GCOVOptions &Options) : + Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {} + + void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) { + LineInfo[Filename].Blocks[Line-1].push_back(Block); + } + void addFunctionLine(StringRef Filename, uint32_t Line, + const GCOVFunction *Function) { + LineInfo[Filename].Functions[Line-1].push_back(Function); } void setRunCount(uint32_t Runs) { RunCount = Runs; } void setProgramCount(uint32_t Programs) { ProgramCount = Programs; } - void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile); + void print(StringRef GCNOFile, StringRef GCDAFile); private: - StringMap<LineCounts> LineInfo; + void printFunctionSummary(raw_fd_ostream &OS, + const FunctionVector &Funcs) const; + void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block, + uint32_t LineIndex, uint32_t &BlockNo) const; + void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block, + GCOVCoverage &Coverage, uint32_t &EdgeNo); + void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo, + uint64_t Count) const; + + void printCoverage(const GCOVCoverage &Coverage) const; + void printFuncCoverage() const; + void printFileCoverage() const; + + const GCOVOptions &Options; + StringMap<LineData> LineInfo; uint32_t RunCount; uint32_t ProgramCount; + + typedef SmallVector<std::pair<std::string, GCOVCoverage>, 4> + FileCoverageList; + typedef MapVector<const GCOVFunction *, GCOVCoverage> FuncCoverageMap; + + FileCoverageList FileCoverages; + FuncCoverageMap FuncCoverages; }; } diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h new file mode 100644 index 0000000..6878844 --- /dev/null +++ b/include/llvm/Support/GenericDomTree.h @@ -0,0 +1,717 @@ +//===- GenericDomTree.h - Generic dominator trees for graphs ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file defines a set of templates that efficiently compute a dominator +/// tree over a generic graph. This is used typically in LLVM for fast +/// dominance queries on the CFG, but is fully generic w.r.t. the underlying +/// graph types. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H +#define LLVM_SUPPORT_GENERIC_DOM_TREE_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> + +namespace llvm { + +//===----------------------------------------------------------------------===// +/// DominatorBase - Base class that other, more interesting dominator analyses +/// inherit from. +/// +template <class NodeT> +class DominatorBase { +protected: + std::vector<NodeT*> Roots; + const bool IsPostDominators; + inline explicit DominatorBase(bool isPostDom) : + Roots(), IsPostDominators(isPostDom) {} +public: + + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + inline const std::vector<NodeT*> &getRoots() const { return Roots; } + + /// isPostDominator - Returns true if analysis based of postdoms + /// + bool isPostDominator() const { return IsPostDominators; } +}; + + +//===----------------------------------------------------------------------===// +// DomTreeNodeBase - Dominator Tree Node +template<class NodeT> class DominatorTreeBase; +struct PostDominatorTree; + +template <class NodeT> +class DomTreeNodeBase { + NodeT *TheBB; + DomTreeNodeBase<NodeT> *IDom; + std::vector<DomTreeNodeBase<NodeT> *> Children; + mutable int DFSNumIn, DFSNumOut; + + template<class N> friend class DominatorTreeBase; + friend struct PostDominatorTree; +public: + typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator; + typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator + const_iterator; + + iterator begin() { return Children.begin(); } + iterator end() { return Children.end(); } + const_iterator begin() const { return Children.begin(); } + const_iterator end() const { return Children.end(); } + + NodeT *getBlock() const { return TheBB; } + DomTreeNodeBase<NodeT> *getIDom() const { return IDom; } + const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const { + return Children; + } + + DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom) + : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { } + + DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) { + Children.push_back(C); + return C; + } + + size_t getNumChildren() const { + return Children.size(); + } + + void clearAllChildren() { + Children.clear(); + } + + bool compare(const DomTreeNodeBase<NodeT> *Other) const { + if (getNumChildren() != Other->getNumChildren()) + return true; + + SmallPtrSet<const NodeT *, 4> OtherChildren; + for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) { + const NodeT *Nd = (*I)->getBlock(); + OtherChildren.insert(Nd); + } + + for (const_iterator I = begin(), E = end(); I != E; ++I) { + const NodeT *N = (*I)->getBlock(); + if (OtherChildren.count(N) == 0) + return true; + } + return false; + } + + void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { + assert(IDom && "No immediate dominator?"); + if (IDom != NewIDom) { + typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), this); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + + // Switch to new dominator + IDom = NewIDom; + IDom->Children.push_back(this); + } + } + + /// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do + /// not call them. + unsigned getDFSNumIn() const { return DFSNumIn; } + unsigned getDFSNumOut() const { return DFSNumOut; } +private: + // Return true if this node is dominated by other. Use this only if DFS info + // is valid. + bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const { + return this->DFSNumIn >= other->DFSNumIn && + this->DFSNumOut <= other->DFSNumOut; + } +}; + +template<class NodeT> +inline raw_ostream &operator<<(raw_ostream &o, + const DomTreeNodeBase<NodeT> *Node) { + if (Node->getBlock()) + Node->getBlock()->printAsOperand(o, false); + else + o << " <<exit node>>"; + + o << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}"; + + return o << "\n"; +} + +template<class NodeT> +inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o, + unsigned Lev) { + o.indent(2*Lev) << "[" << Lev << "] " << N; + for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(), + E = N->end(); I != E; ++I) + PrintDomTree<NodeT>(*I, o, Lev+1); +} + +//===----------------------------------------------------------------------===// +/// DominatorTree - Calculate the immediate dominator tree for a function. +/// + +template<class FuncT, class N> +void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT, + FuncT& F); + +template<class NodeT> +class DominatorTreeBase : public DominatorBase<NodeT> { + bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, + const DomTreeNodeBase<NodeT> *B) const { + assert(A != B); + assert(isReachableFromEntry(B)); + assert(isReachableFromEntry(A)); + + const DomTreeNodeBase<NodeT> *IDom; + while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B) + B = IDom; // Walk up the tree + return IDom != 0; + } + +protected: + typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType; + DomTreeNodeMapType DomTreeNodes; + DomTreeNodeBase<NodeT> *RootNode; + + mutable bool DFSInfoValid; + mutable unsigned int SlowQueries; + // Information record used during immediate dominators computation. + struct InfoRec { + unsigned DFSNum; + unsigned Parent; + unsigned Semi; + NodeT *Label; + + InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {} + }; + + DenseMap<NodeT*, NodeT*> IDoms; + + // Vertex - Map the DFS number to the NodeT* + std::vector<NodeT*> Vertex; + + // Info - Collection of information used during the computation of idoms. + DenseMap<NodeT*, InfoRec> Info; + + void reset() { + for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), + E = DomTreeNodes.end(); I != E; ++I) + delete I->second; + DomTreeNodes.clear(); + IDoms.clear(); + this->Roots.clear(); + Vertex.clear(); + RootNode = 0; + } + + // NewBB is split and now it has one successor. Update dominator tree to + // reflect this change. + template<class N, class GraphT> + void Split(DominatorTreeBase<typename GraphT::NodeType>& DT, + typename GraphT::NodeType* NewBB) { + assert(std::distance(GraphT::child_begin(NewBB), + GraphT::child_end(NewBB)) == 1 && + "NewBB should have a single successor!"); + typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB); + + std::vector<typename GraphT::NodeType*> PredBlocks; + typedef GraphTraits<Inverse<N> > InvTraits; + for (typename InvTraits::ChildIteratorType PI = + InvTraits::child_begin(NewBB), + PE = InvTraits::child_end(NewBB); PI != PE; ++PI) + PredBlocks.push_back(*PI); + + assert(!PredBlocks.empty() && "No predblocks?"); + + bool NewBBDominatesNewBBSucc = true; + for (typename InvTraits::ChildIteratorType PI = + InvTraits::child_begin(NewBBSucc), + E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) { + typename InvTraits::NodeType *ND = *PI; + if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && + DT.isReachableFromEntry(ND)) { + NewBBDominatesNewBBSucc = false; + break; + } + } + + // Find NewBB's immediate dominator and create new dominator tree node for + // NewBB. + NodeT *NewBBIDom = 0; + unsigned i = 0; + for (i = 0; i < PredBlocks.size(); ++i) + if (DT.isReachableFromEntry(PredBlocks[i])) { + NewBBIDom = PredBlocks[i]; + break; + } + + // It's possible that none of the predecessors of NewBB are reachable; + // in that case, NewBB itself is unreachable, so nothing needs to be + // changed. + if (!NewBBIDom) + return; + + for (i = i + 1; i < PredBlocks.size(); ++i) { + if (DT.isReachableFromEntry(PredBlocks[i])) + NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]); + } + + // Create the new dominator tree node... and set the idom of NewBB. + DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); + + // If NewBB strictly dominates other blocks, then it is now the immediate + // dominator of NewBBSucc. Update the dominator tree as appropriate. + if (NewBBDominatesNewBBSucc) { + DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc); + DT.changeImmediateDominator(NewBBSuccNode, NewBBNode); + } + } + +public: + explicit DominatorTreeBase(bool isPostDom) + : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {} + virtual ~DominatorTreeBase() { reset(); } + + /// compare - Return false if the other dominator tree base matches this + /// dominator tree base. Otherwise return true. + bool compare(const DominatorTreeBase &Other) const { + + const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes; + if (DomTreeNodes.size() != OtherDomTreeNodes.size()) + return true; + + for (typename DomTreeNodeMapType::const_iterator + I = this->DomTreeNodes.begin(), + E = this->DomTreeNodes.end(); I != E; ++I) { + NodeT *BB = I->first; + typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB); + if (OI == OtherDomTreeNodes.end()) + return true; + + DomTreeNodeBase<NodeT>* MyNd = I->second; + DomTreeNodeBase<NodeT>* OtherNd = OI->second; + + if (MyNd->compare(OtherNd)) + return true; + } + + return false; + } + + virtual void releaseMemory() { reset(); } + + /// getNode - return the (Post)DominatorTree node for the specified basic + /// block. This is the same as using operator[] on this class. + /// + inline DomTreeNodeBase<NodeT> *getNode(NodeT *BB) const { + return DomTreeNodes.lookup(BB); + } + + /// getRootNode - This returns the entry node for the CFG of the function. If + /// this tree represents the post-dominance relations for a function, however, + /// this root may be a node with the block == NULL. This is the case when + /// there are multiple exit nodes from a particular function. Consumers of + /// post-dominance information must be capable of dealing with this + /// possibility. + /// + DomTreeNodeBase<NodeT> *getRootNode() { return RootNode; } + const DomTreeNodeBase<NodeT> *getRootNode() const { return RootNode; } + + /// Get all nodes dominated by R, including R itself. + void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const { + Result.clear(); + const DomTreeNodeBase<NodeT> *RN = getNode(R); + if (RN == NULL) + return; // If R is unreachable, it will not be present in the DOM tree. + SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL; + WL.push_back(RN); + + while (!WL.empty()) { + const DomTreeNodeBase<NodeT> *N = WL.pop_back_val(); + Result.push_back(N->getBlock()); + WL.append(N->begin(), N->end()); + } + } + + /// properlyDominates - Returns true iff A dominates B and A != B. + /// Note that this is not a constant time operation! + /// + bool properlyDominates(const DomTreeNodeBase<NodeT> *A, + const DomTreeNodeBase<NodeT> *B) const { + if (A == 0 || B == 0) + return false; + if (A == B) + return false; + return dominates(A, B); + } + + bool properlyDominates(const NodeT *A, const NodeT *B) const; + + /// isReachableFromEntry - Return true if A is dominated by the entry + /// block of the function containing it. + bool isReachableFromEntry(const NodeT* A) const { + assert(!this->isPostDominator() && + "This is not implemented for post dominators"); + return isReachableFromEntry(getNode(const_cast<NodeT *>(A))); + } + + inline bool isReachableFromEntry(const DomTreeNodeBase<NodeT> *A) const { + return A; + } + + /// dominates - Returns true iff A dominates B. Note that this is not a + /// constant time operation! + /// + inline bool dominates(const DomTreeNodeBase<NodeT> *A, + const DomTreeNodeBase<NodeT> *B) const { + // A node trivially dominates itself. + if (B == A) + return true; + + // An unreachable node is dominated by anything. + if (!isReachableFromEntry(B)) + return true; + + // And dominates nothing. + if (!isReachableFromEntry(A)) + return false; + + // Compare the result of the tree walk and the dfs numbers, if expensive + // checks are enabled. +#ifdef XDEBUG + assert((!DFSInfoValid || + (dominatedBySlowTreeWalk(A, B) == B->DominatedBy(A))) && + "Tree walk disagrees with dfs numbers!"); +#endif + + if (DFSInfoValid) + return B->DominatedBy(A); + + // If we end up with too many slow queries, just update the + // DFS numbers on the theory that we are going to keep querying. + SlowQueries++; + if (SlowQueries > 32) { + updateDFSNumbers(); + return B->DominatedBy(A); + } + + return dominatedBySlowTreeWalk(A, B); + } + + bool dominates(const NodeT *A, const NodeT *B) const; + + NodeT *getRoot() const { + assert(this->Roots.size() == 1 && "Should always have entry node!"); + return this->Roots[0]; + } + + /// findNearestCommonDominator - Find nearest common dominator basic block + /// for basic block A and B. If there is no such block then return NULL. + NodeT *findNearestCommonDominator(NodeT *A, NodeT *B) { + assert(A->getParent() == B->getParent() && + "Two blocks are not in same function"); + + // If either A or B is a entry block then it is nearest common dominator + // (for forward-dominators). + if (!this->isPostDominator()) { + NodeT &Entry = A->getParent()->front(); + if (A == &Entry || B == &Entry) + return &Entry; + } + + // If B dominates A then B is nearest common dominator. + if (dominates(B, A)) + return B; + + // If A dominates B then A is nearest common dominator. + if (dominates(A, B)) + return A; + + DomTreeNodeBase<NodeT> *NodeA = getNode(A); + DomTreeNodeBase<NodeT> *NodeB = getNode(B); + + // Collect NodeA dominators set. + SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms; + NodeADoms.insert(NodeA); + DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); + while (IDomA) { + NodeADoms.insert(IDomA); + IDomA = IDomA->getIDom(); + } + + // Walk NodeB immediate dominators chain and find common dominator node. + DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom(); + while (IDomB) { + if (NodeADoms.count(IDomB) != 0) + return IDomB->getBlock(); + + IDomB = IDomB->getIDom(); + } + + return NULL; + } + + const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) { + // Cast away the const qualifiers here. This is ok since + // const is re-introduced on the return type. + return findNearestCommonDominator(const_cast<NodeT *>(A), + const_cast<NodeT *>(B)); + } + + //===--------------------------------------------------------------------===// + // API to update (Post)DominatorTree information based on modifications to + // the CFG... + + /// addNewBlock - Add a new node to the dominator tree information. This + /// creates a new node as a child of DomBB dominator node,linking it into + /// the children list of the immediate dominator. + DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) { + assert(getNode(BB) == 0 && "Block already in dominator tree!"); + DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB); + assert(IDomNode && "Not immediate dominator specified for block!"); + DFSInfoValid = false; + return DomTreeNodes[BB] = + IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode)); + } + + /// changeImmediateDominator - This method is used to update the dominator + /// tree information when a node's immediate dominator changes. + /// + void changeImmediateDominator(DomTreeNodeBase<NodeT> *N, + DomTreeNodeBase<NodeT> *NewIDom) { + assert(N && NewIDom && "Cannot change null node pointers!"); + DFSInfoValid = false; + N->setIDom(NewIDom); + } + + void changeImmediateDominator(NodeT *BB, NodeT *NewBB) { + changeImmediateDominator(getNode(BB), getNode(NewBB)); + } + + /// eraseNode - Removes a node from the dominator tree. Block must not + /// dominate any other blocks. Removes node from its immediate dominator's + /// children list. Deletes dominator node associated with basic block BB. + void eraseNode(NodeT *BB) { + DomTreeNodeBase<NodeT> *Node = getNode(BB); + assert(Node && "Removing node that isn't in dominator tree."); + assert(Node->getChildren().empty() && "Node is not a leaf node."); + + // Remove node from immediate dominator's children list. + DomTreeNodeBase<NodeT> *IDom = Node->getIDom(); + if (IDom) { + typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), Node); + assert(I != IDom->Children.end() && + "Not in immediate dominator children set!"); + // I am no longer your child... + IDom->Children.erase(I); + } + + DomTreeNodes.erase(BB); + delete Node; + } + + /// removeNode - Removes a node from the dominator tree. Block must not + /// dominate any other blocks. Invalidates any node pointing to removed + /// block. + void removeNode(NodeT *BB) { + assert(getNode(BB) && "Removing node that isn't in dominator tree."); + DomTreeNodes.erase(BB); + } + + /// splitBlock - BB is split and now it has one successor. Update dominator + /// tree to reflect this change. + void splitBlock(NodeT* NewBB) { + if (this->IsPostDominators) + this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB); + else + this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB); + } + + /// print - Convert to human readable form + /// + void print(raw_ostream &o) const { + o << "=============================--------------------------------\n"; + if (this->isPostDominator()) + o << "Inorder PostDominator Tree: "; + else + o << "Inorder Dominator Tree: "; + if (!this->DFSInfoValid) + o << "DFSNumbers invalid: " << SlowQueries << " slow queries."; + o << "\n"; + + // The postdom tree can have a null root if there are no returns. + if (getRootNode()) + PrintDomTree<NodeT>(getRootNode(), o, 1); + } + +protected: + template<class GraphT> + friend typename GraphT::NodeType* Eval( + DominatorTreeBase<typename GraphT::NodeType>& DT, + typename GraphT::NodeType* V, + unsigned LastLinked); + + template<class GraphT> + friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, + typename GraphT::NodeType* V, + unsigned N); + + template<class FuncT, class N> + friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT, + FuncT& F); + + /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking + /// dominator tree in dfs order. + void updateDFSNumbers() const { + unsigned DFSNum = 0; + + SmallVector<std::pair<const DomTreeNodeBase<NodeT>*, + typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack; + + const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode(); + + if (!ThisRoot) + return; + + // Even in the case of multiple exits that form the post dominator root + // nodes, do not iterate over all exits, but start from the virtual root + // node. Otherwise bbs, that are not post dominated by any exit but by the + // virtual root node, will never be assigned a DFS number. + WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin())); + ThisRoot->DFSNumIn = DFSNum++; + + while (!WorkStack.empty()) { + const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; + typename DomTreeNodeBase<NodeT>::const_iterator ChildIt = + WorkStack.back().second; + + // If we visited all of the children of this node, "recurse" back up the + // stack setting the DFOutNum. + if (ChildIt == Node->end()) { + Node->DFSNumOut = DFSNum++; + WorkStack.pop_back(); + } else { + // Otherwise, recursively visit this child. + const DomTreeNodeBase<NodeT> *Child = *ChildIt; + ++WorkStack.back().second; + + WorkStack.push_back(std::make_pair(Child, Child->begin())); + Child->DFSNumIn = DFSNum++; + } + } + + SlowQueries = 0; + DFSInfoValid = true; + } + + DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) { + if (DomTreeNodeBase<NodeT> *Node = getNode(BB)) + return Node; + + // Haven't calculated this node yet? Get or calculate the node for the + // immediate dominator. + NodeT *IDom = getIDom(BB); + + assert(IDom || this->DomTreeNodes[NULL]); + DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom); + + // Add a new tree node for this NodeT, and link it as a child of + // IDomNode + DomTreeNodeBase<NodeT> *C = new DomTreeNodeBase<NodeT>(BB, IDomNode); + return this->DomTreeNodes[BB] = IDomNode->addChild(C); + } + + inline NodeT *getIDom(NodeT *BB) const { + return IDoms.lookup(BB); + } + + inline void addRoot(NodeT* BB) { + this->Roots.push_back(BB); + } + +public: + /// recalculate - compute a dominator tree for the given function + template<class FT> + void recalculate(FT& F) { + typedef GraphTraits<FT*> TraitsTy; + reset(); + this->Vertex.push_back(0); + + if (!this->IsPostDominators) { + // Initialize root + NodeT *entry = TraitsTy::getEntryNode(&F); + this->Roots.push_back(entry); + this->IDoms[entry] = 0; + this->DomTreeNodes[entry] = 0; + + Calculate<FT, NodeT*>(*this, F); + } else { + // Initialize the roots list + for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), + E = TraitsTy::nodes_end(&F); I != E; ++I) { + if (TraitsTy::child_begin(I) == TraitsTy::child_end(I)) + addRoot(I); + + // Prepopulate maps so that we don't get iterator invalidation issues later. + this->IDoms[I] = 0; + this->DomTreeNodes[I] = 0; + } + + Calculate<FT, Inverse<NodeT*> >(*this, F); + } + } +}; + +// These two functions are declared out of line as a workaround for building +// with old (< r147295) versions of clang because of pr11642. +template<class NodeT> +bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const { + if (A == B) + return true; + + // Cast away the const qualifiers here. This is ok since + // this function doesn't actually return the values returned + // from getNode. + return dominates(getNode(const_cast<NodeT *>(A)), + getNode(const_cast<NodeT *>(B))); +} +template<class NodeT> +bool +DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const { + if (A == B) + return false; + + // Cast away the const qualifiers here. This is ok since + // this function doesn't actually return the values returned + // from getNode. + return dominates(getNode(const_cast<NodeT *>(A)), + getNode(const_cast<NodeT *>(B))); +} + +} + +#endif diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h new file mode 100644 index 0000000..f6bb8f4 --- /dev/null +++ b/include/llvm/Support/GenericDomTreeConstruction.h @@ -0,0 +1,289 @@ +//===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// Generic dominator tree construction - This file provides routines to +/// construct immediate dominator information for a flow-graph based on the +/// algorithm described in this document: +/// +/// A Fast Algorithm for Finding Dominators in a Flowgraph +/// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. +/// +/// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns +/// out that the theoretically slower O(n*log(n)) implementation is actually +/// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs. +/// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H +#define LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H + +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Support/GenericDomTree.h" + +namespace llvm { + +template<class GraphT> +unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, + typename GraphT::NodeType* V, unsigned N) { + // This is more understandable as a recursive algorithm, but we can't use the + // recursive algorithm due to stack depth issues. Keep it here for + // documentation purposes. +#if 0 + InfoRec &VInfo = DT.Info[DT.Roots[i]]; + VInfo.DFSNum = VInfo.Semi = ++N; + VInfo.Label = V; + + Vertex.push_back(V); // Vertex[n] = V; + + for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) { + InfoRec &SuccVInfo = DT.Info[*SI]; + if (SuccVInfo.Semi == 0) { + SuccVInfo.Parent = V; + N = DTDFSPass(DT, *SI, N); + } + } +#else + bool IsChildOfArtificialExit = (N != 0); + + SmallVector<std::pair<typename GraphT::NodeType*, + typename GraphT::ChildIteratorType>, 32> Worklist; + Worklist.push_back(std::make_pair(V, GraphT::child_begin(V))); + while (!Worklist.empty()) { + typename GraphT::NodeType* BB = Worklist.back().first; + typename GraphT::ChildIteratorType NextSucc = Worklist.back().second; + + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = + DT.Info[BB]; + + // First time we visited this BB? + if (NextSucc == GraphT::child_begin(BB)) { + BBInfo.DFSNum = BBInfo.Semi = ++N; + BBInfo.Label = BB; + + DT.Vertex.push_back(BB); // Vertex[n] = V; + + if (IsChildOfArtificialExit) + BBInfo.Parent = 1; + + IsChildOfArtificialExit = false; + } + + // store the DFS number of the current BB - the reference to BBInfo might + // get invalidated when processing the successors. + unsigned BBDFSNum = BBInfo.DFSNum; + + // If we are done with this block, remove it from the worklist. + if (NextSucc == GraphT::child_end(BB)) { + Worklist.pop_back(); + continue; + } + + // Increment the successor number for the next time we get to it. + ++Worklist.back().second; + + // Visit the successor next, if it isn't already visited. + typename GraphT::NodeType* Succ = *NextSucc; + + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo = + DT.Info[Succ]; + if (SuccVInfo.Semi == 0) { + SuccVInfo.Parent = BBDFSNum; + Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ))); + } + } +#endif + return N; +} + +template<class GraphT> +typename GraphT::NodeType* +Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, + typename GraphT::NodeType *VIn, unsigned LastLinked) { + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo = + DT.Info[VIn]; + if (VInInfo.DFSNum < LastLinked) + return VIn; + + SmallVector<typename GraphT::NodeType*, 32> Work; + SmallPtrSet<typename GraphT::NodeType*, 32> Visited; + + if (VInInfo.Parent >= LastLinked) + Work.push_back(VIn); + + while (!Work.empty()) { + typename GraphT::NodeType* V = Work.back(); + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo = + DT.Info[V]; + typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent]; + + // Process Ancestor first + if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) { + Work.push_back(VAncestor); + continue; + } + Work.pop_back(); + + // Update VInfo based on Ancestor info + if (VInfo.Parent < LastLinked) + continue; + + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo = + DT.Info[VAncestor]; + typename GraphT::NodeType* VAncestorLabel = VAInfo.Label; + typename GraphT::NodeType* VLabel = VInfo.Label; + if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) + VInfo.Label = VAncestorLabel; + VInfo.Parent = VAInfo.Parent; + } + + return VInInfo.Label; +} + +template<class FuncT, class NodeT> +void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, + FuncT& F) { + typedef GraphTraits<NodeT> GraphT; + + unsigned N = 0; + bool MultipleRoots = (DT.Roots.size() > 1); + if (MultipleRoots) { + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = + DT.Info[NULL]; + BBInfo.DFSNum = BBInfo.Semi = ++N; + BBInfo.Label = NULL; + + DT.Vertex.push_back(NULL); // Vertex[n] = V; + } + + // Step #1: Number blocks in depth-first order and initialize variables used + // in later stages of the algorithm. + for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size()); + i != e; ++i) + N = DFSPass<GraphT>(DT, DT.Roots[i], N); + + // it might be that some blocks did not get a DFS number (e.g., blocks of + // infinite loops). In these cases an artificial exit node is required. + MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F)); + + // When naively implemented, the Lengauer-Tarjan algorithm requires a separate + // bucket for each vertex. However, this is unnecessary, because each vertex + // is only placed into a single bucket (that of its semidominator), and each + // vertex's bucket is processed before it is added to any bucket itself. + // + // Instead of using a bucket per vertex, we use a single array Buckets that + // has two purposes. Before the vertex V with preorder number i is processed, + // Buckets[i] stores the index of the first element in V's bucket. After V's + // bucket is processed, Buckets[i] stores the index of the next element in the + // bucket containing V, if any. + SmallVector<unsigned, 32> Buckets; + Buckets.resize(N + 1); + for (unsigned i = 1; i <= N; ++i) + Buckets[i] = i; + + for (unsigned i = N; i >= 2; --i) { + typename GraphT::NodeType* W = DT.Vertex[i]; + typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo = + DT.Info[W]; + + // Step #2: Implicitly define the immediate dominator of vertices + for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1); + DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; + } + + // Step #3: Calculate the semidominators of all vertices + + // initialize the semi dominator to point to the parent node + WInfo.Semi = WInfo.Parent; + typedef GraphTraits<Inverse<NodeT> > InvTraits; + for (typename InvTraits::ChildIteratorType CI = + InvTraits::child_begin(W), + E = InvTraits::child_end(W); CI != E; ++CI) { + typename InvTraits::NodeType *N = *CI; + if (DT.Info.count(N)) { // Only if this predecessor is reachable! + unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi; + if (SemiU < WInfo.Semi) + WInfo.Semi = SemiU; + } + } + + // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is + // necessarily parent(V). In this case, set idom(V) here and avoid placing + // V into a bucket. + if (WInfo.Semi == WInfo.Parent) { + DT.IDoms[W] = DT.Vertex[WInfo.Parent]; + } else { + Buckets[i] = Buckets[WInfo.Semi]; + Buckets[WInfo.Semi] = i; + } + } + + if (N >= 1) { + typename GraphT::NodeType* Root = DT.Vertex[1]; + for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { + typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; + DT.IDoms[V] = Root; + } + } + + // Step #4: Explicitly define the immediate dominator of each vertex + for (unsigned i = 2; i <= N; ++i) { + typename GraphT::NodeType* W = DT.Vertex[i]; + typename GraphT::NodeType*& WIDom = DT.IDoms[W]; + if (WIDom != DT.Vertex[DT.Info[W].Semi]) + WIDom = DT.IDoms[WIDom]; + } + + if (DT.Roots.empty()) return; + + // Add a node for the root. This node might be the actual root, if there is + // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) + // which postdominates all real exits if there are multiple exit blocks, or + // an infinite loop. + typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0; + + DT.DomTreeNodes[Root] = DT.RootNode = + new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0); + + // Loop over all of the reachable blocks in the function... + for (unsigned i = 2; i <= N; ++i) { + typename GraphT::NodeType* W = DT.Vertex[i]; + + DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W]; + if (BBNode) continue; // Haven't calculated this node yet? + + typename GraphT::NodeType* ImmDom = DT.getIDom(W); + + assert(ImmDom || DT.DomTreeNodes[NULL]); + + // Get or calculate the node for the immediate dominator + DomTreeNodeBase<typename GraphT::NodeType> *IDomNode = + DT.getNodeForBlock(ImmDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + DomTreeNodeBase<typename GraphT::NodeType> *C = + new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode); + DT.DomTreeNodes[W] = IDomNode->addChild(C); + } + + // Free temporary memory used to construct idom's + DT.IDoms.clear(); + DT.Info.clear(); + std::vector<typename GraphT::NodeType*>().swap(DT.Vertex); + + DT.updateDFSNumbers(); +} + +} + +#endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h deleted file mode 100644 index aacb531..0000000 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ /dev/null @@ -1,113 +0,0 @@ -//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements an iterator for walking through the types indexed by -// getelementptr instructions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H -#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H - -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/User.h" - -namespace llvm { - template<typename ItTy = User::const_op_iterator> - class generic_gep_type_iterator - : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { - typedef std::iterator<std::forward_iterator_tag, - Type *, ptrdiff_t> super; - - ItTy OpIt; - Type *CurTy; - generic_gep_type_iterator() {} - public: - - static generic_gep_type_iterator begin(Type *Ty, ItTy It) { - generic_gep_type_iterator I; - I.CurTy = Ty; - I.OpIt = It; - return I; - } - static generic_gep_type_iterator end(ItTy It) { - generic_gep_type_iterator I; - I.CurTy = 0; - I.OpIt = It; - return I; - } - - bool operator==(const generic_gep_type_iterator& x) const { - return OpIt == x.OpIt; - } - bool operator!=(const generic_gep_type_iterator& x) const { - return !operator==(x); - } - - Type *operator*() const { - return CurTy; - } - - Type *getIndexedType() const { - CompositeType *CT = cast<CompositeType>(CurTy); - return CT->getTypeAtIndex(getOperand()); - } - - // This is a non-standard operator->. It allows you to call methods on the - // current type directly. - Type *operator->() const { return operator*(); } - - Value *getOperand() const { return *OpIt; } - - generic_gep_type_iterator& operator++() { // Preincrement - if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { - CurTy = CT->getTypeAtIndex(getOperand()); - } else { - CurTy = 0; - } - ++OpIt; - return *this; - } - - generic_gep_type_iterator operator++(int) { // Postincrement - generic_gep_type_iterator tmp = *this; ++*this; return tmp; - } - }; - - typedef generic_gep_type_iterator<> gep_type_iterator; - - inline gep_type_iterator gep_type_begin(const User *GEP) { - return gep_type_iterator::begin - (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); - } - inline gep_type_iterator gep_type_end(const User *GEP) { - return gep_type_iterator::end(GEP->op_end()); - } - inline gep_type_iterator gep_type_begin(const User &GEP) { - return gep_type_iterator::begin - (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); - } - inline gep_type_iterator gep_type_end(const User &GEP) { - return gep_type_iterator::end(GEP.op_end()); - } - - template<typename T> - inline generic_gep_type_iterator<const T *> - gep_type_begin(Type *Op0, ArrayRef<T> A) { - return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); - } - - template<typename T> - inline generic_gep_type_iterator<const T *> - gep_type_end(Type * /*Op0*/, ArrayRef<T> A) { - return generic_gep_type_iterator<const T *>::end(A.end()); - } -} // end namespace llvm - -#endif diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h index 28c4cc7..8f4bf3c 100644 --- a/include/llvm/Support/Host.h +++ b/include/llvm/Support/Host.h @@ -55,7 +55,7 @@ namespace sys { /// target which matches the host. /// /// \return - The host CPU name, or empty if the CPU could not be determined. - std::string getHostCPUName(); + StringRef getHostCPUName(); /// getHostCPUFeatures - Get the LLVM names for the host CPU features. /// The particular format of the names are target dependent, and suitable for diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h deleted file mode 100644 index ac936a1..0000000 --- a/include/llvm/Support/InstIterator.h +++ /dev/null @@ -1,147 +0,0 @@ -//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains definitions of two iterators for iterating over the -// instructions in a function. This is effectively a wrapper around a two level -// iterator that can probably be genericized later. -// -// Note that this iterator gets invalidated any time that basic blocks or -// instructions are moved around. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_INSTITERATOR_H -#define LLVM_SUPPORT_INSTITERATOR_H - -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/Function.h" - -namespace llvm { - -// This class implements inst_begin() & inst_end() for -// inst_iterator and const_inst_iterator's. -// -template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> -class InstIterator { - typedef _BB_t BBty; - typedef _BB_i_t BBIty; - typedef _BI_t BIty; - typedef _II_t IIty; - _BB_t *BBs; // BasicBlocksType - _BB_i_t BB; // BasicBlocksType::iterator - _BI_t BI; // BasicBlock::iterator -public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef IIty value_type; - typedef signed difference_type; - typedef IIty* pointer; - typedef IIty& reference; - - // Default constructor - InstIterator() {} - - // Copy constructor... - template<typename A, typename B, typename C, typename D> - InstIterator(const InstIterator<A,B,C,D> &II) - : BBs(II.BBs), BB(II.BB), BI(II.BI) {} - - template<typename A, typename B, typename C, typename D> - InstIterator(InstIterator<A,B,C,D> &II) - : BBs(II.BBs), BB(II.BB), BI(II.BI) {} - - template<class M> InstIterator(M &m) - : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor - if (BB != BBs->end()) { - BI = BB->begin(); - advanceToNextBB(); - } - } - - template<class M> InstIterator(M &m, bool) - : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor - } - - // Accessors to get at the underlying iterators... - inline BBIty &getBasicBlockIterator() { return BB; } - inline BIty &getInstructionIterator() { return BI; } - - inline reference operator*() const { return *BI; } - inline pointer operator->() const { return &operator*(); } - - inline bool operator==(const InstIterator &y) const { - return BB == y.BB && (BB == BBs->end() || BI == y.BI); - } - inline bool operator!=(const InstIterator& y) const { - return !operator==(y); - } - - InstIterator& operator++() { - ++BI; - advanceToNextBB(); - return *this; - } - inline InstIterator operator++(int) { - InstIterator tmp = *this; ++*this; return tmp; - } - - InstIterator& operator--() { - while (BB == BBs->end() || BI == BB->begin()) { - --BB; - BI = BB->end(); - } - --BI; - return *this; - } - inline InstIterator operator--(int) { - InstIterator tmp = *this; --*this; return tmp; - } - - inline bool atEnd() const { return BB == BBs->end(); } - -private: - inline void advanceToNextBB() { - // The only way that the II could be broken is if it is now pointing to - // the end() of the current BasicBlock and there are successor BBs. - while (BI == BB->end()) { - ++BB; - if (BB == BBs->end()) break; - BI = BB->begin(); - } - } -}; - - -typedef InstIterator<iplist<BasicBlock>, - Function::iterator, BasicBlock::iterator, - Instruction> inst_iterator; -typedef InstIterator<const iplist<BasicBlock>, - Function::const_iterator, - BasicBlock::const_iterator, - const Instruction> const_inst_iterator; - -inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); } -inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); } -inline const_inst_iterator inst_begin(const Function *F) { - return const_inst_iterator(*F); -} -inline const_inst_iterator inst_end(const Function *F) { - return const_inst_iterator(*F, true); -} -inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); } -inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); } -inline const_inst_iterator inst_begin(const Function &F) { - return const_inst_iterator(F); -} -inline const_inst_iterator inst_end(const Function &F) { - return const_inst_iterator(F, true); -} - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h index 3d73792..9ef5fe6 100644 --- a/include/llvm/Support/LEB128.h +++ b/include/llvm/Support/LEB128.h @@ -90,6 +90,12 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) { return Value; } +/// Utility function to get the size of the ULEB128-encoded value. +extern unsigned getULEB128Size(uint64_t Value); + +/// Utility function to get the size of the SLEB128-encoded value. +extern unsigned getSLEB128Size(int64_t Value); + } // namespace llvm #endif // LLVM_SYSTEM_LEB128_H diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h deleted file mode 100644 index 501a9db..0000000 --- a/include/llvm/Support/LeakDetector.h +++ /dev/null @@ -1,92 +0,0 @@ -//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a class that can be used to provide very simple memory leak -// checks for an API. Basically LLVM uses this to make sure that Instructions, -// for example, are deleted when they are supposed to be, and not leaked away. -// -// When compiling with NDEBUG (Release build), this class does nothing, thus -// adding no checking overhead to release builds. Note that this class is -// implemented in a very simple way, requiring completely manual manipulation -// and checking for garbage, but this is intentional: users should not be using -// this API, only other APIs should. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_LEAKDETECTOR_H -#define LLVM_SUPPORT_LEAKDETECTOR_H - -#include <string> - -namespace llvm { - -class LLVMContext; -class Value; - -struct LeakDetector { - /// addGarbageObject - Add a pointer to the internal set of "garbage" object - /// pointers. This should be called when objects are created, or if they are - /// taken out of an owning collection. - /// - static void addGarbageObject(void *Object) { -#ifndef NDEBUG - addGarbageObjectImpl(Object); -#endif - } - - /// removeGarbageObject - Remove a pointer from our internal representation of - /// our "garbage" objects. This should be called when an object is added to - /// an "owning" collection. - /// - static void removeGarbageObject(void *Object) { -#ifndef NDEBUG - removeGarbageObjectImpl(Object); -#endif - } - - /// checkForGarbage - Traverse the internal representation of garbage - /// pointers. If there are any pointers that have been add'ed, but not - /// remove'd, big obnoxious warnings about memory leaks are issued. - /// - /// The specified message will be printed indicating when the check was - /// performed. - /// - static void checkForGarbage(LLVMContext &C, const std::string &Message) { -#ifndef NDEBUG - checkForGarbageImpl(C, Message); -#endif - } - - /// Overload the normal methods to work better with Value*'s because they are - /// by far the most common in LLVM. This does not affect the actual - /// functioning of this class, it just makes the warning messages nicer. - /// - static void addGarbageObject(const Value *Object) { -#ifndef NDEBUG - addGarbageObjectImpl(Object); -#endif - } - static void removeGarbageObject(const Value *Object) { -#ifndef NDEBUG - removeGarbageObjectImpl(Object); -#endif - } - -private: - // If we are debugging, the actual implementations will be called... - static void addGarbageObjectImpl(const Value *Object); - static void removeGarbageObjectImpl(const Value *Object); - static void addGarbageObjectImpl(void *Object); - static void removeGarbageObjectImpl(void *Object); - static void checkForGarbageImpl(LLVMContext &C, const std::string &Message); -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h new file mode 100644 index 0000000..7077656 --- /dev/null +++ b/include/llvm/Support/LineIterator.h @@ -0,0 +1,84 @@ +//===- LineIterator.h - Iterator to read a text buffer's lines --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_LINEITERATOR_H__ +#define LLVM_SUPPORT_LINEITERATOR_H__ + +#include "llvm/ADT/StringRef.h" +#include <iterator> + +namespace llvm { + +class MemoryBuffer; + +/// \brief A forward iterator which reads non-blank text lines from a buffer. +/// +/// This class provides a forward iterator interface for reading one line at +/// a time from a buffer. When default constructed the iterator will be the +/// "end" iterator. +/// +/// The iterator also is aware of what line number it is currently processing +/// and can strip comment lines given the comment-starting character. +/// +/// Note that this iterator requires the buffer to be nul terminated. +class line_iterator + : public std::iterator<std::forward_iterator_tag, StringRef, ptrdiff_t> { + const MemoryBuffer *Buffer; + char CommentMarker; + + unsigned LineNumber; + StringRef CurrentLine; + +public: + /// \brief Default construct an "end" iterator. + line_iterator() : Buffer(0) {} + + /// \brief Construct a new iterator around some memory buffer. + explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0'); + + /// \brief Return true if we've reached EOF or are an "end" iterator. + bool is_at_eof() const { return !Buffer; } + + /// \brief Return true if we're an "end" iterator or have reached EOF. + bool is_at_end() const { return is_at_eof(); } + + /// \brief Return the current line number. May return any number at EOF. + int64_t line_number() const { return LineNumber; } + + /// \brief Advance to the next (non-empty, non-comment) line. + line_iterator &operator++() { + advance(); + return *this; + } + line_iterator operator++(int) { + line_iterator tmp(*this); + advance(); + return tmp; + } + + /// \brief Get the current line as a \c StringRef. + StringRef operator*() const { return CurrentLine; } + const StringRef *operator->() const { return &CurrentLine; } + + friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) { + return LHS.Buffer == RHS.Buffer && + LHS.CurrentLine.begin() == RHS.CurrentLine.begin(); + } + + friend bool operator!=(const line_iterator &LHS, const line_iterator &RHS) { + return !(LHS == RHS); + } + +private: + /// \brief Advance the iterator to the next line. + void advance(); +}; +} + +#endif // LLVM_SUPPORT_LINEITERATOR_H__ diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h index b2b8c2d..4eb8507 100644 --- a/include/llvm/Support/MD5.h +++ b/include/llvm/Support/MD5.h @@ -28,13 +28,12 @@ #ifndef LLVM_SYSTEM_MD5_H #define LLVM_SYSTEM_MD5_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/DataTypes.h" namespace llvm { -template <typename T> class ArrayRef; - class MD5 { // Any 32-bit or wider unsigned integer data type will do. typedef uint32_t MD5_u32plus; diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 897a611..ef06a41 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -21,7 +21,7 @@ namespace llvm { namespace MachO { // Enums from <mach-o/loader.h> - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Constants for the "magic" field in llvm::MachO::mach_header and // llvm::MachO::mach_header_64 MH_MAGIC = 0xFEEDFACEu, @@ -76,12 +76,12 @@ namespace llvm { MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u }; - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Flags for the "cmd" field in llvm::MachO::load_command LC_REQ_DYLD = 0x80000000u }; - enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) { + enum LoadCommandType : uint32_t { // Constants for the "cmd" field in llvm::MachO::load_command LC_SEGMENT = 0x00000001u, LC_SYMTAB = 0x00000002u, @@ -128,10 +128,11 @@ namespace llvm { LC_SOURCE_VERSION = 0x0000002Au, LC_DYLIB_CODE_SIGN_DRS = 0x0000002Bu, // 0x0000002Cu, - LC_LINKER_OPTIONS = 0x0000002Du + LC_LINKER_OPTIONS = 0x0000002Du, + LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu }; - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Constant bits for the "flags" field in llvm::MachO::segment_command SG_HIGHVM = 0x1u, SG_FVMLIB = 0x2u, @@ -147,7 +148,9 @@ namespace llvm { SECTION_ATTRIBUTES_SYS = 0x00ffff00u // SECTION_ATTRIBUTES_SYS }; - enum SectionType { + /// These are the section type and attributes fields. A MachO section can + /// have only one Type, but can have any of the attributes specified. + enum SectionType : uint32_t { // Constant masks for the "flags[7:0]" field in llvm::MachO::section and // llvm::MachO::section_64 (mask "flags" with SECTION_TYPE) S_REGULAR = 0x00u, @@ -171,10 +174,12 @@ namespace llvm { S_THREAD_LOCAL_ZEROFILL = 0x12u, S_THREAD_LOCAL_VARIABLES = 0x13u, S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u, - S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u + S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u, + + LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS }; - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Constant masks for the "flags[31:24]" field in llvm::MachO::section and // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR) S_ATTR_PURE_INSTRUCTIONS = 0x80000000u, @@ -348,7 +353,7 @@ namespace llvm { N_LENG = 0xFEu }; - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Constant values for the r_symbolnum field in an // llvm::MachO::relocation_info structure when r_extern is 0. R_ABS = 0, @@ -403,6 +408,34 @@ namespace llvm { ARM_RELOC_HALF = 8, ARM_RELOC_HALF_SECTDIFF = 9, + // Constant values for the r_type field in an ARM64 architecture + // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info + // structure. + + // For pointers. + ARM64_RELOC_UNSIGNED = 0, + // Must be followed by an ARM64_RELOC_UNSIGNED + ARM64_RELOC_SUBTRACTOR = 1, + // A B/BL instruction with 26-bit displacement. + ARM64_RELOC_BRANCH26 = 2, + // PC-rel distance to page of target. + ARM64_RELOC_PAGE21 = 3, + // Offset within page, scaled by r_length. + ARM64_RELOC_PAGEOFF12 = 4, + // PC-rel distance to page of GOT slot. + ARM64_RELOC_GOT_LOAD_PAGE21 = 5, + // Offset within page of GOT slot, scaled by r_length. + ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6, + // For pointers to GOT slots. + ARM64_RELOC_POINTER_TO_GOT = 7, + // PC-rel distance to page of TLVP slot. + ARM64_RELOC_TLVP_LOAD_PAGE21 = 8, + // Offset within page of TLVP slot, scaled by r_length. + ARM64_RELOC_TLVP_LOAD_PAGEOFF12 = 9, + // Must be followed by ARM64_RELOC_PAGE21 or ARM64_RELOC_PAGEOFF12. + ARM64_RELOC_ADDEND = 10, + + // Constant values for the r_type field in an x86_64 architecture // llvm::MachO::relocation_info or llvm::MachO::scattered_relocation_info // structure @@ -739,9 +772,10 @@ namespace llvm { }; struct version_min_command { - uint32_t cmd; - uint32_t cmdsize; - uint32_t version; + uint32_t cmd; // LC_VERSION_MIN_MACOSX or + // LC_VERSION_MIN_IPHONEOS + uint32_t cmdsize; // sizeof(struct version_min_command) + uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz uint32_t reserved; }; @@ -893,7 +927,7 @@ namespace llvm { } // Enums from <mach/machine.h> - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Capability bits used in the definition of cpu_type. CPU_ARCH_MASK = 0xff000000, // Mask for architecture bits CPU_ARCH_ABI64 = 0x01000000 // 64 bit ABI @@ -908,12 +942,13 @@ namespace llvm { /* CPU_TYPE_MIPS = 8, */ CPU_TYPE_MC98000 = 10, // Old Motorola PowerPC CPU_TYPE_ARM = 12, + CPU_TYPE_ARM64 = CPU_TYPE_ARM | CPU_ARCH_ABI64, CPU_TYPE_SPARC = 14, CPU_TYPE_POWERPC = 18, CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64 }; - enum LLVM_ENUM_INT_TYPE(uint32_t) { + enum : uint32_t { // Capability bits used in the definition of cpusubtype. CPU_SUB_TYPE_MASK = 0xff000000, // Mask for architecture bits CPU_SUB_TYPE_LIB64 = 0x80000000, // 64 bit libraries @@ -973,7 +1008,7 @@ namespace llvm { CPU_SUBTYPE_ARM_V5TEJ = 7, CPU_SUBTYPE_ARM_XSCALE = 8, CPU_SUBTYPE_ARM_V7 = 9, - CPU_SUBTYPE_ARM_V7F = 10, + // unused ARM_V7F = 10, CPU_SUBTYPE_ARM_V7S = 11, CPU_SUBTYPE_ARM_V7K = 12, CPU_SUBTYPE_ARM_V6M = 14, @@ -981,6 +1016,10 @@ namespace llvm { CPU_SUBTYPE_ARM_V7EM = 16 }; + enum CPUSubTypeARM64 { + CPU_SUBTYPE_ARM64_ALL = 0 + }; + enum CPUSubTypeSPARC { CPU_SUBTYPE_SPARC_ALL = 0 }; diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index ff41608..f1f7b4f 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -16,9 +16,9 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/type_traits.h" - +#include <cassert> #include <cstring> +#include <type_traits> #ifdef _MSC_VER #include <intrin.h> @@ -44,8 +44,8 @@ enum ZeroBehavior { /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, std::size_t>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, std::size_t>::type countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { (void)ZB; @@ -71,8 +71,8 @@ countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) { // Disable signed. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, std::size_t>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, std::size_t>::type countTrailingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION; #if __GNUC__ >= 4 || _MSC_VER @@ -115,8 +115,8 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { /// \param ZB the behavior on an input of 0. Only ZB_Width and ZB_Undefined are /// valid arguments. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, std::size_t>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, std::size_t>::type countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { (void)ZB; @@ -137,8 +137,8 @@ countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) { // Disable signed. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, std::size_t>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, std::size_t>::type countLeadingZeros(T Val, ZeroBehavior ZB = ZB_Width) LLVM_DELETED_FUNCTION; #if __GNUC__ >= 4 || _MSC_VER @@ -181,8 +181,8 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// valid arguments. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, T>::type findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return std::numeric_limits<T>::max(); @@ -192,8 +192,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) { // Disable signed. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, T>::type findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION; /// \brief Get the index of the last set bit starting from the least @@ -204,8 +204,8 @@ findFirstSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION; /// \param ZB the behavior on an input of 0. Only ZB_Max and ZB_Undefined are /// valid arguments. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + !std::numeric_limits<T>::is_signed, T>::type findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { if (ZB == ZB_Max && Val == 0) return std::numeric_limits<T>::max(); @@ -218,8 +218,8 @@ findLastSet(T Val, ZeroBehavior ZB = ZB_Max) { // Disable signed. template <typename T> -typename enable_if_c<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, T>::type +typename std::enable_if<std::numeric_limits<T>::is_integer && + std::numeric_limits<T>::is_signed, T>::type findLastSet(T Val, ZeroBehavior ZB = ZB_Max) LLVM_DELETED_FUNCTION; /// \brief Macro compressed bit reversal table for 256 bits. @@ -541,6 +541,18 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) { return (A | B) & (1 + ~(A | B)); } +/// \brief Aligns \c Ptr to \c Alignment bytes, rounding up. +/// +/// Alignment should be a power of two. This method rounds up, so +/// AlignPtr(7, 4) == 8 and AlignPtr(8, 4) == 8. +inline char *alignPtr(char *Ptr, size_t Alignment) { + assert(Alignment && isPowerOf2_64((uint64_t)Alignment) && + "Alignment is not a power of two!"); + + return (char *)(((uintptr_t)Ptr + Alignment - 1) & + ~(uintptr_t)(Alignment - 1)); +} + /// NextPowerOf2 - Returns the next power of two (in 64-bits) /// that is strictly greater than A. Returns zero on overflow. inline uint64_t NextPowerOf2(uint64_t A) { @@ -553,6 +565,13 @@ inline uint64_t NextPowerOf2(uint64_t A) { return A + 1; } +/// Returns the power of two which is less than or equal to the given value. +/// Essentially, it is a floor operation across the domain of powers of two. +inline uint64_t PowerOf2Floor(uint64_t A) { + if (!A) return 0; + return 1ull << (63 - countLeadingZeros(A, ZB_Undefined)); +} + /// Returns the next integer (mod 2**64) that is greater than or equal to /// \p Value and is a multiple of \p Align. \p Align must be non-zero. /// diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h index a08c796..8251fcd 100644 --- a/include/llvm/Support/Memory.h +++ b/include/llvm/Support/Memory.h @@ -95,7 +95,7 @@ namespace sys { /// memory was not allocated using the allocateMappedMemory method. /// \p Block describes the memory block to be protected. /// \p Flags specifies the new protection state to be assigned to the block. - /// \p ErrMsg [out] returns a string describing any error that occured. + /// \p ErrMsg [out] returns a string describing any error that occurred. /// /// If \p Flags is MF_WRITE, the actual behavior varies /// with the operating system (i.e. MF_READ | MF_WRITE on Windows) and the diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index ff22fb6..578c7e8 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -14,11 +14,12 @@ #ifndef LLVM_SUPPORT_MEMORYBUFFER_H #define LLVM_SUPPORT_MEMORYBUFFER_H +#include "llvm-c/Support.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" -#include "llvm-c/Core.h" +#include <memory> namespace llvm { @@ -66,7 +67,11 @@ public: /// MemoryBuffer if successful, otherwise returning null. If FileSize is /// specified, this means that the client knows that the file exists and that /// it has the specified size. - static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &result, + static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &Result, + int64_t FileSize = -1, + bool RequiresNullTerminator = true); + static error_code getFile(Twine Filename, + std::unique_ptr<MemoryBuffer> &Result, int64_t FileSize = -1, bool RequiresNullTerminator = true); @@ -76,6 +81,9 @@ public: static error_code getOpenFileSlice(int FD, const char *Filename, OwningPtr<MemoryBuffer> &Result, uint64_t MapSize, int64_t Offset); + static error_code getOpenFileSlice(int FD, const char *Filename, + std::unique_ptr<MemoryBuffer> &Result, + uint64_t MapSize, int64_t Offset); /// Given an already-open file descriptor, read the file and return a /// MemoryBuffer. @@ -83,6 +91,10 @@ public: OwningPtr<MemoryBuffer> &Result, uint64_t FileSize, bool RequiresNullTerminator = true); + static error_code getOpenFile(int FD, const char *Filename, + std::unique_ptr<MemoryBuffer> &Result, + uint64_t FileSize, + bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note /// that InputData must be null terminated if RequiresNullTerminator is true. @@ -111,14 +123,18 @@ public: /// getSTDIN - Read all of stdin into a file buffer, and return it. /// If an error occurs, this returns null and sets ec. - static error_code getSTDIN(OwningPtr<MemoryBuffer> &result); + static error_code getSTDIN(OwningPtr<MemoryBuffer> &Result); + static error_code getSTDIN(std::unique_ptr<MemoryBuffer> &Result); /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin /// if the Filename is "-". If an error occurs, this returns null and sets /// ec. static error_code getFileOrSTDIN(StringRef Filename, - OwningPtr<MemoryBuffer> &result, + OwningPtr<MemoryBuffer> &Result, + int64_t FileSize = -1); + static error_code getFileOrSTDIN(StringRef Filename, + std::unique_ptr<MemoryBuffer> &Result, int64_t FileSize = -1); //===--------------------------------------------------------------------===// diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h deleted file mode 100644 index ecfbbaa..0000000 --- a/include/llvm/Support/NoFolder.h +++ /dev/null @@ -1,298 +0,0 @@ -//======-- llvm/Support/NoFolder.h - Constant folding helper -*- C++ -*-======// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the NoFolder class, a helper for IRBuilder. It provides -// IRBuilder with a set of methods for creating unfolded constants. This is -// useful for learners trying to understand how LLVM IR works, and who don't -// want details to be hidden by the constant folder. For general constant -// creation and folding, use ConstantExpr and the routines in -// llvm/Analysis/ConstantFolding.h. -// -// Note: since it is not actually possible to create unfolded constants, this -// class returns instructions rather than constants. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_NOFOLDER_H -#define LLVM_SUPPORT_NOFOLDER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/Instructions.h" - -namespace llvm { - -/// NoFolder - Create "constants" (actually, instructions) with no folding. -class NoFolder { -public: - explicit NoFolder() {} - - //===--------------------------------------------------------------------===// - // Binary Operators - //===--------------------------------------------------------------------===// - - Instruction *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNSWAdd(LHS, RHS); - } - Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNUWAdd(LHS, RHS); - } - Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateFAdd(LHS, RHS); - } - Instruction *CreateSub(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNSWSub(LHS, RHS); - } - Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNUWSub(LHS, RHS); - } - Instruction *CreateFSub(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateFSub(LHS, RHS); - } - Instruction *CreateMul(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNSWMul(LHS, RHS); - } - Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateNUWMul(LHS, RHS); - } - Instruction *CreateFMul(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateFMul(LHS, RHS); - } - Instruction *CreateUDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) - return BinaryOperator::CreateUDiv(LHS, RHS); - return BinaryOperator::CreateExactUDiv(LHS, RHS); - } - Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateExactUDiv(LHS, RHS); - } - Instruction *CreateSDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) - return BinaryOperator::CreateSDiv(LHS, RHS); - return BinaryOperator::CreateExactSDiv(LHS, RHS); - } - Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateExactSDiv(LHS, RHS); - } - Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateFDiv(LHS, RHS); - } - Instruction *CreateURem(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateURem(LHS, RHS); - } - Instruction *CreateSRem(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateSRem(LHS, RHS); - } - Instruction *CreateFRem(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateFRem(LHS, RHS); - } - Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false, - bool HasNSW = false) const { - BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateLShr(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) - return BinaryOperator::CreateLShr(LHS, RHS); - return BinaryOperator::CreateExactLShr(LHS, RHS); - } - Instruction *CreateAShr(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) - return BinaryOperator::CreateAShr(LHS, RHS); - return BinaryOperator::CreateExactAShr(LHS, RHS); - } - Instruction *CreateAnd(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateAnd(LHS, RHS); - } - Instruction *CreateOr(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateOr(LHS, RHS); - } - Instruction *CreateXor(Constant *LHS, Constant *RHS) const { - return BinaryOperator::CreateXor(LHS, RHS); - } - - Instruction *CreateBinOp(Instruction::BinaryOps Opc, - Constant *LHS, Constant *RHS) const { - return BinaryOperator::Create(Opc, LHS, RHS); - } - - //===--------------------------------------------------------------------===// - // Unary Operators - //===--------------------------------------------------------------------===// - - Instruction *CreateNeg(Constant *C, - bool HasNUW = false, bool HasNSW = false) const { - BinaryOperator *BO = BinaryOperator::CreateNeg(C); - if (HasNUW) BO->setHasNoUnsignedWrap(); - if (HasNSW) BO->setHasNoSignedWrap(); - return BO; - } - Instruction *CreateNSWNeg(Constant *C) const { - return BinaryOperator::CreateNSWNeg(C); - } - Instruction *CreateNUWNeg(Constant *C) const { - return BinaryOperator::CreateNUWNeg(C); - } - Instruction *CreateFNeg(Constant *C) const { - return BinaryOperator::CreateFNeg(C); - } - Instruction *CreateNot(Constant *C) const { - return BinaryOperator::CreateNot(C); - } - - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return ConstantExpr::getGetElementPtr(C, IdxList); - } - Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return ConstantExpr::getGetElementPtr(C, Idx); - } - Instruction *CreateGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return GetElementPtrInst::Create(C, IdxList); - } - - Constant *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); - } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return ConstantExpr::getInBoundsGetElementPtr(C, Idx); - } - Instruction *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return GetElementPtrInst::CreateInBounds(C, IdxList); - } - - //===--------------------------------------------------------------------===// - // Cast/Conversion Operators - //===--------------------------------------------------------------------===// - - Instruction *CreateCast(Instruction::CastOps Op, Constant *C, - Type *DestTy) const { - return CastInst::Create(Op, C, DestTy); - } - Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { - return CastInst::CreatePointerCast(C, DestTy); - } - Instruction *CreateIntCast(Constant *C, Type *DestTy, - bool isSigned) const { - return CastInst::CreateIntegerCast(C, DestTy, isSigned); - } - Instruction *CreateFPCast(Constant *C, Type *DestTy) const { - return CastInst::CreateFPCast(C, DestTy); - } - - Instruction *CreateBitCast(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::BitCast, C, DestTy); - } - Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::IntToPtr, C, DestTy); - } - Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::PtrToInt, C, DestTy); - } - Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { - return CastInst::CreateZExtOrBitCast(C, DestTy); - } - Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { - return CastInst::CreateSExtOrBitCast(C, DestTy); - } - - Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { - return CastInst::CreateTruncOrBitCast(C, DestTy); - } - - //===--------------------------------------------------------------------===// - // Compare Instructions - //===--------------------------------------------------------------------===// - - Instruction *CreateICmp(CmpInst::Predicate P, - Constant *LHS, Constant *RHS) const { - return new ICmpInst(P, LHS, RHS); - } - Instruction *CreateFCmp(CmpInst::Predicate P, - Constant *LHS, Constant *RHS) const { - return new FCmpInst(P, LHS, RHS); - } - - //===--------------------------------------------------------------------===// - // Other Instructions - //===--------------------------------------------------------------------===// - - Instruction *CreateSelect(Constant *C, - Constant *True, Constant *False) const { - return SelectInst::Create(C, True, False); - } - - Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const { - return ExtractElementInst::Create(Vec, Idx); - } - - Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt, - Constant *Idx) const { - return InsertElementInst::Create(Vec, NewElt, Idx); - } - - Instruction *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const { - return new ShuffleVectorInst(V1, V2, Mask); - } - - Instruction *CreateExtractValue(Constant *Agg, - ArrayRef<unsigned> IdxList) const { - return ExtractValueInst::Create(Agg, IdxList); - } - - Instruction *CreateInsertValue(Constant *Agg, Constant *Val, - ArrayRef<unsigned> IdxList) const { - return InsertValueInst::Create(Agg, Val, IdxList); - } -}; - -} - -#endif diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h deleted file mode 100644 index c0914b1..0000000 --- a/include/llvm/Support/PassNameParser.h +++ /dev/null @@ -1,136 +0,0 @@ -//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the PassNameParser and FilteredPassNameParser<> classes, -// which are used to add command line arguments to a utility for all of the -// passes that have been registered into the system. -// -// The PassNameParser class adds ALL passes linked into the system (that are -// creatable) as command line arguments to the tool (when instantiated with the -// appropriate command line option template). The FilteredPassNameParser<> -// template is used for the same purposes as PassNameParser, except that it only -// includes passes that have a PassType that are compatible with the filter -// (which is the template argument). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H -#define LLVM_SUPPORT_PASSNAMEPARSER_H - -#include "llvm/ADT/STLExtras.h" -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include <cstring> - -namespace llvm { - -//===----------------------------------------------------------------------===// -// PassNameParser class - Make use of the pass registration mechanism to -// automatically add a command line argument to opt for each pass. -// -class PassNameParser : public PassRegistrationListener, - public cl::parser<const PassInfo*> { - cl::Option *Opt; -public: - PassNameParser() : Opt(0) {} - virtual ~PassNameParser(); - - void initialize(cl::Option &O) { - Opt = &O; - cl::parser<const PassInfo*>::initialize(O); - - // Add all of the passes to the map that got initialized before 'this' did. - enumeratePasses(); - } - - // ignorablePassImpl - Can be overriden in subclasses to refine the list of - // which passes we want to include. - // - virtual bool ignorablePassImpl(const PassInfo *P) const { return false; } - - inline bool ignorablePass(const PassInfo *P) const { - // Ignore non-selectable and non-constructible passes! Ignore - // non-optimizations. - return P->getPassArgument() == 0 || *P->getPassArgument() == 0 || - P->getNormalCtor() == 0 || ignorablePassImpl(P); - } - - // Implement the PassRegistrationListener callbacks used to populate our map - // - virtual void passRegistered(const PassInfo *P) { - if (ignorablePass(P) || !Opt) return; - if (findOption(P->getPassArgument()) != getNumOptions()) { - errs() << "Two passes with the same argument (-" - << P->getPassArgument() << ") attempted to be registered!\n"; - llvm_unreachable(0); - } - addLiteralOption(P->getPassArgument(), P, P->getPassName()); - } - virtual void passEnumerate(const PassInfo *P) { passRegistered(P); } - - // printOptionInfo - Print out information about this option. Override the - // default implementation to sort the table before we print... - virtual void printOptionInfo(const cl::Option &O, size_t GlobalWidth) const { - PassNameParser *PNP = const_cast<PassNameParser*>(this); - array_pod_sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan); - cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth); - } - -private: - // ValLessThan - Provide a sorting comparator for Values elements... - static int ValLessThan(const PassNameParser::OptionInfo *VT1, - const PassNameParser::OptionInfo *VT2) { - return std::strcmp(VT1->Name, VT2->Name); - } -}; - -///===----------------------------------------------------------------------===// -/// FilteredPassNameParser class - Make use of the pass registration -/// mechanism to automatically add a command line argument to opt for -/// each pass that satisfies a filter criteria. Filter should return -/// true for passes to be registered as command-line options. -/// -template<typename Filter> -class FilteredPassNameParser : public PassNameParser { -private: - Filter filter; - -public: - bool ignorablePassImpl(const PassInfo *P) const { return !filter(*P); } -}; - -///===----------------------------------------------------------------------===// -/// PassArgFilter - A filter for use with PassNameFilterParser that only -/// accepts a Pass whose Arg matches certain strings. -/// -/// Use like this: -/// -/// extern const char AllowedPassArgs[] = "-anders_aa -dse"; -/// -/// static cl::list< -/// const PassInfo*, -/// bool, -/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > > -/// PassList(cl::desc("Passes available:")); -/// -/// Only the -anders_aa and -dse options will be available to the user. -/// -template<const char *Args> -class PassArgFilter { -public: - bool operator()(const PassInfo &P) const { - return(std::strstr(Args, P.getPassArgument())); - } -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h index b2afe1b..ba18529 100644 --- a/include/llvm/Support/Path.h +++ b/include/llvm/Support/Path.h @@ -306,6 +306,12 @@ bool is_separator(char value); /// @param result Holds the resulting path name. void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); +/// @brief Get the user's home directory. +/// +/// @param result Holds the resulting path name. +/// @result True if a home directory is set, false otherwise. +bool home_directory(SmallVectorImpl<char> &result); + /// @brief Has root name? /// /// root_name != "" diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h deleted file mode 100644 index 240bb81..0000000 --- a/include/llvm/Support/PatternMatch.h +++ /dev/null @@ -1,1121 +0,0 @@ -//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides a simple and efficient mechanism for performing general -// tree-based pattern matches on the LLVM IR. The power of these routines is -// that it allows you to write concise patterns that are expressive and easy to -// understand. The other major advantage of this is that it allows you to -// trivially capture/bind elements in the pattern to variables. For example, -// you can do something like this: -// -// Value *Exp = ... -// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2) -// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)), -// m_And(m_Value(Y), m_ConstantInt(C2))))) { -// ... Pattern is matched and variables are bound ... -// } -// -// This is primarily useful to things like the instruction combiner, but can -// also be useful for static analysis tools or code generators. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PATTERNMATCH_H -#define LLVM_SUPPORT_PATTERNMATCH_H - -#include "llvm/IR/Constants.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/Operator.h" -#include "llvm/Support/CallSite.h" - -namespace llvm { -namespace PatternMatch { - -template<typename Val, typename Pattern> -bool match(Val *V, const Pattern &P) { - return const_cast<Pattern&>(P).match(V); -} - - -template<typename SubPattern_t> -struct OneUse_match { - SubPattern_t SubPattern; - - OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {} - - template<typename OpTy> - bool match(OpTy *V) { - return V->hasOneUse() && SubPattern.match(V); - } -}; - -template<typename T> -inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; } - - -template<typename Class> -struct class_match { - template<typename ITy> - bool match(ITy *V) { return isa<Class>(V); } -}; - -/// m_Value() - Match an arbitrary value and ignore it. -inline class_match<Value> m_Value() { return class_match<Value>(); } -/// m_ConstantInt() - Match an arbitrary ConstantInt and ignore it. -inline class_match<ConstantInt> m_ConstantInt() { - return class_match<ConstantInt>(); -} -/// m_Undef() - Match an arbitrary undef constant. -inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); } - -inline class_match<Constant> m_Constant() { return class_match<Constant>(); } - -/// Matching combinators -template<typename LTy, typename RTy> -struct match_combine_or { - LTy L; - RTy R; - - match_combine_or(const LTy &Left, const RTy &Right) : L(Left), R(Right) { } - - template<typename ITy> - bool match(ITy *V) { - if (L.match(V)) - return true; - if (R.match(V)) - return true; - return false; - } -}; - -template<typename LTy, typename RTy> -struct match_combine_and { - LTy L; - RTy R; - - match_combine_and(const LTy &Left, const RTy &Right) : L(Left), R(Right) { } - - template<typename ITy> - bool match(ITy *V) { - if (L.match(V)) - if (R.match(V)) - return true; - return false; - } -}; - -/// Combine two pattern matchers matching L || R -template<typename LTy, typename RTy> -inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R) { - return match_combine_or<LTy, RTy>(L, R); -} - -/// Combine two pattern matchers matching L && R -template<typename LTy, typename RTy> -inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) { - return match_combine_and<LTy, RTy>(L, R); -} - -struct match_zero { - template<typename ITy> - bool match(ITy *V) { - if (const Constant *C = dyn_cast<Constant>(V)) - return C->isNullValue(); - return false; - } -}; - -/// m_Zero() - Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. -inline match_zero m_Zero() { return match_zero(); } - -struct match_neg_zero { - template<typename ITy> - bool match(ITy *V) { - if (const Constant *C = dyn_cast<Constant>(V)) - return C->isNegativeZeroValue(); - return false; - } -}; - -/// m_NegZero() - Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. For -/// floating point constants, this will match negative zero but not positive -/// zero -inline match_neg_zero m_NegZero() { return match_neg_zero(); } - -/// m_AnyZero() - Match an arbitrary zero/null constant. This includes -/// zero_initializer for vectors and ConstantPointerNull for pointers. For -/// floating point constants, this will match negative zero and positive zero -inline match_combine_or<match_zero, match_neg_zero> m_AnyZero() { - return m_CombineOr(m_Zero(), m_NegZero()); -} - -struct apint_match { - const APInt *&Res; - apint_match(const APInt *&R) : Res(R) {} - template<typename ITy> - bool match(ITy *V) { - if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { - Res = &CI->getValue(); - return true; - } - if (V->getType()->isVectorTy()) - if (const Constant *C = dyn_cast<Constant>(V)) - if (ConstantInt *CI = - dyn_cast_or_null<ConstantInt>(C->getSplatValue())) { - Res = &CI->getValue(); - return true; - } - return false; - } -}; - -/// m_APInt - Match a ConstantInt or splatted ConstantVector, binding the -/// specified pointer to the contained APInt. -inline apint_match m_APInt(const APInt *&Res) { return Res; } - - -template<int64_t Val> -struct constantint_match { - template<typename ITy> - bool match(ITy *V) { - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { - const APInt &CIV = CI->getValue(); - if (Val >= 0) - return CIV == static_cast<uint64_t>(Val); - // If Val is negative, and CI is shorter than it, truncate to the right - // number of bits. If it is larger, then we have to sign extend. Just - // compare their negated values. - return -CIV == -Val; - } - return false; - } -}; - -/// m_ConstantInt<int64_t> - Match a ConstantInt with a specific value. -template<int64_t Val> -inline constantint_match<Val> m_ConstantInt() { - return constantint_match<Val>(); -} - -/// cst_pred_ty - This helper class is used to match scalar and vector constants -/// that satisfy a specified predicate. -template<typename Predicate> -struct cst_pred_ty : public Predicate { - template<typename ITy> - bool match(ITy *V) { - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) - return this->isValue(CI->getValue()); - if (V->getType()->isVectorTy()) - if (const Constant *C = dyn_cast<Constant>(V)) - if (const ConstantInt *CI = - dyn_cast_or_null<ConstantInt>(C->getSplatValue())) - return this->isValue(CI->getValue()); - return false; - } -}; - -/// api_pred_ty - This helper class is used to match scalar and vector constants -/// that satisfy a specified predicate, and bind them to an APInt. -template<typename Predicate> -struct api_pred_ty : public Predicate { - const APInt *&Res; - api_pred_ty(const APInt *&R) : Res(R) {} - template<typename ITy> - bool match(ITy *V) { - if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - if (V->getType()->isVectorTy()) - if (const Constant *C = dyn_cast<Constant>(V)) - if (ConstantInt *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - - return false; - } -}; - - -struct is_one { - bool isValue(const APInt &C) { return C == 1; } -}; - -/// m_One() - Match an integer 1 or a vector with all elements equal to 1. -inline cst_pred_ty<is_one> m_One() { return cst_pred_ty<is_one>(); } -inline api_pred_ty<is_one> m_One(const APInt *&V) { return V; } - -struct is_all_ones { - bool isValue(const APInt &C) { return C.isAllOnesValue(); } -}; - -/// m_AllOnes() - Match an integer or vector with all bits set to true. -inline cst_pred_ty<is_all_ones> m_AllOnes() {return cst_pred_ty<is_all_ones>();} -inline api_pred_ty<is_all_ones> m_AllOnes(const APInt *&V) { return V; } - -struct is_sign_bit { - bool isValue(const APInt &C) { return C.isSignBit(); } -}; - -/// m_SignBit() - Match an integer or vector with only the sign bit(s) set. -inline cst_pred_ty<is_sign_bit> m_SignBit() {return cst_pred_ty<is_sign_bit>();} -inline api_pred_ty<is_sign_bit> m_SignBit(const APInt *&V) { return V; } - -struct is_power2 { - bool isValue(const APInt &C) { return C.isPowerOf2(); } -}; - -/// m_Power2() - Match an integer or vector power of 2. -inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); } -inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; } - -template<typename Class> -struct bind_ty { - Class *&VR; - bind_ty(Class *&V) : VR(V) {} - - template<typename ITy> - bool match(ITy *V) { - if (Class *CV = dyn_cast<Class>(V)) { - VR = CV; - return true; - } - return false; - } -}; - -/// m_Value - Match a value, capturing it if we match. -inline bind_ty<Value> m_Value(Value *&V) { return V; } - -/// m_ConstantInt - Match a ConstantInt, capturing the value if we match. -inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; } - -/// m_Constant - Match a Constant, capturing the value if we match. -inline bind_ty<Constant> m_Constant(Constant *&C) { return C; } - -/// m_ConstantFP - Match a ConstantFP, capturing the value if we match. -inline bind_ty<ConstantFP> m_ConstantFP(ConstantFP *&C) { return C; } - -/// specificval_ty - Match a specified Value*. -struct specificval_ty { - const Value *Val; - specificval_ty(const Value *V) : Val(V) {} - - template<typename ITy> - bool match(ITy *V) { - return V == Val; - } -}; - -/// m_Specific - Match if we have a specific specified value. -inline specificval_ty m_Specific(const Value *V) { return V; } - -/// Match a specified floating point value or vector of all elements of that -/// value. -struct specific_fpval { - double Val; - specific_fpval(double V) : Val(V) {} - - template<typename ITy> - bool match(ITy *V) { - if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) - return CFP->isExactlyValue(Val); - if (V->getType()->isVectorTy()) - if (const Constant *C = dyn_cast<Constant>(V)) - if (ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(C->getSplatValue())) - return CFP->isExactlyValue(Val); - return false; - } -}; - -/// Match a specific floating point value or vector with all elements equal to -/// the value. -inline specific_fpval m_SpecificFP(double V) { return specific_fpval(V); } - -/// Match a float 1.0 or vector with all elements equal to 1.0. -inline specific_fpval m_FPOne() { return m_SpecificFP(1.0); } - -struct bind_const_intval_ty { - uint64_t &VR; - bind_const_intval_ty(uint64_t &V) : VR(V) {} - - template<typename ITy> - bool match(ITy *V) { - if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) - if (CV->getBitWidth() <= 64) { - VR = CV->getZExtValue(); - return true; - } - return false; - } -}; - -/// m_ConstantInt - Match a ConstantInt and bind to its value. This does not -/// match ConstantInts wider than 64-bits. -inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } - -//===----------------------------------------------------------------------===// -// Matchers for specific binary operators. -// - -template<typename LHS_t, typename RHS_t, unsigned Opcode> -struct BinaryOp_match { - LHS_t L; - RHS_t R; - - BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (V->getValueID() == Value::InstructionVal + Opcode) { - BinaryOperator *I = cast<BinaryOperator>(V); - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); - } - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) - return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) && - R.match(CE->getOperand(1)); - return false; - } -}; - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Add> -m_Add(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::FAdd> -m_FAdd(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::FAdd>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Sub> -m_Sub(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::FSub> -m_FSub(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::FSub>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Mul> -m_Mul(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::FMul> -m_FMul(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::FMul>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::UDiv> -m_UDiv(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::SDiv> -m_SDiv(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::FDiv> -m_FDiv(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::URem> -m_URem(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::SRem> -m_SRem(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::FRem> -m_FRem(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::And> -m_And(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::And>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Or> -m_Or(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Xor> -m_Xor(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::Shl> -m_Shl(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::LShr> -m_LShr(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R); -} - -template<typename LHS, typename RHS> -inline BinaryOp_match<LHS, RHS, Instruction::AShr> -m_AShr(const LHS &L, const RHS &R) { - return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R); -} - -//===----------------------------------------------------------------------===// -// Class that matches two different binary ops. -// -template<typename LHS_t, typename RHS_t, unsigned Opc1, unsigned Opc2> -struct BinOp2_match { - LHS_t L; - RHS_t R; - - BinOp2_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (V->getValueID() == Value::InstructionVal + Opc1 || - V->getValueID() == Value::InstructionVal + Opc2) { - BinaryOperator *I = cast<BinaryOperator>(V); - return L.match(I->getOperand(0)) && R.match(I->getOperand(1)); - } - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) - return (CE->getOpcode() == Opc1 || CE->getOpcode() == Opc2) && - L.match(CE->getOperand(0)) && R.match(CE->getOperand(1)); - return false; - } -}; - -/// m_Shr - Matches LShr or AShr. -template<typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr> -m_Shr(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::AShr>(L, R); -} - -/// m_LogicalShift - Matches LShr or Shl. -template<typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl> -m_LogicalShift(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::LShr, Instruction::Shl>(L, R); -} - -/// m_IDiv - Matches UDiv and SDiv. -template<typename LHS, typename RHS> -inline BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv> -m_IDiv(const LHS &L, const RHS &R) { - return BinOp2_match<LHS, RHS, Instruction::SDiv, Instruction::UDiv>(L, R); -} - -//===----------------------------------------------------------------------===// -// Class that matches exact binary ops. -// -template<typename SubPattern_t> -struct Exact_match { - SubPattern_t SubPattern; - - Exact_match(const SubPattern_t &SP) : SubPattern(SP) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (PossiblyExactOperator *PEO = dyn_cast<PossiblyExactOperator>(V)) - return PEO->isExact() && SubPattern.match(V); - return false; - } -}; - -template<typename T> -inline Exact_match<T> m_Exact(const T &SubPattern) { return SubPattern; } - -//===----------------------------------------------------------------------===// -// Matchers for CmpInst classes -// - -template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy> -struct CmpClass_match { - PredicateTy &Predicate; - LHS_t L; - RHS_t R; - - CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS) - : Predicate(Pred), L(LHS), R(RHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (Class *I = dyn_cast<Class>(V)) - if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) { - Predicate = I->getPredicate(); - return true; - } - return false; - } -}; - -template<typename LHS, typename RHS> -inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate> -m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) { - return CmpClass_match<LHS, RHS, - ICmpInst, ICmpInst::Predicate>(Pred, L, R); -} - -template<typename LHS, typename RHS> -inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate> -m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) { - return CmpClass_match<LHS, RHS, - FCmpInst, FCmpInst::Predicate>(Pred, L, R); -} - -//===----------------------------------------------------------------------===// -// Matchers for SelectInst classes -// - -template<typename Cond_t, typename LHS_t, typename RHS_t> -struct SelectClass_match { - Cond_t C; - LHS_t L; - RHS_t R; - - SelectClass_match(const Cond_t &Cond, const LHS_t &LHS, - const RHS_t &RHS) - : C(Cond), L(LHS), R(RHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (SelectInst *I = dyn_cast<SelectInst>(V)) - return C.match(I->getOperand(0)) && - L.match(I->getOperand(1)) && - R.match(I->getOperand(2)); - return false; - } -}; - -template<typename Cond, typename LHS, typename RHS> -inline SelectClass_match<Cond, LHS, RHS> -m_Select(const Cond &C, const LHS &L, const RHS &R) { - return SelectClass_match<Cond, LHS, RHS>(C, L, R); -} - -/// m_SelectCst - This matches a select of two constants, e.g.: -/// m_SelectCst<-1, 0>(m_Value(V)) -template<int64_t L, int64_t R, typename Cond> -inline SelectClass_match<Cond, constantint_match<L>, constantint_match<R> > -m_SelectCst(const Cond &C) { - return m_Select(C, m_ConstantInt<L>(), m_ConstantInt<R>()); -} - - -//===----------------------------------------------------------------------===// -// Matchers for CastInst classes -// - -template<typename Op_t, unsigned Opcode> -struct CastClass_match { - Op_t Op; - - CastClass_match(const Op_t &OpMatch) : Op(OpMatch) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (Operator *O = dyn_cast<Operator>(V)) - return O->getOpcode() == Opcode && Op.match(O->getOperand(0)); - return false; - } -}; - -/// m_BitCast -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::BitCast> -m_BitCast(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::BitCast>(Op); -} - -/// m_PtrToInt -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::PtrToInt> -m_PtrToInt(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::PtrToInt>(Op); -} - -/// m_Trunc -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::Trunc> -m_Trunc(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::Trunc>(Op); -} - -/// m_SExt -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::SExt> -m_SExt(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::SExt>(Op); -} - -/// m_ZExt -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::ZExt> -m_ZExt(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::ZExt>(Op); -} - -/// m_UIToFP -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::UIToFP> -m_UIToFP(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::UIToFP>(Op); -} - -/// m_SIToFP -template<typename OpTy> -inline CastClass_match<OpTy, Instruction::SIToFP> -m_SIToFP(const OpTy &Op) { - return CastClass_match<OpTy, Instruction::SIToFP>(Op); -} - -//===----------------------------------------------------------------------===// -// Matchers for unary operators -// - -template<typename LHS_t> -struct not_match { - LHS_t L; - - not_match(const LHS_t &LHS) : L(LHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (Operator *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::Xor) - return matchIfNot(O->getOperand(0), O->getOperand(1)); - return false; - } -private: - bool matchIfNot(Value *LHS, Value *RHS) { - return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) || - // FIXME: Remove CV. - isa<ConstantVector>(RHS)) && - cast<Constant>(RHS)->isAllOnesValue() && - L.match(LHS); - } -}; - -template<typename LHS> -inline not_match<LHS> m_Not(const LHS &L) { return L; } - - -template<typename LHS_t> -struct neg_match { - LHS_t L; - - neg_match(const LHS_t &LHS) : L(LHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (Operator *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::Sub) - return matchIfNeg(O->getOperand(0), O->getOperand(1)); - return false; - } -private: - bool matchIfNeg(Value *LHS, Value *RHS) { - return ((isa<ConstantInt>(LHS) && cast<ConstantInt>(LHS)->isZero()) || - isa<ConstantAggregateZero>(LHS)) && - L.match(RHS); - } -}; - -/// m_Neg - Match an integer negate. -template<typename LHS> -inline neg_match<LHS> m_Neg(const LHS &L) { return L; } - - -template<typename LHS_t> -struct fneg_match { - LHS_t L; - - fneg_match(const LHS_t &LHS) : L(LHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - if (Operator *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::FSub) - return matchIfFNeg(O->getOperand(0), O->getOperand(1)); - return false; - } -private: - bool matchIfFNeg(Value *LHS, Value *RHS) { - if (ConstantFP *C = dyn_cast<ConstantFP>(LHS)) - return C->isNegativeZeroValue() && L.match(RHS); - return false; - } -}; - -/// m_FNeg - Match a floating point negate. -template<typename LHS> -inline fneg_match<LHS> m_FNeg(const LHS &L) { return L; } - - -//===----------------------------------------------------------------------===// -// Matchers for control flow. -// - -struct br_match { - BasicBlock *&Succ; - br_match(BasicBlock *&Succ) - : Succ(Succ) { - } - - template<typename OpTy> - bool match(OpTy *V) { - if (BranchInst *BI = dyn_cast<BranchInst>(V)) - if (BI->isUnconditional()) { - Succ = BI->getSuccessor(0); - return true; - } - return false; - } -}; - -inline br_match m_UnconditionalBr(BasicBlock *&Succ) { return br_match(Succ); } - -template<typename Cond_t> -struct brc_match { - Cond_t Cond; - BasicBlock *&T, *&F; - brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f) - : Cond(C), T(t), F(f) { - } - - template<typename OpTy> - bool match(OpTy *V) { - if (BranchInst *BI = dyn_cast<BranchInst>(V)) - if (BI->isConditional() && Cond.match(BI->getCondition())) { - T = BI->getSuccessor(0); - F = BI->getSuccessor(1); - return true; - } - return false; - } -}; - -template<typename Cond_t> -inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F) { - return brc_match<Cond_t>(C, T, F); -} - - -//===----------------------------------------------------------------------===// -// Matchers for max/min idioms, eg: "select (sgt x, y), x, y" -> smax(x,y). -// - -template<typename CmpInst_t, typename LHS_t, typename RHS_t, typename Pred_t> -struct MaxMin_match { - LHS_t L; - RHS_t R; - - MaxMin_match(const LHS_t &LHS, const RHS_t &RHS) - : L(LHS), R(RHS) {} - - template<typename OpTy> - bool match(OpTy *V) { - // Look for "(x pred y) ? x : y" or "(x pred y) ? y : x". - SelectInst *SI = dyn_cast<SelectInst>(V); - if (!SI) - return false; - CmpInst_t *Cmp = dyn_cast<CmpInst_t>(SI->getCondition()); - if (!Cmp) - return false; - // At this point we have a select conditioned on a comparison. Check that - // it is the values returned by the select that are being compared. - Value *TrueVal = SI->getTrueValue(); - Value *FalseVal = SI->getFalseValue(); - Value *LHS = Cmp->getOperand(0); - Value *RHS = Cmp->getOperand(1); - if ((TrueVal != LHS || FalseVal != RHS) && - (TrueVal != RHS || FalseVal != LHS)) - return false; - typename CmpInst_t::Predicate Pred = LHS == TrueVal ? - Cmp->getPredicate() : Cmp->getSwappedPredicate(); - // Does "(x pred y) ? x : y" represent the desired max/min operation? - if (!Pred_t::match(Pred)) - return false; - // It does! Bind the operands. - return L.match(LHS) && R.match(RHS); - } -}; - -/// smax_pred_ty - Helper class for identifying signed max predicates. -struct smax_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_SGT || Pred == CmpInst::ICMP_SGE; - } -}; - -/// smin_pred_ty - Helper class for identifying signed min predicates. -struct smin_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_SLT || Pred == CmpInst::ICMP_SLE; - } -}; - -/// umax_pred_ty - Helper class for identifying unsigned max predicates. -struct umax_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_UGE; - } -}; - -/// umin_pred_ty - Helper class for identifying unsigned min predicates. -struct umin_pred_ty { - static bool match(ICmpInst::Predicate Pred) { - return Pred == CmpInst::ICMP_ULT || Pred == CmpInst::ICMP_ULE; - } -}; - -/// ofmax_pred_ty - Helper class for identifying ordered max predicates. -struct ofmax_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_OGT || Pred == CmpInst::FCMP_OGE; - } -}; - -/// ofmin_pred_ty - Helper class for identifying ordered min predicates. -struct ofmin_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_OLT || Pred == CmpInst::FCMP_OLE; - } -}; - -/// ufmax_pred_ty - Helper class for identifying unordered max predicates. -struct ufmax_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_UGT || Pred == CmpInst::FCMP_UGE; - } -}; - -/// ufmin_pred_ty - Helper class for identifying unordered min predicates. -struct ufmin_pred_ty { - static bool match(FCmpInst::Predicate Pred) { - return Pred == CmpInst::FCMP_ULT || Pred == CmpInst::FCMP_ULE; - } -}; - -template<typename LHS, typename RHS> -inline MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty> -m_SMax(const LHS &L, const RHS &R) { - return MaxMin_match<ICmpInst, LHS, RHS, smax_pred_ty>(L, R); -} - -template<typename LHS, typename RHS> -inline MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty> -m_SMin(const LHS &L, const RHS &R) { - return MaxMin_match<ICmpInst, LHS, RHS, smin_pred_ty>(L, R); -} - -template<typename LHS, typename RHS> -inline MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty> -m_UMax(const LHS &L, const RHS &R) { - return MaxMin_match<ICmpInst, LHS, RHS, umax_pred_ty>(L, R); -} - -template<typename LHS, typename RHS> -inline MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty> -m_UMin(const LHS &L, const RHS &R) { - return MaxMin_match<ICmpInst, LHS, RHS, umin_pred_ty>(L, R); -} - -/// \brief Match an 'ordered' floating point maximum function. -/// Floating point has one special value 'NaN'. Therefore, there is no total -/// order. However, if we can ignore the 'NaN' value (for example, because of a -/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum' -/// semantics. In the presence of 'NaN' we have to preserve the original -/// select(fcmp(ogt/ge, L, R), L, R) semantics matched by this predicate. -/// -/// max(L, R) iff L and R are not NaN -/// m_OrdFMax(L, R) = R iff L or R are NaN -template<typename LHS, typename RHS> -inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> -m_OrdFMax(const LHS &L, const RHS &R) { - return MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty>(L, R); -} - -/// \brief Match an 'ordered' floating point minimum function. -/// Floating point has one special value 'NaN'. Therefore, there is no total -/// order. However, if we can ignore the 'NaN' value (for example, because of a -/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum' -/// semantics. In the presence of 'NaN' we have to preserve the original -/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate. -/// -/// max(L, R) iff L and R are not NaN -/// m_OrdFMin(L, R) = R iff L or R are NaN -template<typename LHS, typename RHS> -inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> -m_OrdFMin(const LHS &L, const RHS &R) { - return MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty>(L, R); -} - -/// \brief Match an 'unordered' floating point maximum function. -/// Floating point has one special value 'NaN'. Therefore, there is no total -/// order. However, if we can ignore the 'NaN' value (for example, because of a -/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'maximum' -/// semantics. In the presence of 'NaN' we have to preserve the original -/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate. -/// -/// max(L, R) iff L and R are not NaN -/// m_UnordFMin(L, R) = L iff L or R are NaN -template<typename LHS, typename RHS> -inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty> -m_UnordFMax(const LHS &L, const RHS &R) { - return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R); -} - -/// \brief Match an 'unordered' floating point minimum function. -/// Floating point has one special value 'NaN'. Therefore, there is no total -/// order. However, if we can ignore the 'NaN' value (for example, because of a -/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum' -/// semantics. In the presence of 'NaN' we have to preserve the original -/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate. -/// -/// max(L, R) iff L and R are not NaN -/// m_UnordFMin(L, R) = L iff L or R are NaN -template<typename LHS, typename RHS> -inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty> -m_UnordFMin(const LHS &L, const RHS &R) { - return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R); -} - -template<typename Opnd_t> -struct Argument_match { - unsigned OpI; - Opnd_t Val; - Argument_match(unsigned OpIdx, const Opnd_t &V) : OpI(OpIdx), Val(V) { } - - template<typename OpTy> - bool match(OpTy *V) { - CallSite CS(V); - return CS.isCall() && Val.match(CS.getArgument(OpI)); - } -}; - -/// Match an argument -template<unsigned OpI, typename Opnd_t> -inline Argument_match<Opnd_t> m_Argument(const Opnd_t &Op) { - return Argument_match<Opnd_t>(OpI, Op); -} - -/// Intrinsic matchers. -struct IntrinsicID_match { - unsigned ID; - IntrinsicID_match(Intrinsic::ID IntrID) : ID(IntrID) { } - - template<typename OpTy> - bool match(OpTy *V) { - IntrinsicInst *II = dyn_cast<IntrinsicInst>(V); - return II && II->getIntrinsicID() == ID; - } -}; - -/// Intrinsic matches are combinations of ID matchers, and argument -/// matchers. Higher arity matcher are defined recursively in terms of and-ing -/// them with lower arity matchers. Here's some convenient typedefs for up to -/// several arguments, and more can be added as needed -template <typename T0 = void, typename T1 = void, typename T2 = void, - typename T3 = void, typename T4 = void, typename T5 = void, - typename T6 = void, typename T7 = void, typename T8 = void, - typename T9 = void, typename T10 = void> struct m_Intrinsic_Ty; -template <typename T0> -struct m_Intrinsic_Ty<T0> { - typedef match_combine_and<IntrinsicID_match, Argument_match<T0> > Ty; -}; -template <typename T0, typename T1> -struct m_Intrinsic_Ty<T0, T1> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0>::Ty, - Argument_match<T1> > Ty; -}; -template <typename T0, typename T1, typename T2> -struct m_Intrinsic_Ty<T0, T1, T2> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1>::Ty, - Argument_match<T2> > Ty; -}; -template <typename T0, typename T1, typename T2, typename T3> -struct m_Intrinsic_Ty<T0, T1, T2, T3> { - typedef match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2>::Ty, - Argument_match<T3> > Ty; -}; - -/// Match intrinsic calls like this: -/// m_Intrinsic<Intrinsic::fabs>(m_Value(X)) -template <Intrinsic::ID IntrID> -inline IntrinsicID_match -m_Intrinsic() { return IntrinsicID_match(IntrID); } - -template<Intrinsic::ID IntrID, typename T0> -inline typename m_Intrinsic_Ty<T0>::Ty -m_Intrinsic(const T0 &Op0) { - return m_CombineAnd(m_Intrinsic<IntrID>(), m_Argument<0>(Op0)); -} - -template<Intrinsic::ID IntrID, typename T0, typename T1> -inline typename m_Intrinsic_Ty<T0, T1>::Ty -m_Intrinsic(const T0 &Op0, const T1 &Op1) { - return m_CombineAnd(m_Intrinsic<IntrID>(Op0), m_Argument<1>(Op1)); -} - -template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2> -inline typename m_Intrinsic_Ty<T0, T1, T2>::Ty -m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2) { - return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1), m_Argument<2>(Op2)); -} - -template<Intrinsic::ID IntrID, typename T0, typename T1, typename T2, typename T3> -inline typename m_Intrinsic_Ty<T0, T1, T2, T3>::Ty -m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3) { - return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2), m_Argument<3>(Op3)); -} - -// Helper intrinsic matching specializations -template<typename Opnd0> -inline typename m_Intrinsic_Ty<Opnd0>::Ty -m_BSwap(const Opnd0 &Op0) { - return m_Intrinsic<Intrinsic::bswap>(Op0); -} - -} // end namespace PatternMatch -} // end namespace llvm - -#endif diff --git a/include/llvm/Support/PredIteratorCache.h b/include/llvm/Support/PredIteratorCache.h deleted file mode 100644 index c5fb780..0000000 --- a/include/llvm/Support/PredIteratorCache.h +++ /dev/null @@ -1,70 +0,0 @@ -//===- llvm/Support/PredIteratorCache.h - pred_iterator Cache ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PredIteratorCache class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/CFG.h" - -#ifndef LLVM_SUPPORT_PREDITERATORCACHE_H -#define LLVM_SUPPORT_PREDITERATORCACHE_H - -namespace llvm { - - /// PredIteratorCache - This class is an extremely trivial cache for - /// predecessor iterator queries. This is useful for code that repeatedly - /// wants the predecessor list for the same blocks. - class PredIteratorCache { - /// BlockToPredsMap - Pointer to null-terminated list. - DenseMap<BasicBlock*, BasicBlock**> BlockToPredsMap; - DenseMap<BasicBlock*, unsigned> BlockToPredCountMap; - - /// Memory - This is the space that holds cached preds. - BumpPtrAllocator Memory; - public: - - /// GetPreds - Get a cached list for the null-terminated predecessor list of - /// the specified block. This can be used in a loop like this: - /// for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) - /// use(*PI); - /// instead of: - /// for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) - BasicBlock **GetPreds(BasicBlock *BB) { - BasicBlock **&Entry = BlockToPredsMap[BB]; - if (Entry) return Entry; - - SmallVector<BasicBlock*, 32> PredCache(pred_begin(BB), pred_end(BB)); - PredCache.push_back(0); // null terminator. - - BlockToPredCountMap[BB] = PredCache.size()-1; - - Entry = Memory.Allocate<BasicBlock*>(PredCache.size()); - std::copy(PredCache.begin(), PredCache.end(), Entry); - return Entry; - } - - unsigned GetNumPreds(BasicBlock *BB) { - GetPreds(BB); - return BlockToPredCountMap[BB]; - } - - /// clear - Remove all information. - void clear() { - BlockToPredsMap.clear(); - BlockToPredCountMap.clear(); - Memory.Reset(); - } - }; -} // end namespace llvm - -#endif diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h index 4f68fca..914141a 100644 --- a/include/llvm/Support/PrettyStackTrace.h +++ b/include/llvm/Support/PrettyStackTrace.h @@ -50,7 +50,7 @@ namespace llvm { const char *Str; public: PrettyStackTraceString(const char *str) : Str(str) {} - virtual void print(raw_ostream &OS) const LLVM_OVERRIDE; + void print(raw_ostream &OS) const override; }; /// PrettyStackTraceProgram - This object prints a specified program arguments @@ -63,7 +63,7 @@ namespace llvm { : ArgC(argc), ArgV(argv) { EnablePrettyStackTrace(); } - virtual void print(raw_ostream &OS) const LLVM_OVERRIDE; + void print(raw_ostream &OS) const override; }; } // end namespace llvm diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 2172036..7f6441e 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -29,9 +29,9 @@ #include "llvm/ADT/Optional.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/system_error.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/TimeValue.h" +#include "llvm/Support/system_error.h" namespace llvm { class StringRef; @@ -110,10 +110,10 @@ class self_process : public process { virtual ~self_process(); public: - virtual id_type get_id(); - virtual TimeValue get_user_time() const; - virtual TimeValue get_system_time() const; - virtual TimeValue get_wall_time() const; + id_type get_id() override; + TimeValue get_user_time() const override; + TimeValue get_system_time() const override; + TimeValue get_wall_time() const override; /// \name Process configuration (sysconf on POSIX) /// @{ diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 00571a4..a1067a6 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -52,27 +52,31 @@ struct ProcessInfo { ProcessInfo(); }; - /// This static constructor (factory) will attempt to locate a program in - /// the operating system's file system using some pre-determined set of - /// locations to search (e.g. the PATH on Unix). Paths with slashes are - /// returned unmodified. - /// @returns A Path object initialized to the path of the program or a - /// Path object that is empty (invalid) if the program could not be found. - /// @brief Construct a Program by finding it by name. + /// This function attempts to locate a program in the operating + /// system's file system using some pre-determined set of locations to search + /// (e.g. the PATH on Unix). Paths with slashes are returned unmodified. + /// + /// It does not perform hashing as a shell would but instead stats each PATH + /// entry individually so should generally be avoided. Core LLVM library + /// functions and options should instead require fully specified paths. + /// + /// @returns A string containing the path of the program or an empty string if + /// the program could not be found. std::string FindProgramByName(const std::string& name); - // These functions change the specified standard stream (stdin, stdout, or - // stderr) to binary mode. They return errc::success if the specified stream + // These functions change the specified standard stream (stdin or stdout) to + // binary mode. They return errc::success if the specified stream // was changed. Otherwise a platform dependent error is returned. error_code ChangeStdinToBinary(); error_code ChangeStdoutToBinary(); - error_code ChangeStderrToBinary(); /// This function executes the program using the arguments provided. The /// invoked program will inherit the stdin, stdout, and stderr file /// descriptors, the environment and other configuration settings of the /// invoking program. - /// This function waits the program to finish. + /// This function waits for the program to finish, so should be avoided in + /// library functions that aren't expected to block. Consider using + /// ExecuteNoWait() instead. /// @returns an integer result code indicating the status of the program. /// A zero or positive value indicates the result code of the program. /// -1 indicates failure to execute diff --git a/include/llvm/Support/Recycler.h b/include/llvm/Support/Recycler.h index bcc561d..e97f36a 100644 --- a/include/llvm/Support/Recycler.h +++ b/include/llvm/Support/Recycler.h @@ -17,13 +17,12 @@ #include "llvm/ADT/ilist.h" #include "llvm/Support/AlignOf.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorHandling.h" #include <cassert> namespace llvm { -class BumpPtrAllocator; - /// PrintRecyclingAllocatorStats - Helper for RecyclingAllocator for /// printing statistics. /// @@ -100,10 +99,10 @@ public: template<class SubClass, class AllocatorType> SubClass *Allocate(AllocatorType &Allocator) { - assert(sizeof(SubClass) <= Size && - "Recycler allocation size is less than object size!"); - assert(AlignOf<SubClass>::Alignment <= Align && - "Recycler allocation alignment is less than object alignment!"); + static_assert(AlignOf<SubClass>::Alignment <= Align, + "Recycler allocation alignment is less than object align!"); + static_assert(sizeof(SubClass) <= Size, + "Recycler allocation size is less than object size!"); return !FreeList.empty() ? reinterpret_cast<SubClass *>(FreeList.remove(FreeList.begin())) : static_cast<SubClass *>(Allocator.Allocate(Size, Align)); diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index 3d071be..2eea369 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -17,6 +17,7 @@ #ifndef LLVM_SUPPORT_REGEX_H #define LLVM_SUPPORT_REGEX_H +#include "llvm/Support/Compiler.h" #include <string> struct llvm_regex; @@ -45,6 +46,17 @@ namespace llvm { /// Compiles the given regular expression \p Regex. Regex(StringRef Regex, unsigned Flags = NoFlags); + Regex(const Regex &) LLVM_DELETED_FUNCTION; + Regex &operator=(Regex regex) { + std::swap(preg, regex.preg); + std::swap(error, regex.error); + return *this; + } + Regex(Regex &®ex) { + preg = regex.preg; + error = regex.error; + regex.preg = NULL; + } ~Regex(); /// isValid - returns the error encountered during regex compilation, or @@ -81,6 +93,9 @@ namespace llvm { /// expression that matches Str and only Str. static bool isLiteralERE(StringRef Str); + /// \brief Turn String into a regex by escaping its special characters. + static std::string escape(StringRef String); + private: struct llvm_regex *preg; int error; diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h index e823d48..0259630 100644 --- a/include/llvm/Support/StreamableMemoryObject.h +++ b/include/llvm/Support/StreamableMemoryObject.h @@ -11,10 +11,11 @@ #ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H #define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H -#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/MemoryObject.h" +#include <cassert> +#include <memory> #include <vector> namespace llvm { @@ -38,7 +39,7 @@ class StreamableMemoryObject : public MemoryObject { /// getBase - Returns the lowest valid address in the region. /// /// @result - The lowest valid address. - virtual uint64_t getBase() const LLVM_OVERRIDE = 0; + uint64_t getBase() const override = 0; /// getExtent - Returns the size of the region in bytes. (The region is /// contiguous, so the highest valid address of the region @@ -46,7 +47,7 @@ class StreamableMemoryObject : public MemoryObject { /// May block until all bytes in the stream have been read /// /// @result - The size of the region. - virtual uint64_t getExtent() const LLVM_OVERRIDE = 0; + uint64_t getExtent() const override = 0; /// readByte - Tries to read a single byte from the region. /// May block until (address - base) bytes have been read @@ -54,7 +55,7 @@ class StreamableMemoryObject : public MemoryObject { /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE = 0; + int readByte(uint64_t address, uint8_t *ptr) const override = 0; /// readBytes - Tries to read a contiguous range of bytes from the /// region, up to the end of the region. @@ -70,9 +71,8 @@ class StreamableMemoryObject : public MemoryObject { /// and large enough to hold size bytes. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readBytes(uint64_t address, - uint64_t size, - uint8_t *buf) const LLVM_OVERRIDE = 0; + int readBytes(uint64_t address, uint64_t size, + uint8_t *buf) const override = 0; /// getPointer - Ensures that the requested data is in memory, and returns /// A pointer to it. More efficient than using readBytes if the @@ -105,14 +105,12 @@ class StreamableMemoryObject : public MemoryObject { class StreamingMemoryObject : public StreamableMemoryObject { public: StreamingMemoryObject(DataStreamer *streamer); - virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; } - virtual uint64_t getExtent() const LLVM_OVERRIDE; - virtual int readByte(uint64_t address, uint8_t *ptr) const LLVM_OVERRIDE; - virtual int readBytes(uint64_t address, - uint64_t size, - uint8_t *buf) const LLVM_OVERRIDE; - virtual const uint8_t *getPointer(uint64_t address, - uint64_t size) const LLVM_OVERRIDE { + uint64_t getBase() const override { return 0; } + uint64_t getExtent() const override; + int readByte(uint64_t address, uint8_t *ptr) const override; + int readBytes(uint64_t address, uint64_t size, + uint8_t *buf) const override; + const uint8_t *getPointer(uint64_t address, uint64_t size) const override { // This could be fixed by ensuring the bytes are fetched and making a copy, // requiring that the bitcode size be known, or otherwise ensuring that // the memory doesn't go away/get reallocated, but it's @@ -120,8 +118,8 @@ public: assert(0 && "getPointer in streaming memory objects not allowed"); return NULL; } - virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE; - virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE; + bool isValidAddress(uint64_t address) const override; + bool isObjectEnd(uint64_t address) const override; /// Drop s bytes from the front of the stream, pushing the positions of the /// remaining bytes down by s. This is used to skip past the bitcode header, @@ -137,7 +135,7 @@ public: private: const static uint32_t kChunkSize = 4096 * 4; mutable std::vector<unsigned char> Bytes; - OwningPtr<DataStreamer> Streamer; + std::unique_ptr<DataStreamer> Streamer; mutable size_t BytesRead; // Bytes read from stream size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached diff --git a/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h index 994fa34..8a349ea 100644 --- a/include/llvm/Support/StringRefMemoryObject.h +++ b/include/llvm/Support/StringRefMemoryObject.h @@ -29,11 +29,11 @@ public: StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0) : Bytes(Bytes), Base(Base) {} - uint64_t getBase() const LLVM_OVERRIDE { return Base; } - uint64_t getExtent() const LLVM_OVERRIDE { return Bytes.size(); } + uint64_t getBase() const override { return Base; } + uint64_t getExtent() const override { return Bytes.size(); } - int readByte(uint64_t Addr, uint8_t *Byte) const LLVM_OVERRIDE; - int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const LLVM_OVERRIDE; + int readByte(uint64_t Addr, uint8_t *Byte) const override; + int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const override; }; } diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h deleted file mode 100644 index 5c1978d..0000000 --- a/include/llvm/Support/TargetFolder.h +++ /dev/null @@ -1,262 +0,0 @@ -//====-- llvm/Support/TargetFolder.h - Constant folding helper -*- C++ -*-====// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the TargetFolder class, a helper for IRBuilder. -// It provides IRBuilder with a set of methods for creating constants with -// target dependent folding, in addition to the same target-independent -// folding that the ConstantFolder class provides. For general constant -// creation and folding, use ConstantExpr and the routines in -// llvm/Analysis/ConstantFolding.h. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_TARGETFOLDER_H -#define LLVM_SUPPORT_TARGETFOLDER_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Analysis/ConstantFolding.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/InstrTypes.h" - -namespace llvm { - -class DataLayout; - -/// TargetFolder - Create constants with target dependent folding. -class TargetFolder { - const DataLayout *TD; - - /// Fold - Fold the constant using target specific information. - Constant *Fold(Constant *C) const { - if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) - if (Constant *CF = ConstantFoldConstantExpression(CE, TD)) - return CF; - return C; - } - -public: - explicit TargetFolder(const DataLayout *TheTD) : TD(TheTD) {} - - //===--------------------------------------------------------------------===// - // Binary Operators - //===--------------------------------------------------------------------===// - - Constant *CreateAdd(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW)); - } - Constant *CreateFAdd(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getFAdd(LHS, RHS)); - } - Constant *CreateSub(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW)); - } - Constant *CreateFSub(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getFSub(LHS, RHS)); - } - Constant *CreateMul(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW)); - } - Constant *CreateFMul(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getFMul(LHS, RHS)); - } - Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact)); - } - Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact)); - } - Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getFDiv(LHS, RHS)); - } - Constant *CreateURem(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getURem(LHS, RHS)); - } - Constant *CreateSRem(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getSRem(LHS, RHS)); - } - Constant *CreateFRem(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getFRem(LHS, RHS)); - } - Constant *CreateShl(Constant *LHS, Constant *RHS, - bool HasNUW = false, bool HasNSW = false) const { - return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW)); - } - Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getLShr(LHS, RHS, isExact)); - } - Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getAShr(LHS, RHS, isExact)); - } - Constant *CreateAnd(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getAnd(LHS, RHS)); - } - Constant *CreateOr(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getOr(LHS, RHS)); - } - Constant *CreateXor(Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::getXor(LHS, RHS)); - } - - Constant *CreateBinOp(Instruction::BinaryOps Opc, - Constant *LHS, Constant *RHS) const { - return Fold(ConstantExpr::get(Opc, LHS, RHS)); - } - - //===--------------------------------------------------------------------===// - // Unary Operators - //===--------------------------------------------------------------------===// - - Constant *CreateNeg(Constant *C, - bool HasNUW = false, bool HasNSW = false) const { - return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW)); - } - Constant *CreateFNeg(Constant *C) const { - return Fold(ConstantExpr::getFNeg(C)); - } - Constant *CreateNot(Constant *C) const { - return Fold(ConstantExpr::getNot(C)); - } - - //===--------------------------------------------------------------------===// - // Memory Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); - } - Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return Fold(ConstantExpr::getGetElementPtr(C, Idx)); - } - Constant *CreateGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); - } - - Constant *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Constant *> IdxList) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); - } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { - // This form of the function only exists to avoid ambiguous overload - // warnings about whether to convert Idx to ArrayRef<Constant *> or - // ArrayRef<Value *>. - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); - } - Constant *CreateInBoundsGetElementPtr(Constant *C, - ArrayRef<Value *> IdxList) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); - } - - //===--------------------------------------------------------------------===// - // Cast/Conversion Operators - //===--------------------------------------------------------------------===// - - Constant *CreateCast(Instruction::CastOps Op, Constant *C, - Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getCast(Op, C, DestTy)); - } - Constant *CreateIntCast(Constant *C, Type *DestTy, - bool isSigned) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); - } - Constant *CreatePointerCast(Constant *C, Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getPointerCast(C, DestTy)); - } - Constant *CreateFPCast(Constant *C, Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getFPCast(C, DestTy)); - } - Constant *CreateBitCast(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::BitCast, C, DestTy); - } - Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::IntToPtr, C, DestTy); - } - Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { - return CreateCast(Instruction::PtrToInt, C, DestTy); - } - Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); - } - Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); - } - Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { - if (C->getType() == DestTy) - return C; // avoid calling Fold - return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); - } - - //===--------------------------------------------------------------------===// - // Compare Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS, - Constant *RHS) const { - return Fold(ConstantExpr::getCompare(P, LHS, RHS)); - } - Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS, - Constant *RHS) const { - return Fold(ConstantExpr::getCompare(P, LHS, RHS)); - } - - //===--------------------------------------------------------------------===// - // Other Instructions - //===--------------------------------------------------------------------===// - - Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const { - return Fold(ConstantExpr::getSelect(C, True, False)); - } - - Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const { - return Fold(ConstantExpr::getExtractElement(Vec, Idx)); - } - - Constant *CreateInsertElement(Constant *Vec, Constant *NewElt, - Constant *Idx) const { - return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx)); - } - - Constant *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const { - return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); - } - - Constant *CreateExtractValue(Constant *Agg, - ArrayRef<unsigned> IdxList) const { - return Fold(ConstantExpr::getExtractValue(Agg, IdxList)); - } - - Constant *CreateInsertValue(Constant *Agg, Constant *Val, - ArrayRef<unsigned> IdxList) const { - return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList)); - } -}; - -} - -#endif diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 9ecee3b..8e7478c 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -19,9 +19,9 @@ #ifndef LLVM_SUPPORT_TARGETREGISTRY_H #define LLVM_SUPPORT_TARGETREGISTRY_H +#include "llvm-c/Disassembler.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/CodeGen.h" -#include "llvm-c/Disassembler.h" #include <cassert> #include <string> @@ -46,15 +46,12 @@ namespace llvm { class MCRelocationInfo; class MCTargetAsmParser; class TargetMachine; - class MCTargetStreamer; class TargetOptions; class raw_ostream; class formatted_raw_ostream; - MCStreamer *createAsmStreamer(MCContext &Ctx, - MCTargetStreamer *TargetStreamer, - formatted_raw_ostream &OS, bool isVerboseAsm, - bool useLoc, bool useCFI, + MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst); @@ -79,7 +76,7 @@ namespace llvm { public: friend struct TargetRegistry; - typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); + typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch); typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI, StringRef TT); @@ -128,12 +125,12 @@ namespace llvm { MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, + const MCSubtargetInfo &STI, bool RelaxAll, bool NoExecStack); typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, - bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, @@ -154,9 +151,8 @@ namespace llvm { /// TargetRegistry. Target *Next; - /// TripleMatchQualityFn - The target function for rating the match quality - /// of a triple. - TripleMatchQualityFnTy TripleMatchQualityFn; + /// The target function for checking if an architecture is supported. + ArchMatchFnTy ArchMatchFn; /// Name - The target name. const char *Name; @@ -421,11 +417,12 @@ namespace llvm { MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, + const MCSubtargetInfo &STI, bool RelaxAll, bool NoExecStack) const { if (!MCObjectStreamerCtorFn) return 0; - return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, + return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI, RelaxAll, NoExecStack); } @@ -433,7 +430,6 @@ namespace llvm { MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, - bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, @@ -441,10 +437,10 @@ namespace llvm { MCAsmBackend *TAB, bool ShowInst) const { if (AsmStreamerCtorFn) - return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI, + return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useCFI, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); - return llvm::createAsmStreamer(Ctx, 0, OS, isVerboseAsm, useLoc, useCFI, + return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useCFI, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); } @@ -490,7 +486,6 @@ namespace llvm { explicit iterator(Target *T) : Current(T) {} friend struct TargetRegistry; public: - iterator(const iterator &I) : Current(I.Current) {} iterator() : Current(0) {} bool operator==(const iterator &x) const { @@ -578,14 +573,13 @@ namespace llvm { /// @param Name - The target name. This should be a static string. /// @param ShortDesc - A short target description. This should be a static /// string. - /// @param TQualityFn - The triple match quality computation function for - /// this target. + /// @param ArchMatchFn - The arch match checking function for this target. /// @param HasJIT - Whether the target supports JIT code /// generation. static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, - Target::TripleMatchQualityFnTy TQualityFn, + Target::ArchMatchFnTy ArchMatchFn, bool HasJIT = false); /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the @@ -831,15 +825,11 @@ namespace llvm { bool HasJIT = false> struct RegisterTarget { RegisterTarget(Target &T, const char *Name, const char *Desc) { - TargetRegistry::RegisterTarget(T, Name, Desc, - &getTripleMatchQuality, - HasJIT); + TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT); } - static unsigned getTripleMatchQuality(const std::string &TT) { - if (Triple(TT).getArch() == TargetArchType) - return 20; - return 0; + static bool getArchMatch(Triple::ArchType Arch) { + return Arch == TargetArchType; } }; diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h index 2785408..ee0e286 100644 --- a/include/llvm/Support/TimeValue.h +++ b/include/llvm/Support/TimeValue.h @@ -74,8 +74,7 @@ namespace sys { MILLISECONDS_PER_SECOND = 1000, ///< One Thousand NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million - NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms) - NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms) + NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 10^7 Hz (10ns) }; /// @} @@ -236,15 +235,6 @@ namespace sys { ( nanos_ / NANOSECONDS_PER_MILLISECOND ); } - /// Converts the TimeValue into the corresponding number of "ticks" for - /// Posix, correcting for the difference in Posix zero time. - /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970) - uint64_t toPosixTime() const { - uint64_t result = seconds_ - PosixZeroTimeSeconds; - result += nanos_ / NANOSECONDS_PER_POSIX_TICK; - return result; - } - /// Converts the TimeValue into the corresponding number of seconds /// since the epoch (00:00:00 Jan 1,1970). uint64_t toEpochTime() const { diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h index a2191ad..88f8ccc 100644 --- a/include/llvm/Support/ToolOutputFile.h +++ b/include/llvm/Support/ToolOutputFile.h @@ -47,7 +47,7 @@ public: /// tool_output_file - This constructor's arguments are passed to /// to raw_fd_ostream's constructor. tool_output_file(const char *filename, std::string &ErrorInfo, - sys::fs::OpenFlags Flags = sys::fs::F_None); + sys::fs::OpenFlags Flags); tool_output_file(const char *Filename, int FD); diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h index 86faa38..734d323 100644 --- a/include/llvm/Support/UnicodeCharRanges.h +++ b/include/llvm/Support/UnicodeCharRanges.h @@ -16,7 +16,6 @@ #include "llvm/Support/Mutex.h" #include "llvm/Support/MutexGuard.h" #include "llvm/Support/raw_ostream.h" - #include <algorithm> namespace llvm { @@ -40,7 +39,7 @@ inline bool operator<(UnicodeCharRange Range, uint32_t Value) { /// array. class UnicodeCharSet { public: - typedef llvm::ArrayRef<UnicodeCharRange> CharRanges; + typedef ArrayRef<UnicodeCharRange> CharRanges; /// \brief Constructs a UnicodeCharSet instance from an array of /// UnicodeCharRanges. @@ -67,17 +66,17 @@ private: for (CharRanges::const_iterator I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { if (I != Ranges.begin() && Prev >= I->Lower) { - DEBUG(llvm::dbgs() << "Upper bound 0x"); - DEBUG(llvm::dbgs().write_hex(Prev)); - DEBUG(llvm::dbgs() << " should be less than succeeding lower bound 0x"); - DEBUG(llvm::dbgs().write_hex(I->Lower) << "\n"); + DEBUG(dbgs() << "Upper bound 0x"); + DEBUG(dbgs().write_hex(Prev)); + DEBUG(dbgs() << " should be less than succeeding lower bound 0x"); + DEBUG(dbgs().write_hex(I->Lower) << "\n"); return false; } if (I->Upper < I->Lower) { - DEBUG(llvm::dbgs() << "Upper bound 0x"); - DEBUG(llvm::dbgs().write_hex(I->Lower)); - DEBUG(llvm::dbgs() << " should not be less than lower bound 0x"); - DEBUG(llvm::dbgs().write_hex(I->Upper) << "\n"); + DEBUG(dbgs() << "Upper bound 0x"); + DEBUG(dbgs().write_hex(I->Lower)); + DEBUG(dbgs() << " should not be less than lower bound 0x"); + DEBUG(dbgs().write_hex(I->Upper) << "\n"); return false; } Prev = I->Upper; diff --git a/include/llvm/Support/Valgrind.h b/include/llvm/Support/Valgrind.h index 7ae40af..cebf75c 100644 --- a/include/llvm/Support/Valgrind.h +++ b/include/llvm/Support/Valgrind.h @@ -24,12 +24,10 @@ // tsan (Thread Sanitizer) is a valgrind-based tool that detects these exact // functions by name. extern "C" { -LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line, - const volatile void *cv); -LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line, - const volatile void *cv); -LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line); -LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line); +void AnnotateHappensAfter(const char *file, int line, const volatile void *cv); +void AnnotateHappensBefore(const char *file, int line, const volatile void *cv); +void AnnotateIgnoreWritesBegin(const char *file, int line); +void AnnotateIgnoreWritesEnd(const char *file, int line); } #endif diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h deleted file mode 100644 index bc02ba3..0000000 --- a/include/llvm/Support/ValueHandle.h +++ /dev/null @@ -1,380 +0,0 @@ -//===- llvm/Support/ValueHandle.h - Value Smart Pointer classes -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the ValueHandle class and its sub-classes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_VALUEHANDLE_H -#define LLVM_SUPPORT_VALUEHANDLE_H - -#include "llvm/ADT/DenseMapInfo.h" -#include "llvm/ADT/PointerIntPair.h" -#include "llvm/IR/Value.h" - -namespace llvm { -class ValueHandleBase; -template<typename From> struct simplify_type; - -// ValueHandleBase** is only 4-byte aligned. -template<> -class PointerLikeTypeTraits<ValueHandleBase**> { -public: - static inline void *getAsVoidPointer(ValueHandleBase** P) { return P; } - static inline ValueHandleBase **getFromVoidPointer(void *P) { - return static_cast<ValueHandleBase**>(P); - } - enum { NumLowBitsAvailable = 2 }; -}; - -/// ValueHandleBase - This is the common base class of value handles. -/// ValueHandle's are smart pointers to Value's that have special behavior when -/// the value is deleted or ReplaceAllUsesWith'd. See the specific handles -/// below for details. -/// -class ValueHandleBase { - friend class Value; -protected: - /// HandleBaseKind - This indicates what sub class the handle actually is. - /// This is to avoid having a vtable for the light-weight handle pointers. The - /// fully general Callback version does have a vtable. - enum HandleBaseKind { - Assert, - Callback, - Tracking, - Weak - }; - -private: - PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; - ValueHandleBase *Next; - - // A subclass may want to store some information along with the value - // pointer. Allow them to do this by making the value pointer a pointer-int - // pair. The 'setValPtrInt' and 'getValPtrInt' methods below give them this - // access. - PointerIntPair<Value*, 2> VP; - - ValueHandleBase(const ValueHandleBase&) LLVM_DELETED_FUNCTION; -public: - explicit ValueHandleBase(HandleBaseKind Kind) - : PrevPair(0, Kind), Next(0), VP(0, 0) {} - ValueHandleBase(HandleBaseKind Kind, Value *V) - : PrevPair(0, Kind), Next(0), VP(V, 0) { - if (isValid(VP.getPointer())) - AddToUseList(); - } - ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS) - : PrevPair(0, Kind), Next(0), VP(RHS.VP) { - if (isValid(VP.getPointer())) - AddToExistingUseList(RHS.getPrevPtr()); - } - ~ValueHandleBase() { - if (isValid(VP.getPointer())) - RemoveFromUseList(); - } - - Value *operator=(Value *RHS) { - if (VP.getPointer() == RHS) return RHS; - if (isValid(VP.getPointer())) RemoveFromUseList(); - VP.setPointer(RHS); - if (isValid(VP.getPointer())) AddToUseList(); - return RHS; - } - - Value *operator=(const ValueHandleBase &RHS) { - if (VP.getPointer() == RHS.VP.getPointer()) return RHS.VP.getPointer(); - if (isValid(VP.getPointer())) RemoveFromUseList(); - VP.setPointer(RHS.VP.getPointer()); - if (isValid(VP.getPointer())) AddToExistingUseList(RHS.getPrevPtr()); - return VP.getPointer(); - } - - Value *operator->() const { return getValPtr(); } - Value &operator*() const { return *getValPtr(); } - -protected: - Value *getValPtr() const { return VP.getPointer(); } - - void setValPtrInt(unsigned K) { VP.setInt(K); } - unsigned getValPtrInt() const { return VP.getInt(); } - - static bool isValid(Value *V) { - return V && - V != DenseMapInfo<Value *>::getEmptyKey() && - V != DenseMapInfo<Value *>::getTombstoneKey(); - } - -public: - // Callbacks made from Value. - static void ValueIsDeleted(Value *V); - static void ValueIsRAUWd(Value *Old, Value *New); - -private: - // Internal implementation details. - ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); } - HandleBaseKind getKind() const { return PrevPair.getInt(); } - void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); } - - /// AddToExistingUseList - Add this ValueHandle to the use list for VP, where - /// List is the address of either the head of the list or a Next node within - /// the existing use list. - void AddToExistingUseList(ValueHandleBase **List); - - /// AddToExistingUseListAfter - Add this ValueHandle to the use list after - /// Node. - void AddToExistingUseListAfter(ValueHandleBase *Node); - - /// AddToUseList - Add this ValueHandle to the use list for VP. - void AddToUseList(); - /// RemoveFromUseList - Remove this ValueHandle from its current use list. - void RemoveFromUseList(); -}; - -/// WeakVH - This is a value handle that tries hard to point to a Value, even -/// across RAUW operations, but will null itself out if the value is destroyed. -/// this is useful for advisory sorts of information, but should not be used as -/// the key of a map (since the map would have to rearrange itself when the -/// pointer changes). -class WeakVH : public ValueHandleBase { -public: - WeakVH() : ValueHandleBase(Weak) {} - WeakVH(Value *P) : ValueHandleBase(Weak, P) {} - WeakVH(const WeakVH &RHS) - : ValueHandleBase(Weak, RHS) {} - - Value *operator=(Value *RHS) { - return ValueHandleBase::operator=(RHS); - } - Value *operator=(const ValueHandleBase &RHS) { - return ValueHandleBase::operator=(RHS); - } - - operator Value*() const { - return getValPtr(); - } -}; - -// Specialize simplify_type to allow WeakVH to participate in -// dyn_cast, isa, etc. -template<> struct simplify_type<WeakVH> { - typedef Value* SimpleType; - static SimpleType getSimplifiedValue(WeakVH &WVH) { - return WVH; - } -}; - -/// AssertingVH - This is a Value Handle that points to a value and asserts out -/// if the value is destroyed while the handle is still live. This is very -/// useful for catching dangling pointer bugs and other things which can be -/// non-obvious. One particularly useful place to use this is as the Key of a -/// map. Dangling pointer bugs often lead to really subtle bugs that only occur -/// if another object happens to get allocated to the same address as the old -/// one. Using an AssertingVH ensures that an assert is triggered as soon as -/// the bad delete occurs. -/// -/// Note that an AssertingVH handle does *not* follow values across RAUW -/// operations. This means that RAUW's need to explicitly update the -/// AssertingVH's as it moves. This is required because in non-assert mode this -/// class turns into a trivial wrapper around a pointer. -template <typename ValueTy> -class AssertingVH -#ifndef NDEBUG - : public ValueHandleBase -#endif - { - -#ifndef NDEBUG - ValueTy *getValPtr() const { - return static_cast<ValueTy*>(ValueHandleBase::getValPtr()); - } - void setValPtr(ValueTy *P) { - ValueHandleBase::operator=(GetAsValue(P)); - } -#else - ValueTy *ThePtr; - ValueTy *getValPtr() const { return ThePtr; } - void setValPtr(ValueTy *P) { ThePtr = P; } -#endif - - // Convert a ValueTy*, which may be const, to the type the base - // class expects. - static Value *GetAsValue(Value *V) { return V; } - static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } - -public: -#ifndef NDEBUG - AssertingVH() : ValueHandleBase(Assert) {} - AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {} - AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {} -#else - AssertingVH() : ThePtr(0) {} - AssertingVH(ValueTy *P) : ThePtr(P) {} -#endif - - operator ValueTy*() const { - return getValPtr(); - } - - ValueTy *operator=(ValueTy *RHS) { - setValPtr(RHS); - return getValPtr(); - } - ValueTy *operator=(const AssertingVH<ValueTy> &RHS) { - setValPtr(RHS.getValPtr()); - return getValPtr(); - } - - ValueTy *operator->() const { return getValPtr(); } - ValueTy &operator*() const { return *getValPtr(); } -}; - -// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap. -template<typename T> -struct DenseMapInfo<AssertingVH<T> > { - typedef DenseMapInfo<T*> PointerInfo; - static inline AssertingVH<T> getEmptyKey() { - return AssertingVH<T>(PointerInfo::getEmptyKey()); - } - static inline T* getTombstoneKey() { - return AssertingVH<T>(PointerInfo::getTombstoneKey()); - } - static unsigned getHashValue(const AssertingVH<T> &Val) { - return PointerInfo::getHashValue(Val); - } - static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) { - return LHS == RHS; - } -}; - -template <typename T> -struct isPodLike<AssertingVH<T> > { -#ifdef NDEBUG - static const bool value = true; -#else - static const bool value = false; -#endif -}; - - -/// TrackingVH - This is a value handle that tracks a Value (or Value subclass), -/// even across RAUW operations. -/// -/// TrackingVH is designed for situations where a client needs to hold a handle -/// to a Value (or subclass) across some operations which may move that value, -/// but should never destroy it or replace it with some unacceptable type. -/// -/// It is an error to do anything with a TrackingVH whose value has been -/// destroyed, except to destruct it. -/// -/// It is an error to attempt to replace a value with one of a type which is -/// incompatible with any of its outstanding TrackingVHs. -template<typename ValueTy> -class TrackingVH : public ValueHandleBase { - void CheckValidity() const { - Value *VP = ValueHandleBase::getValPtr(); - - // Null is always ok. - if (!VP) return; - - // Check that this value is valid (i.e., it hasn't been deleted). We - // explicitly delay this check until access to avoid requiring clients to be - // unnecessarily careful w.r.t. destruction. - assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!"); - - // Check that the value is a member of the correct subclass. We would like - // to check this property on assignment for better debugging, but we don't - // want to require a virtual interface on this VH. Instead we allow RAUW to - // replace this value with a value of an invalid type, and check it here. - assert(isa<ValueTy>(VP) && - "Tracked Value was replaced by one with an invalid type!"); - } - - ValueTy *getValPtr() const { - CheckValidity(); - return (ValueTy*)ValueHandleBase::getValPtr(); - } - void setValPtr(ValueTy *P) { - CheckValidity(); - ValueHandleBase::operator=(GetAsValue(P)); - } - - // Convert a ValueTy*, which may be const, to the type the base - // class expects. - static Value *GetAsValue(Value *V) { return V; } - static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); } - -public: - TrackingVH() : ValueHandleBase(Tracking) {} - TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {} - TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {} - - operator ValueTy*() const { - return getValPtr(); - } - - ValueTy *operator=(ValueTy *RHS) { - setValPtr(RHS); - return getValPtr(); - } - ValueTy *operator=(const TrackingVH<ValueTy> &RHS) { - setValPtr(RHS.getValPtr()); - return getValPtr(); - } - - ValueTy *operator->() const { return getValPtr(); } - ValueTy &operator*() const { return *getValPtr(); } -}; - -/// CallbackVH - This is a value handle that allows subclasses to define -/// callbacks that run when the underlying Value has RAUW called on it or is -/// destroyed. This class can be used as the key of a map, as long as the user -/// takes it out of the map before calling setValPtr() (since the map has to -/// rearrange itself when the pointer changes). Unlike ValueHandleBase, this -/// class has a vtable and a virtual destructor. -class CallbackVH : public ValueHandleBase { - virtual void anchor(); -protected: - CallbackVH(const CallbackVH &RHS) - : ValueHandleBase(Callback, RHS) {} - - virtual ~CallbackVH() {} - - void setValPtr(Value *P) { - ValueHandleBase::operator=(P); - } - -public: - CallbackVH() : ValueHandleBase(Callback) {} - CallbackVH(Value *P) : ValueHandleBase(Callback, P) {} - - operator Value*() const { - return getValPtr(); - } - - /// Called when this->getValPtr() is destroyed, inside ~Value(), so you may - /// call any non-virtual Value method on getValPtr(), but no subclass methods. - /// If WeakVH were implemented as a CallbackVH, it would use this method to - /// call setValPtr(NULL). AssertingVH would use this method to cause an - /// assertion failure. - /// - /// All implementations must remove the reference from this object to the - /// Value that's being destroyed. - virtual void deleted() { setValPtr(NULL); } - - /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, - /// _before_ any of the uses have actually been replaced. If WeakVH were - /// implemented as a CallbackVH, it would use this method to call - /// setValPtr(new_value). AssertingVH would do nothing in this method. - virtual void allUsesReplacedWith(Value *) {} -}; - -} // End llvm namespace - -#endif diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h index ecce713..7ca218e 100644 --- a/include/llvm/Support/Win64EH.h +++ b/include/llvm/Support/Win64EH.h @@ -108,17 +108,19 @@ struct UnwindInfo { /// \brief Return pointer to language specific data part of UnwindInfo. const void *getLanguageSpecificData() const { - return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]); + return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes + 1) & ~1]); } /// \brief Return image-relative offset of language-specific exception handler. uint32_t getLanguageSpecificHandlerOffset() const { - return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData()); + return *reinterpret_cast<const support::ulittle32_t *>( + getLanguageSpecificData()); } /// \brief Set image-relative offset of language-specific exception handler. void setLanguageSpecificHandlerOffset(uint32_t offset) { - *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset; + *reinterpret_cast<support::ulittle32_t *>(getLanguageSpecificData()) = + offset; } /// \brief Return pointer to exception-specific data. diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index 7020449..5194b52 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -38,14 +38,12 @@ #ifndef LLVM_SUPPORT_YAMLPARSER_H #define LLVM_SUPPORT_YAMLPARSER_H -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/SMLoc.h" - -#include <map> #include <limits> +#include <map> #include <utility> namespace llvm { @@ -97,8 +95,8 @@ public: void printError(Node *N, const Twine &Msg); private: - OwningPtr<Scanner> scanner; - OwningPtr<Document> CurrentDoc; + std::unique_ptr<Scanner> scanner; + std::unique_ptr<Document> CurrentDoc; friend class Document; }; @@ -116,7 +114,7 @@ public: NK_Alias }; - Node(unsigned int Type, OwningPtr<Document> &, StringRef Anchor, + Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor, StringRef Tag); /// @brief Get the value of the anchor attached to this node. If it does not @@ -157,7 +155,7 @@ public: } protected: - OwningPtr<Document> &Doc; + std::unique_ptr<Document> &Doc; SMRange SourceRange; void operator delete(void *) throw() {} @@ -176,9 +174,9 @@ private: /// Example: /// !!null null class NullNode : public Node { - virtual void anchor(); + void anchor() override; public: - NullNode(OwningPtr<Document> &D) + NullNode(std::unique_ptr<Document> &D) : Node(NK_Null, D, StringRef(), StringRef()) {} static inline bool classof(const Node *N) { @@ -192,9 +190,9 @@ public: /// Example: /// Adena class ScalarNode : public Node { - virtual void anchor(); + void anchor() override; public: - ScalarNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag, + ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag, StringRef Val) : Node(NK_Scalar, D, Anchor, Tag), Value(Val) { SMLoc Start = SMLoc::getFromPointer(Val.begin()); @@ -234,13 +232,10 @@ private: /// Example: /// Section: .text class KeyValueNode : public Node { - virtual void anchor(); + void anchor() override; public: - KeyValueNode(OwningPtr<Document> &D) - : Node(NK_KeyValue, D, StringRef(), StringRef()) - , Key(0) - , Value(0) - {} + KeyValueNode(std::unique_ptr<Document> &D) + : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(0), Value(0) {} /// @brief Parse and return the key. /// @@ -256,7 +251,7 @@ public: /// @returns The value, or nullptr if failed() == true. Node *getValue(); - virtual void skip() LLVM_OVERRIDE { + void skip() override { getKey()->skip(); getValue()->skip(); } @@ -346,7 +341,7 @@ void skip(CollectionType &C) { /// Name: _main /// Scope: Global class MappingNode : public Node { - virtual void anchor(); + void anchor() override; public: enum MappingType { MT_Block, @@ -354,7 +349,7 @@ public: MT_Inline ///< An inline mapping node is used for "[key: value]". }; - MappingNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag, + MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag, MappingType MT) : Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true), IsAtEnd(false), CurrentEntry(0) {} @@ -370,7 +365,7 @@ public: iterator end() { return iterator(); } - virtual void skip() LLVM_OVERRIDE { + void skip() override { yaml::skip(*this); } @@ -396,7 +391,7 @@ private: /// - Hello /// - World class SequenceNode : public Node { - virtual void anchor(); + void anchor() override; public: enum SequenceType { ST_Block, @@ -411,7 +406,7 @@ public: ST_Indentless }; - SequenceNode(OwningPtr<Document> &D, StringRef Anchor, StringRef Tag, + SequenceNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag, SequenceType ST) : Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true), IsAtEnd(false), @@ -431,7 +426,7 @@ public: iterator end() { return iterator(); } - virtual void skip() LLVM_OVERRIDE { + void skip() override { yaml::skip(*this); } @@ -452,10 +447,10 @@ private: /// Example: /// *AnchorName class AliasNode : public Node { - virtual void anchor(); + void anchor() override; public: - AliasNode(OwningPtr<Document> &D, StringRef Val) - : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {} + AliasNode(std::unique_ptr<Document> &D, StringRef Val) + : Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {} StringRef getName() const { return Name; } Node *getTarget(); @@ -532,7 +527,7 @@ private: class document_iterator { public: document_iterator() : Doc(0) {} - document_iterator(OwningPtr<Document> &D) : Doc(&D) {} + document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {} bool operator ==(const document_iterator &Other) { if (isAtEnd() || Other.isAtEnd()) @@ -559,16 +554,14 @@ public: return *Doc->get(); } - OwningPtr<Document> &operator ->() { - return *Doc; - } + std::unique_ptr<Document> &operator->() { return *Doc; } private: bool isAtEnd() const { return !Doc || !*Doc; } - OwningPtr<Document> *Doc; + std::unique_ptr<Document> *Doc; }; } diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index c19eb23..ea217c3 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -1,4 +1,4 @@ -//===- llvm/Supporrt/YAMLTraits.h -------------------------------*- C++ -*-===// +//===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===// // // The LLVM Linker // @@ -13,19 +13,17 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/Support/type_traits.h" - namespace llvm { namespace yaml { @@ -45,6 +43,8 @@ template<class T> struct MappingTraits { // Must provide: // static void mapping(IO &io, T &fields); + // Optionally may provide: + // static StringRef validate(IO &io, T &fields); }; @@ -227,6 +227,23 @@ public: static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1); }; +// Test if MappingTraits<T>::validate() is defined on type T. +template <class T> +struct has_MappingValidateTraits +{ + typedef StringRef (*Signature_validate)(class IO&, T&); + + template <typename U> + static char test(SameType<Signature_validate, &U::validate>*); + + template <typename U> + static double test(...); + +public: + static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1); +}; + + // Test if SequenceTraits<T> is defined on type T. template <class T> @@ -248,7 +265,7 @@ public: // has_FlowTraits<int> will cause an error with some compilers because // it subclasses int. Using this wrapper only instantiates the // real has_FlowTraits only if the template type is a class. -template <typename T, bool Enabled = llvm::is_class<T>::value> +template <typename T, bool Enabled = std::is_class<T>::value> class has_FlowTraits { public: @@ -278,7 +295,7 @@ public: // Test if SequenceTraits<T> is defined on type T template<typename T> -struct has_SequenceTraits : public llvm::integral_constant<bool, +struct has_SequenceTraits : public std::integral_constant<bool, has_SequenceMethodTraits<T>::value > { }; @@ -302,7 +319,7 @@ public: template<typename T> -struct missingTraits : public llvm::integral_constant<bool, +struct missingTraits : public std::integral_constant<bool, !has_ScalarEnumerationTraits<T>::value && !has_ScalarBitSetTraits<T>::value && !has_ScalarTraits<T>::value @@ -310,7 +327,15 @@ struct missingTraits : public llvm::integral_constant<bool, && !has_SequenceTraits<T>::value && !has_DocumentListTraits<T>::value > {}; +template<typename T> +struct validatedMappingTraits : public std::integral_constant<bool, + has_MappingTraits<T>::value + && has_MappingValidateTraits<T>::value> {}; +template<typename T> +struct unvalidatedMappingTraits : public std::integral_constant<bool, + has_MappingTraits<T>::value + && !has_MappingValidateTraits<T>::value> {}; // Base class for Input and Output. class IO { public: @@ -318,7 +343,7 @@ public: IO(void *Ctxt=NULL); virtual ~IO(); - virtual bool outputting() const = 0; + virtual bool outputting() = 0; virtual unsigned beginSequence() = 0; virtual bool preflightElement(unsigned, void *&) = 0; @@ -388,7 +413,7 @@ public: } template <typename T> - typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type + typename std::enable_if<has_SequenceTraits<T>::value,void>::type mapOptional(const char* Key, T& Val) { // omit key/value instead of outputting empty sequence if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) ) @@ -397,7 +422,12 @@ public: } template <typename T> - typename llvm::enable_if_c<!has_SequenceTraits<T>::value,void>::type + void mapOptional(const char* Key, Optional<T> &Val) { + processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false); + } + + template <typename T> + typename std::enable_if<!has_SequenceTraits<T>::value,void>::type mapOptional(const char* Key, T& Val) { this->processKey(Key, Val, false); } @@ -409,6 +439,26 @@ public: private: template <typename T> + void processKeyWithDefault(const char *Key, Optional<T> &Val, + const Optional<T> &DefaultValue, bool Required) { + assert(DefaultValue.hasValue() == false && + "Optional<T> shouldn't have a value!"); + void *SaveInfo; + bool UseDefault; + const bool sameAsDefault = outputting() && !Val.hasValue(); + if (!outputting() && !Val.hasValue()) + Val = T(); + if (this->preflightKey(Key, Required, sameAsDefault, UseDefault, + SaveInfo)) { + yamlize(*this, Val.getValue(), Required); + this->postflightKey(SaveInfo); + } else { + if (UseDefault) + Val = DefaultValue; + } + } + + template <typename T> void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue, bool Required) { void *SaveInfo; @@ -442,7 +492,7 @@ private: template<typename T> -typename llvm::enable_if_c<has_ScalarEnumerationTraits<T>::value,void>::type +typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type yamlize(IO &io, T &Val, bool) { io.beginEnumScalar(); ScalarEnumerationTraits<T>::enumeration(io, Val); @@ -450,7 +500,7 @@ yamlize(IO &io, T &Val, bool) { } template<typename T> -typename llvm::enable_if_c<has_ScalarBitSetTraits<T>::value,void>::type +typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type yamlize(IO &io, T &Val, bool) { bool DoClear; if ( io.beginBitSetScalar(DoClear) ) { @@ -463,7 +513,7 @@ yamlize(IO &io, T &Val, bool) { template<typename T> -typename llvm::enable_if_c<has_ScalarTraits<T>::value,void>::type +typename std::enable_if<has_ScalarTraits<T>::value,void>::type yamlize(IO &io, T &Val, bool) { if ( io.outputting() ) { std::string Storage; @@ -484,21 +534,41 @@ yamlize(IO &io, T &Val, bool) { template<typename T> -typename llvm::enable_if_c<has_MappingTraits<T>::value, void>::type +typename std::enable_if<validatedMappingTraits<T>::value, void>::type yamlize(IO &io, T &Val, bool) { io.beginMapping(); + if (io.outputting()) { + StringRef Err = MappingTraits<T>::validate(io, Val); + if (!Err.empty()) { + llvm::errs() << Err << "\n"; + assert(Err.empty() && "invalid struct trying to be written as yaml"); + } + } MappingTraits<T>::mapping(io, Val); + if (!io.outputting()) { + StringRef Err = MappingTraits<T>::validate(io, Val); + if (!Err.empty()) + io.setError(Err); + } io.endMapping(); } template<typename T> -typename llvm::enable_if_c<missingTraits<T>::value, void>::type +typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type +yamlize(IO &io, T &Val, bool) { + io.beginMapping(); + MappingTraits<T>::mapping(io, Val); + io.endMapping(); +} + +template<typename T> +typename std::enable_if<missingTraits<T>::value, void>::type yamlize(IO &io, T &Val, bool) { char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; } template<typename T> -typename llvm::enable_if_c<has_SequenceTraits<T>::value,void>::type +typename std::enable_if<has_SequenceTraits<T>::value,void>::type yamlize(IO &io, T &Seq, bool) { if ( has_FlowTraits< SequenceTraits<T> >::value ) { unsigned incnt = io.beginFlowSequence(); @@ -538,6 +608,12 @@ struct ScalarTraits<StringRef> { static void output(const StringRef &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, StringRef &); }; + +template<> +struct ScalarTraits<std::string> { + static void output(const std::string &, void*, llvm::raw_ostream &); + static StringRef input(StringRef, void*, std::string &); +}; template<> struct ScalarTraits<uint8_t> { @@ -697,32 +773,30 @@ public: // Check if there was an syntax or semantic error during parsing. llvm::error_code error(); - static bool classof(const IO *io) { return !io->outputting(); } - private: - virtual bool outputting() const; - virtual bool mapTag(StringRef, bool); - virtual void beginMapping(); - virtual void endMapping(); - virtual bool preflightKey(const char *, bool, bool, bool &, void *&); - virtual void postflightKey(void *); - virtual unsigned beginSequence(); - virtual void endSequence(); - virtual bool preflightElement(unsigned index, void *&); - virtual void postflightElement(void *); - virtual unsigned beginFlowSequence(); - virtual bool preflightFlowElement(unsigned , void *&); - virtual void postflightFlowElement(void *); - virtual void endFlowSequence(); - virtual void beginEnumScalar(); - virtual bool matchEnumScalar(const char*, bool); - virtual void endEnumScalar(); - virtual bool beginBitSetScalar(bool &); - virtual bool bitSetMatch(const char *, bool ); - virtual void endBitSetScalar(); - virtual void scalarString(StringRef &); - virtual void setError(const Twine &message); - virtual bool canElideEmptySequence(); + bool outputting() override; + bool mapTag(StringRef, bool) override; + void beginMapping() override; + void endMapping() override; + bool preflightKey(const char *, bool, bool, bool &, void *&) override; + void postflightKey(void *) override; + unsigned beginSequence() override; + void endSequence() override; + bool preflightElement(unsigned index, void *&) override; + void postflightElement(void *) override; + unsigned beginFlowSequence() override; + bool preflightFlowElement(unsigned , void *&) override; + void postflightFlowElement(void *) override; + void endFlowSequence() override; + void beginEnumScalar() override; + bool matchEnumScalar(const char*, bool) override; + void endEnumScalar() override; + bool beginBitSetScalar(bool &) override; + bool bitSetMatch(const char *, bool ) override; + void endBitSetScalar() override; + void scalarString(StringRef &) override; + void setError(const Twine &message) override; + bool canElideEmptySequence() override; class HNode { virtual void anchor(); @@ -735,7 +809,7 @@ private: }; class EmptyHNode : public HNode { - virtual void anchor(); + void anchor() override; public: EmptyHNode(Node *n) : HNode(n) { } static inline bool classof(const HNode *n) { @@ -745,7 +819,7 @@ private: }; class ScalarHNode : public HNode { - virtual void anchor(); + void anchor() override; public: ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { } @@ -802,15 +876,15 @@ public: void nextDocument(); private: - llvm::SourceMgr SrcMgr; // must be before Strm - OwningPtr<llvm::yaml::Stream> Strm; - OwningPtr<HNode> TopNode; - llvm::error_code EC; - llvm::BumpPtrAllocator StringAllocator; - llvm::yaml::document_iterator DocIterator; - std::vector<bool> BitValuesUsed; - HNode *CurrentNode; - bool ScalarMatchFound; + llvm::SourceMgr SrcMgr; // must be before Strm + std::unique_ptr<llvm::yaml::Stream> Strm; + std::unique_ptr<HNode> TopNode; + llvm::error_code EC; + llvm::BumpPtrAllocator StringAllocator; + llvm::yaml::document_iterator DocIterator; + std::vector<bool> BitValuesUsed; + HNode *CurrentNode; + bool ScalarMatchFound; }; @@ -825,31 +899,29 @@ public: Output(llvm::raw_ostream &, void *Ctxt=NULL); virtual ~Output(); - static bool classof(const IO *io) { return io->outputting(); } - - virtual bool outputting() const; - virtual bool mapTag(StringRef, bool); - virtual void beginMapping(); - virtual void endMapping(); - virtual bool preflightKey(const char *key, bool, bool, bool &, void *&); - virtual void postflightKey(void *); - virtual unsigned beginSequence(); - virtual void endSequence(); - virtual bool preflightElement(unsigned, void *&); - virtual void postflightElement(void *); - virtual unsigned beginFlowSequence(); - virtual bool preflightFlowElement(unsigned, void *&); - virtual void postflightFlowElement(void *); - virtual void endFlowSequence(); - virtual void beginEnumScalar(); - virtual bool matchEnumScalar(const char*, bool); - virtual void endEnumScalar(); - virtual bool beginBitSetScalar(bool &); - virtual bool bitSetMatch(const char *, bool ); - virtual void endBitSetScalar(); - virtual void scalarString(StringRef &); - virtual void setError(const Twine &message); - virtual bool canElideEmptySequence(); + bool outputting() override; + bool mapTag(StringRef, bool) override; + void beginMapping() override; + void endMapping() override; + bool preflightKey(const char *key, bool, bool, bool &, void *&) override; + void postflightKey(void *) override; + unsigned beginSequence() override; + void endSequence() override; + bool preflightElement(unsigned, void *&) override; + void postflightElement(void *) override; + unsigned beginFlowSequence() override; + bool preflightFlowElement(unsigned, void *&) override; + void postflightFlowElement(void *) override; + void endFlowSequence() override; + void beginEnumScalar() override; + bool matchEnumScalar(const char*, bool) override; + void endEnumScalar() override; + bool beginBitSetScalar(bool &) override; + bool bitSetMatch(const char *, bool ) override; + void endBitSetScalar() override; + void scalarString(StringRef &) override; + void setError(const Twine &message) override; + bool canElideEmptySequence() override; public: // These are only used by operator<<. They could be private // if that templated operator could be made a friend. @@ -942,7 +1014,7 @@ struct ScalarTraits<Hex64> { // Define non-member operator>> so that Input can stream in a document list. template <typename T> inline -typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Input &>::type +typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type operator>>(Input &yin, T &docList) { int i = 0; while ( yin.setCurrentDocument() ) { @@ -958,7 +1030,7 @@ operator>>(Input &yin, T &docList) { // Define non-member operator>> so that Input can stream in a map as a document. template <typename T> inline -typename llvm::enable_if_c<has_MappingTraits<T>::value,Input &>::type +typename std::enable_if<has_MappingTraits<T>::value, Input &>::type operator>>(Input &yin, T &docMap) { yin.setCurrentDocument(); yamlize(yin, docMap, true); @@ -969,7 +1041,7 @@ operator>>(Input &yin, T &docMap) { // a document. template <typename T> inline -typename llvm::enable_if_c<has_SequenceTraits<T>::value,Input &>::type +typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type operator>>(Input &yin, T &docSeq) { if (yin.setCurrentDocument()) yamlize(yin, docSeq, true); @@ -979,7 +1051,7 @@ operator>>(Input &yin, T &docSeq) { // Provide better error message about types missing a trait specialization template <typename T> inline -typename llvm::enable_if_c<missingTraits<T>::value,Input &>::type +typename std::enable_if<missingTraits<T>::value, Input &>::type operator>>(Input &yin, T &docSeq) { char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; return yin; @@ -989,7 +1061,7 @@ operator>>(Input &yin, T &docSeq) { // Define non-member operator<< so that Output can stream out document list. template <typename T> inline -typename llvm::enable_if_c<has_DocumentListTraits<T>::value,Output &>::type +typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type operator<<(Output &yout, T &docList) { yout.beginDocuments(); const size_t count = DocumentListTraits<T>::size(yout, docList); @@ -1006,7 +1078,7 @@ operator<<(Output &yout, T &docList) { // Define non-member operator<< so that Output can stream out a map. template <typename T> inline -typename llvm::enable_if_c<has_MappingTraits<T>::value,Output &>::type +typename std::enable_if<has_MappingTraits<T>::value, Output &>::type operator<<(Output &yout, T &map) { yout.beginDocuments(); if ( yout.preflightDocument(0) ) { @@ -1020,7 +1092,7 @@ operator<<(Output &yout, T &map) { // Define non-member operator<< so that Output can stream out a sequence. template <typename T> inline -typename llvm::enable_if_c<has_SequenceTraits<T>::value,Output &>::type +typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type operator<<(Output &yout, T &seq) { yout.beginDocuments(); if ( yout.preflightDocument(0) ) { @@ -1034,7 +1106,7 @@ operator<<(Output &yout, T &seq) { // Provide better error message about types missing a trait specialization template <typename T> inline -typename llvm::enable_if_c<missingTraits<T>::value,Output &>::type +typename std::enable_if<missingTraits<T>::value, Output &>::type operator<<(Output &yout, T &seq) { char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)]; return yout; @@ -1075,6 +1147,7 @@ operator<<(Output &yout, T &seq) { return seq.size(); \ } \ static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\ + (void)flow; /* Remove this workaround after PR17897 is fixed */ \ if ( index >= seq.size() ) \ seq.resize(index+1); \ return seq[index]; \ diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h index 9000306..3114199 100644 --- a/include/llvm/Support/circular_raw_ostream.h +++ b/include/llvm/Support/circular_raw_ostream.h @@ -81,12 +81,12 @@ namespace llvm Filled = false; } - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, /// not counting the bytes currently in the buffer. /// - virtual uint64_t current_pos() const LLVM_OVERRIDE { + uint64_t current_pos() const override { // This has the same effect as calling TheStream.current_pos(), // but that interface is private. return TheStream->tell() - TheStream->GetNumBytesInBuffer(); diff --git a/include/llvm/Support/raw_os_ostream.h b/include/llvm/Support/raw_os_ostream.h index 4385721..04cf3b6 100644 --- a/include/llvm/Support/raw_os_ostream.h +++ b/include/llvm/Support/raw_os_ostream.h @@ -26,11 +26,11 @@ class raw_os_ostream : public raw_ostream { std::ostream &OS; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE; + uint64_t current_pos() const override; public: raw_os_ostream(std::ostream &O) : OS(O) {} diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index ec7e06b..0240035 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -322,14 +322,14 @@ class raw_fd_ostream : public raw_ostream { uint64_t pos; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE { return pos; } + uint64_t current_pos() const override { return pos; } /// preferred_buffer_size - Determine an efficient buffer size. - virtual size_t preferred_buffer_size() const LLVM_OVERRIDE; + size_t preferred_buffer_size() const override; /// error_detected - Set the flag indicating that an output error has /// been encountered. @@ -347,7 +347,7 @@ public: /// file descriptor when it is done (this is necessary to detect /// output errors). raw_fd_ostream(const char *Filename, std::string &ErrorInfo, - sys::fs::OpenFlags Flags = sys::fs::F_None); + sys::fs::OpenFlags Flags); /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If /// ShouldClose is true, this closes the file when the stream is destroyed. @@ -373,15 +373,15 @@ public: UseAtomicWrites = Value; } - virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, - bool bg=false) LLVM_OVERRIDE; - virtual raw_ostream &resetColor() LLVM_OVERRIDE; + raw_ostream &changeColor(enum Colors colors, bool bold=false, + bool bg=false) override; + raw_ostream &resetColor() override; - virtual raw_ostream &reverseColor() LLVM_OVERRIDE; + raw_ostream &reverseColor() override; - virtual bool is_displayed() const LLVM_OVERRIDE; + bool is_displayed() const override; - virtual bool has_colors() const LLVM_OVERRIDE; + bool has_colors() const override; /// has_error - Return the value of the flag in this raw_fd_ostream indicating /// whether an output error has been encountered. @@ -427,11 +427,11 @@ class raw_string_ostream : public raw_ostream { std::string &OS; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE { return OS.size(); } + uint64_t current_pos() const override { return OS.size(); } public: explicit raw_string_ostream(std::string &O) : OS(O) {} ~raw_string_ostream(); @@ -451,11 +451,11 @@ class raw_svector_ostream : public raw_ostream { SmallVectorImpl<char> &OS; /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t Size) override; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE; + uint64_t current_pos() const override; public: /// Construct a new raw_svector_ostream. /// @@ -477,11 +477,11 @@ public: /// raw_null_ostream - A raw_ostream that discards all output. class raw_null_ostream : public raw_ostream { /// write_impl - See raw_ostream::write_impl. - virtual void write_impl(const char *Ptr, size_t size) LLVM_OVERRIDE; + void write_impl(const char *Ptr, size_t size) override; /// current_pos - Return the current position within the stream, not /// counting the bytes currently in the buffer. - virtual uint64_t current_pos() const LLVM_OVERRIDE; + uint64_t current_pos() const override; public: explicit raw_null_ostream() {} diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h index 43dace6..4ca4b06 100644 --- a/include/llvm/Support/system_error.h +++ b/include/llvm/Support/system_error.h @@ -48,10 +48,10 @@ const error_category& generic_category(); const error_category& system_category(); template <class T> struct is_error_code_enum - : public false_type {}; + : public std::false_type {}; template <class T> struct is_error_condition_enum - : public false_type {}; + : public std::false_type {}; class error_code { @@ -203,7 +203,7 @@ enum class errc wrong_protocol_type // EPROTOTYPE }; -template <> struct is_error_condition_enum<errc> : true_type { } +template <> struct is_error_condition_enum<errc> : std::true_type { } error_code make_error_code(errc e); error_condition make_error_condition(errc e); @@ -225,7 +225,6 @@ template <> struct hash<std::error_code>; */ #include "llvm/Config/llvm-config.h" -#include "llvm/Support/type_traits.h" #include <cerrno> #include <string> @@ -474,11 +473,11 @@ namespace llvm { // is_error_code_enum -template <class Tp> struct is_error_code_enum : public false_type {}; +template <class Tp> struct is_error_code_enum : public std::false_type {}; // is_error_condition_enum -template <class Tp> struct is_error_condition_enum : public false_type {}; +template <class Tp> struct is_error_condition_enum : public std::false_type {}; // Some error codes are not present on all platforms, so we provide equivalents // for them: @@ -613,9 +612,9 @@ enum _ { operator int() const {return v_;} }; -template <> struct is_error_condition_enum<errc> : true_type { }; +template <> struct is_error_condition_enum<errc> : std::true_type { }; -template <> struct is_error_condition_enum<errc::_> : true_type { }; +template <> struct is_error_condition_enum<errc::_> : std::true_type { }; class error_condition; class error_code; @@ -629,8 +628,8 @@ class error_category public: virtual ~error_category(); -private: error_category(); +private: error_category(const error_category&) LLVM_DELETED_FUNCTION; error_category& operator=(const error_category&) LLVM_DELETED_FUNCTION; @@ -653,7 +652,7 @@ public: class _do_message : public error_category { public: - virtual std::string message(int ev) const LLVM_OVERRIDE; + std::string message(int ev) const override; }; const error_category& generic_category(); @@ -675,7 +674,7 @@ public: : _val_(_val), _cat_(&_cat) {} template <class E> - error_condition(E _e, typename enable_if_c< + error_condition(E _e, typename std::enable_if< is_error_condition_enum<E>::value >::type* = 0) {*this = make_error_condition(_e);} @@ -686,13 +685,12 @@ public: } template <class E> - typename enable_if_c - < - is_error_condition_enum<E>::value, - error_condition& - >::type - operator=(E _e) - {*this = make_error_condition(_e); return *this;} + typename std::enable_if<is_error_condition_enum<E>::value, + error_condition &>::type + operator=(E _e) { + *this = make_error_condition(_e); + return *this; + } void clear() { _val_ = 0; @@ -737,7 +735,7 @@ public: : _val_(_val), _cat_(&_cat) {} template <class E> - error_code(E _e, typename enable_if_c< + error_code(E _e, typename std::enable_if< is_error_code_enum<E>::value >::type* = 0) { *this = make_error_code(_e); @@ -749,13 +747,11 @@ public: } template <class E> - typename enable_if_c - < - is_error_code_enum<E>::value, - error_code& - >::type - operator=(E _e) - {*this = make_error_code(_e); return *this;} + typename std::enable_if<is_error_code_enum<E>::value, error_code &>::type + operator=(E _e) { + *this = make_error_code(_e); + return *this; + } void clear() { _val_ = 0; @@ -892,9 +888,9 @@ enum _ { }; -template <> struct is_error_code_enum<windows_error> : true_type { }; +template <> struct is_error_code_enum<windows_error> : std::true_type { }; -template <> struct is_error_code_enum<windows_error::_> : true_type { }; +template <> struct is_error_code_enum<windows_error::_> : std::true_type { }; inline error_code make_error_code(windows_error e) { return error_code(static_cast<int>(e), system_category()); diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h index 906e97c..70953a9 100644 --- a/include/llvm/Support/type_traits.h +++ b/include/llvm/Support/type_traits.h @@ -7,18 +7,14 @@ // //===----------------------------------------------------------------------===// // -// This file provides a template class that determines if a type is a class or -// not. The basic mechanism, based on using the pointer to member function of -// a zero argument to a function was "boosted" from the boost type_traits -// library. See http://www.boost.org/ for all the gory details. +// This file provides useful additions to the standard type_traits library. // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_TYPE_TRAITS_H #define LLVM_SUPPORT_TYPE_TRAITS_H -#include "llvm/Support/DataTypes.h" -#include <cstddef> +#include <type_traits> #include <utility> #ifndef __has_feature @@ -26,40 +22,8 @@ #define __has_feature(x) 0 #endif -// This is actually the conforming implementation which works with abstract -// classes. However, enough compilers have trouble with it that most will use -// the one in boost/type_traits/object_traits.hpp. This implementation actually -// works with VC7.0, but other interactions seem to fail when we use it. - namespace llvm { - -namespace dont_use -{ - // These two functions should never be used. They are helpers to - // the is_class template below. They cannot be located inside - // is_class because doing so causes at least GCC to think that - // the value of the "value" enumerator is not constant. Placing - // them out here (for some strange reason) allows the sizeof - // operator against them to magically be constant. This is - // important to make the is_class<T>::value idiom zero cost. it - // evaluates to a constant 1 or 0 depending on whether the - // parameter T is a class or not (respectively). - template<typename T> char is_class_helper(void(T::*)()); - template<typename T> double is_class_helper(...); -} -template <typename T> -struct is_class -{ - // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For - // more details: - // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1 -public: - static const bool value = - sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)); -}; - - /// isPodLike - This is a type trait that is used to determine whether a given /// type can be copied around with memcpy instead of running ctors etc. template <typename T> @@ -71,7 +35,7 @@ struct isPodLike { #else // If we don't know anything else, we can (at least) assume that all non-class // types are PODs. - static const bool value = !is_class<T>::value; + static const bool value = !std::is_class<T>::value; #endif }; @@ -80,161 +44,45 @@ template<typename T, typename U> struct isPodLike<std::pair<T, U> > { static const bool value = isPodLike<T>::value && isPodLike<U>::value; }; - - -template <class T, T v> -struct integral_constant { - typedef T value_type; - static const value_type value = v; - typedef integral_constant<T,v> type; - operator value_type() { return value; } -}; - -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; - -/// \brief Metafunction that determines whether the two given types are -/// equivalent. -template<typename T, typename U> struct is_same : public false_type {}; -template<typename T> struct is_same<T, T> : public true_type {}; - -/// \brief Metafunction that removes const qualification from a type. -template <typename T> struct remove_const { typedef T type; }; -template <typename T> struct remove_const<const T> { typedef T type; }; - -/// \brief Metafunction that removes volatile qualification from a type. -template <typename T> struct remove_volatile { typedef T type; }; -template <typename T> struct remove_volatile<volatile T> { typedef T type; }; - -/// \brief Metafunction that removes both const and volatile qualification from -/// a type. -template <typename T> struct remove_cv { - typedef typename remove_const<typename remove_volatile<T>::type>::type type; -}; - -/// \brief Helper to implement is_integral metafunction. -template <typename T> struct is_integral_impl : false_type {}; -template <> struct is_integral_impl< bool> : true_type {}; -template <> struct is_integral_impl< char> : true_type {}; -template <> struct is_integral_impl< signed char> : true_type {}; -template <> struct is_integral_impl<unsigned char> : true_type {}; -template <> struct is_integral_impl< wchar_t> : true_type {}; -template <> struct is_integral_impl< short> : true_type {}; -template <> struct is_integral_impl<unsigned short> : true_type {}; -template <> struct is_integral_impl< int> : true_type {}; -template <> struct is_integral_impl<unsigned int> : true_type {}; -template <> struct is_integral_impl< long> : true_type {}; -template <> struct is_integral_impl<unsigned long> : true_type {}; -template <> struct is_integral_impl< long long> : true_type {}; -template <> struct is_integral_impl<unsigned long long> : true_type {}; - -/// \brief Metafunction that determines whether the given type is an integral -/// type. -template <typename T> -struct is_integral : is_integral_impl<T> {}; - -/// \brief Metafunction to remove reference from a type. -template <typename T> struct remove_reference { typedef T type; }; -template <typename T> struct remove_reference<T&> { typedef T type; }; - -/// \brief Metafunction that determines whether the given type is a pointer -/// type. -template <typename T> struct is_pointer : false_type {}; -template <typename T> struct is_pointer<T*> : true_type {}; -template <typename T> struct is_pointer<T* const> : true_type {}; -template <typename T> struct is_pointer<T* volatile> : true_type {}; -template <typename T> struct is_pointer<T* const volatile> : true_type {}; - -/// \brief Metafunction that determines wheather the given type is a reference. -template <typename T> struct is_reference : false_type {}; -template <typename T> struct is_reference<T&> : true_type {}; /// \brief Metafunction that determines whether the given type is either an /// integral type or an enumeration type. /// -/// Note that this accepts potentially more integral types than we whitelist -/// above for is_integral because it is based on merely being convertible -/// implicitly to an integral type. +/// Note that this accepts potentially more integral types than is_integral +/// because it is based on merely being convertible implicitly to an integral +/// type. template <typename T> class is_integral_or_enum { - // Provide an overload which can be called with anything implicitly - // convertible to an unsigned long long. This should catch integer types and - // enumeration types at least. We blacklist classes with conversion operators - // below. - static double check_int_convertible(unsigned long long); - static char check_int_convertible(...); - - typedef typename remove_reference<T>::type UnderlyingT; - static UnderlyingT &nonce_instance; + typedef typename std::remove_reference<T>::type UnderlyingT; public: - static const bool - value = (!is_class<UnderlyingT>::value && !is_pointer<UnderlyingT>::value && - !is_same<UnderlyingT, float>::value && - !is_same<UnderlyingT, double>::value && - sizeof(char) != sizeof(check_int_convertible(nonce_instance))); -}; - -// enable_if_c - Enable/disable a template based on a metafunction -template<bool Cond, typename T = void> -struct enable_if_c { - typedef T type; -}; - -template<typename T> struct enable_if_c<false, T> { }; - -// enable_if - Enable/disable a template based on a metafunction -template<typename Cond, typename T = void> -struct enable_if : public enable_if_c<Cond::value, T> { }; - -namespace dont_use { - template<typename Base> char base_of_helper(const volatile Base*); - template<typename Base> double base_of_helper(...); -} - -/// is_base_of - Metafunction to determine whether one type is a base class of -/// (or identical to) another type. -template<typename Base, typename Derived> -struct is_base_of { - static const bool value - = is_class<Base>::value && is_class<Derived>::value && - sizeof(char) == sizeof(dont_use::base_of_helper<Base>((Derived*)0)); + static const bool value = + !std::is_class<UnderlyingT>::value && // Filter conversion operators. + !std::is_pointer<UnderlyingT>::value && + !std::is_floating_point<UnderlyingT>::value && + std::is_convertible<UnderlyingT, unsigned long long>::value; }; -// remove_pointer - Metafunction to turn Foo* into Foo. Defined in -// C++0x [meta.trans.ptr]. -template <typename T> struct remove_pointer { typedef T type; }; -template <typename T> struct remove_pointer<T*> { typedef T type; }; -template <typename T> struct remove_pointer<T*const> { typedef T type; }; -template <typename T> struct remove_pointer<T*volatile> { typedef T type; }; -template <typename T> struct remove_pointer<T*const volatile> { - typedef T type; }; - -// If T is a pointer, just return it. If it is not, return T&. +/// \brief If T is a pointer, just return it. If it is not, return T&. template<typename T, typename Enable = void> struct add_lvalue_reference_if_not_pointer { typedef T &type; }; -template<typename T> -struct add_lvalue_reference_if_not_pointer<T, - typename enable_if<is_pointer<T> >::type> { +template <typename T> +struct add_lvalue_reference_if_not_pointer< + T, typename std::enable_if<std::is_pointer<T>::value>::type> { typedef T type; }; -// If T is a pointer to X, return a pointer to const X. If it is not, return -// const T. +/// \brief If T is a pointer to X, return a pointer to const X. If it is not, +/// return const T. template<typename T, typename Enable = void> struct add_const_past_pointer { typedef const T type; }; -template<typename T> -struct add_const_past_pointer<T, typename enable_if<is_pointer<T> >::type> { - typedef const typename remove_pointer<T>::type *type; +template <typename T> +struct add_const_past_pointer< + T, typename std::enable_if<std::is_pointer<T>::value>::type> { + typedef const typename std::remove_pointer<T>::type *type; }; -template <bool, typename T, typename F> -struct conditional { typedef T type; }; - -template <typename T, typename F> -struct conditional<false, T, F> { typedef F type; }; - } #ifdef LLVM_DEFINED_HAS_FEATURE |