summaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/AlignOf.h92
-rw-r--r--include/llvm/Support/COFF.h10
-rw-r--r--include/llvm/Support/CallSite.h5
-rw-r--r--include/llvm/Support/CommandLine.h8
-rw-r--r--include/llvm/Support/Compiler.h21
-rw-r--r--include/llvm/Support/ConstantRange.h4
-rw-r--r--include/llvm/Support/DataTypes.h.cmake12
-rw-r--r--include/llvm/Support/DataTypes.h.in12
-rw-r--r--include/llvm/Support/Debug.h8
-rw-r--r--include/llvm/Support/DebugLoc.h9
-rw-r--r--include/llvm/Support/ELF.h130
-rw-r--r--include/llvm/Support/Endian.h8
-rw-r--r--include/llvm/Support/FileOutputBuffer.h97
-rw-r--r--include/llvm/Support/FileSystem.h109
-rw-r--r--include/llvm/Support/GCOV.h20
-rw-r--r--include/llvm/Support/GraphWriter.h4
-rw-r--r--include/llvm/Support/IRBuilder.h1281
-rw-r--r--include/llvm/Support/InstVisitor.h53
-rw-r--r--include/llvm/Support/IntegersSubset.h541
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h580
-rw-r--r--include/llvm/Support/LEB128.h58
-rw-r--r--include/llvm/Support/MDBuilder.h118
-rw-r--r--include/llvm/Support/MachO.h82
-rw-r--r--include/llvm/Support/MathExtras.h4
-rw-r--r--include/llvm/Support/PathV2.h6
-rw-r--r--include/llvm/Support/Process.h10
-rw-r--r--include/llvm/Support/SMLoc.h3
-rw-r--r--include/llvm/Support/SourceMgr.h13
-rw-r--r--include/llvm/Support/TargetRegistry.h20
-rw-r--r--include/llvm/Support/ThreadLocal.h11
-rw-r--r--include/llvm/Support/TypeBuilder.h399
-rw-r--r--include/llvm/Support/ValueHandle.h11
-rw-r--r--include/llvm/Support/YAMLParser.h33
-rw-r--r--include/llvm/Support/raw_ostream.h7
-rw-r--r--include/llvm/Support/type_traits.h15
35 files changed, 1851 insertions, 1943 deletions
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index cebfa79..85607c8 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -15,6 +15,9 @@
#ifndef LLVM_SUPPORT_ALIGNOF_H
#define LLVM_SUPPORT_ALIGNOF_H
+#include "llvm/Support/Compiler.h"
+#include <cstddef>
+
namespace llvm {
template <typename T>
@@ -54,7 +57,94 @@ struct AlignOf {
/// class besides some cosmetic cleanliness. Example usage:
/// alignOf<int>() returns the alignment of an int.
template <typename T>
-static inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+inline unsigned alignOf() { return AlignOf<T>::Alignment; }
+
+
+/// \brief Helper for building an aligned character array type.
+///
+/// This template is used to explicitly build up a collection of aligned
+/// character types. We have to build these up using a macro and explicit
+/// specialization to cope with old versions of MSVC and GCC where only an
+/// integer literal can be used to specify an alignment constraint. Once built
+/// up here, we can then begin to indirect between these using normal C++
+/// template parameters.
+template <size_t Alignment> struct AlignedCharArrayImpl {};
+template <> struct AlignedCharArrayImpl<0> {
+ typedef char type;
+};
+#if __has_feature(cxx_alignas)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef char alignas(x) type; \
+ }
+#elif defined(__clang__) || defined(__GNUC__)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef char type __attribute__((aligned(x))); \
+ }
+#elif defined(_MSC_VER)
+#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
+ template <> struct AlignedCharArrayImpl<x> { \
+ typedef __declspec(align(x)) char type; \
+ }
+#else
+# error No supported align as directive.
+#endif
+
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
+LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
+// Any larger and MSVC complains.
+#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
+
+/// \brief This class template exposes a typedef for type containing a suitable
+/// aligned character array to hold elements of any of up to four types.
+///
+/// These types may be arrays, structs, or any other types. The goal is to
+/// produce a union type containing a character array which, when used, forms
+/// storage suitable to placement new any of these types over. Support for more
+/// than four types can be added at the cost of more boiler plate.
+template <typename T1,
+ typename T2 = char, typename T3 = char, typename T4 = char>
+class AlignedCharArray {
+ class AlignerImpl {
+ T1 t1; T2 t2; T3 t3; T4 t4;
+
+ AlignerImpl(); // Never defined or instantiated.
+ };
+ union SizerImpl {
+ char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
+ };
+
+public:
+ // Sadly, Clang and GCC both fail to align a character array properly even
+ // with an explicit alignment attribute. To work around this, we union
+ // the character array that will actually be used with a struct that contains
+ // a single aligned character member. Tests seem to indicate that both Clang
+ // and GCC will properly register the alignment of a struct containing an
+ // aligned member, and this alignment should carry over to the character
+ // array in the union.
+ union union_type {
+ // This is the only member of the union which should be used by clients:
+ char buffer[sizeof(SizerImpl)];
+
+ // This member of the union only exists to force the alignment.
+ struct {
+ typename llvm::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment>::type
+ nonce_inner_member;
+ } nonce_member;
+ };
+};
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index 88c60ba..6c2ee08 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -50,6 +50,8 @@ namespace COFF {
};
enum MachineTypes {
+ MT_Invalid = -1,
+
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x13,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
@@ -74,6 +76,8 @@ namespace COFF {
};
enum Characteristics {
+ C_Invalid = 0,
+
/// The file does not contain base relocations and must be loaded at its
/// preferred base. If this cannot be done, the loader will error.
IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
@@ -114,9 +118,9 @@ namespace COFF {
struct symbol {
char Name[NameSize];
uint32_t Value;
+ uint16_t SectionNumber;
uint16_t Type;
uint8_t StorageClass;
- uint16_t SectionNumber;
uint8_t NumberOfAuxSymbols;
};
@@ -138,6 +142,8 @@ namespace COFF {
/// Storage class tells where and what the symbol represents
enum SymbolStorageClass {
+ SSC_Invalid = -1,
+
IMAGE_SYM_CLASS_END_OF_FUNCTION = -1, ///< Physical end of function
IMAGE_SYM_CLASS_NULL = 0, ///< No symbol
IMAGE_SYM_CLASS_AUTOMATIC = 1, ///< Stack variable
@@ -214,6 +220,8 @@ namespace COFF {
};
enum SectionCharacteristics {
+ SC_Invalid = -1,
+
IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
IMAGE_SCN_CNT_CODE = 0x00000020,
IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
index 20634ed..c23bb6a 100644
--- a/include/llvm/Support/CallSite.h
+++ b/include/llvm/Support/CallSite.h
@@ -184,6 +184,11 @@ public:
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
}
+ /// \brief Return true if this function has the given attribute.
+ bool hasFnAttr(Attributes N) const {
+ CALLSITE_DELEGATE_GETTER(hasFnAttr(N));
+ }
+
/// paramHasAttr - whether the call or the callee has the given attribute.
bool paramHasAttr(uint16_t i, Attributes attr) const {
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index c212d2d..ae1570d 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -217,11 +217,11 @@ public:
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
protected:
- explicit Option(enum NumOccurrencesFlag Occurrences,
+ explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
enum OptionHidden Hidden)
- : NumOccurrences(0), Occurrences(Occurrences), HiddenFlag(Hidden),
- Formatting(NormalFormatting), Position(0),
- AdditionalVals(0), NextRegistered(0),
+ : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
+ HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
+ Position(0), AdditionalVals(0), NextRegistered(0),
ArgStr(""), HelpStr(""), ValueStr("") {
}
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index d0b186e..f654f32 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -19,6 +19,25 @@
# define __has_feature(x) 0
#endif
+/// LLVM_HAS_RVALUE_REFERENCES - Does the compiler provide 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__) \
+ || _MSC_VER >= 1600)
+#define LLVM_USE_RVALUE_REFERENCES 1
+#else
+#define LLVM_USE_RVALUE_REFERENCES 0
+#endif
+
+/// llvm_move - Expands to ::std::move if the compiler supports
+/// r-value references; otherwise, expands to the argument.
+#if LLVM_USE_RVALUE_REFERENCES
+#define llvm_move(value) (::std::move(value))
+#else
+#define llvm_move(value) (value)
+#endif
+
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
@@ -102,7 +121,7 @@
// 3.4 supported this but is buggy in various cases and produces unimplemented
// errors, just use it in GCC 4.0 and later.
#if __GNUC__ > 3
-#define LLVM_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline))
+#define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline
#else
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index ced3a2c..90dd69f 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -155,6 +155,10 @@ public:
/// 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
diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake
index a3a6489..7484abd 100644
--- a/include/llvm/Support/DataTypes.h.cmake
+++ b/include/llvm/Support/DataTypes.h.cmake
@@ -79,18 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#endif
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
index b492bb1..b9fb48a 100644
--- a/include/llvm/Support/DataTypes.h.in
+++ b/include/llvm/Support/DataTypes.h.in
@@ -79,18 +79,6 @@ typedef u_int64_t uint64_t;
#endif
#endif
-#ifdef _OpenBSD_
-#define INT8_MAX 127
-#define INT8_MIN -128
-#define UINT8_MAX 255
-#define INT16_MAX 32767
-#define INT16_MIN -32768
-#define UINT16_MAX 65535
-#define INT32_MAX 2147483647
-#define INT32_MIN -2147483648
-#define UINT32_MAX 4294967295U
-#endif
-
#else /* _MSC_VER */
/* Visual C++ doesn't provide standard integer headers, but it does provide
built-in data types. */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index e723272..896fe84 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -19,7 +19,7 @@
// foo class.
//
// When compiling without assertions, the -debug-* options and all code in
-// DEBUG() statements disappears, so it does not effect the runtime of the code.
+// DEBUG() statements disappears, so it does not affect the runtime of the code.
//
//===----------------------------------------------------------------------===//
@@ -49,11 +49,11 @@ extern bool DebugFlag;
///
bool isCurrentDebugType(const char *Type);
-/// SetCurrentDebugType - Set the current debug type, as if the -debug-only=X
+/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
/// option were specified. Note that DebugFlag also needs to be set to true for
/// debug output to be produced.
///
-void SetCurrentDebugType(const char *Type);
+void setCurrentDebugType(const char *Type);
/// DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug
/// information. In the '-debug' option is specified on the commandline, and if
@@ -70,7 +70,7 @@ void SetCurrentDebugType(const char *Type);
#else
#define isCurrentDebugType(X) (false)
-#define SetCurrentDebugType(X)
+#define setCurrentDebugType(X)
#define DEBUG_WITH_TYPE(TYPE, X) do { } while (0)
#endif
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 2ee9f87..0498075 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -15,9 +15,8 @@
#ifndef LLVM_SUPPORT_DEBUGLOC_H
#define LLVM_SUPPORT_DEBUGLOC_H
-#include "llvm/ADT/DenseMapInfo.h"
-
namespace llvm {
+ template <typename T> struct DenseMapInfo;
class MDNode;
class LLVMContext;
@@ -103,10 +102,10 @@ namespace llvm {
template <>
struct DenseMapInfo<DebugLoc> {
- static DebugLoc getEmptyKey();
- static DebugLoc getTombstoneKey();
+ static DebugLoc getEmptyKey() { return DebugLoc::getEmptyKey(); }
+ static DebugLoc getTombstoneKey() { return DebugLoc::getTombstoneKey(); }
static unsigned getHashValue(const DebugLoc &Key);
- static bool isEqual(const DebugLoc &LHS, const DebugLoc &RHS);
+ static bool isEqual(DebugLoc LHS, DebugLoc RHS) { return LHS == RHS; }
};
} // end namespace llvm
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 04953b6..f7ae60f 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -248,7 +248,7 @@ enum {
EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor
EM_R32C = 162, // Renesas R32C series microprocessors
EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family
- EM_QDSP6 = 164, // QUALCOMM DSP6 Processor
+ EM_HEXAGON = 164, // Qualcomm Hexagon processor
EM_8051 = 165, // Intel 8051 and variants
EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable
// and extensible RISC processors
@@ -674,6 +674,97 @@ enum {
R_MIPS_NUM = 218
};
+// ELF Relocation types for Hexagon
+// Release 5 ABI - Document: 80-V9418-3 Rev. J
+enum {
+ R_HEX_NONE = 0,
+ R_HEX_B22_PCREL = 1,
+ R_HEX_B15_PCREL = 2,
+ R_HEX_B7_PCREL = 3,
+ R_HEX_LO16 = 4,
+ R_HEX_HI16 = 5,
+ R_HEX_32 = 6,
+ R_HEX_16 = 7,
+ R_HEX_8 = 8,
+ R_HEX_GPREL16_0 = 9,
+ R_HEX_GPREL16_1 = 10,
+ R_HEX_GPREL16_2 = 11,
+ R_HEX_GPREL16_3 = 12,
+ R_HEX_HL16 = 13,
+ R_HEX_B13_PCREL = 14,
+ R_HEX_B9_PCREL = 15,
+ R_HEX_B32_PCREL_X = 16,
+ R_HEX_32_6_X = 17,
+ R_HEX_B22_PCREL_X = 18,
+ R_HEX_B15_PCREL_X = 19,
+ R_HEX_B13_PCREL_X = 20,
+ R_HEX_B9_PCREL_X = 21,
+ R_HEX_B7_PCREL_X = 22,
+ R_HEX_16_X = 23,
+ R_HEX_12_X = 24,
+ R_HEX_11_X = 25,
+ R_HEX_10_X = 26,
+ R_HEX_9_X = 27,
+ R_HEX_8_X = 28,
+ R_HEX_7_X = 29,
+ R_HEX_6_X = 30,
+ R_HEX_32_PCREL = 31,
+ R_HEX_COPY = 32,
+ R_HEX_GLOB_DAT = 33,
+ R_HEX_JMP_SLOT = 34,
+ R_HEX_RELATIVE = 35,
+ R_HEX_PLT_B22_PCREL = 36,
+ R_HEX_GOTREL_LO16 = 37,
+ R_HEX_GOTREL_HI16 = 38,
+ R_HEX_GOTREL_32 = 39,
+ R_HEX_GOT_LO16 = 40,
+ R_HEX_GOT_HI16 = 41,
+ R_HEX_GOT_32 = 42,
+ R_HEX_GOT_16 = 43,
+ R_HEX_DTPMOD_32 = 44,
+ R_HEX_DTPREL_LO16 = 45,
+ R_HEX_DTPREL_HI16 = 46,
+ R_HEX_DTPREL_32 = 47,
+ R_HEX_DTPREL_16 = 48,
+ R_HEX_GD_PLT_B22_PCREL = 49,
+ R_HEX_GD_GOT_LO16 = 50,
+ R_HEX_GD_GOT_HI16 = 51,
+ R_HEX_GD_GOT_32 = 52,
+ R_HEX_GD_GOT_16 = 53,
+ R_HEX_IE_LO16 = 54,
+ R_HEX_IE_HI16 = 55,
+ R_HEX_IE_32 = 56,
+ R_HEX_IE_GOT_LO16 = 57,
+ R_HEX_IE_GOT_HI16 = 58,
+ R_HEX_IE_GOT_32 = 59,
+ R_HEX_IE_GOT_16 = 60,
+ R_HEX_TPREL_LO16 = 61,
+ R_HEX_TPREL_HI16 = 62,
+ R_HEX_TPREL_32 = 63,
+ R_HEX_TPREL_16 = 64,
+ R_HEX_6_PCREL_X = 65,
+ R_HEX_GOTREL_32_6_X = 66,
+ R_HEX_GOTREL_16_X = 67,
+ R_HEX_GOTREL_11_X = 68,
+ R_HEX_GOT_32_6_X = 69,
+ R_HEX_GOT_16_X = 70,
+ R_HEX_GOT_11_X = 71,
+ R_HEX_DTPREL_32_6_X = 72,
+ R_HEX_DTPREL_16_X = 73,
+ R_HEX_DTPREL_11_X = 74,
+ R_HEX_GD_GOT_32_6_X = 75,
+ R_HEX_GD_GOT_16_X = 76,
+ R_HEX_GD_GOT_11_X = 77,
+ R_HEX_IE_32_6_X = 78,
+ R_HEX_IE_16_X = 79,
+ R_HEX_IE_GOT_32_6_X = 80,
+ R_HEX_IE_GOT_16_X = 81,
+ R_HEX_IE_GOT_11_X = 82,
+ R_HEX_TPREL_32_6_X = 83,
+ R_HEX_TPREL_16_X = 84,
+ R_HEX_TPREL_11_X = 85
+};
+
// Section header.
struct Elf32_Shdr {
Elf32_Word sh_name; // Section name (index into string table)
@@ -736,6 +827,8 @@ enum {
SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_GNU_ATTRIBUTES= 0x6ffffff5, // Object attributes.
+ SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
@@ -1017,6 +1110,9 @@ enum {
PT_SUNW_EH_FRAME = 0x6474e550,
PT_SUNW_UNWIND = 0x6464e550,
+ PT_GNU_STACK = 0x6474e551, // Indicates stack executability.
+ PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
+
PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type.
PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
@@ -1095,7 +1191,16 @@ enum {
DT_LOOS = 0x60000000, // Start of environment specific tags.
DT_HIOS = 0x6FFFFFFF, // End of environment specific tags.
DT_LOPROC = 0x70000000, // Start of processor specific tags.
- DT_HIPROC = 0x7FFFFFFF // End of processor specific tags.
+ DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags.
+
+ DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count.
+ DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count.
+
+ DT_FLAGS_1 = 0X6FFFFFFB, // Flags_1.
+ DT_VERDEF = 0X6FFFFFFC, // The address of the version definition table.
+ DT_VERDEFNUM = 0X6FFFFFFD, // The number of entries in DT_VERDEF.
+ DT_VERNEED = 0X6FFFFFFE, // The address of the version Dependency table.
+ DT_VERNEEDNUM = 0X6FFFFFFF // The number of entries in DT_VERNEED.
};
// DT_FLAGS values.
@@ -1107,6 +1212,27 @@ enum {
DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically.
};
+// State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry.
+enum {
+ DF_1_NOW = 0x00000001, // Set RTLD_NOW for this object.
+ DF_1_GLOBAL = 0x00000002, // Set RTLD_GLOBAL for this object.
+ DF_1_GROUP = 0x00000004, // Set RTLD_GROUP for this object.
+ DF_1_NODELETE = 0x00000008, // Set RTLD_NODELETE for this object.
+ DF_1_LOADFLTR = 0x00000010, // Trigger filtee loading at runtime.
+ DF_1_INITFIRST = 0x00000020, // Set RTLD_INITFIRST for this object.
+ DF_1_NOOPEN = 0x00000040, // Set RTLD_NOOPEN for this object.
+ DF_1_ORIGIN = 0x00000080, // $ORIGIN must be handled.
+ DF_1_DIRECT = 0x00000100, // Direct binding enabled.
+ DF_1_TRANS = 0x00000200,
+ DF_1_INTERPOSE = 0x00000400, // Object is used to interpose.
+ DF_1_NODEFLIB = 0x00000800, // Ignore default lib search path.
+ DF_1_NODUMP = 0x00001000, // Object can't be dldump'ed.
+ DF_1_CONFALT = 0x00002000, // Configuration alternative created.
+ DF_1_ENDFILTEE = 0x00004000, // Filtee terminates filters search.
+ DF_1_DISPRELDNE = 0x00008000, // Disp reloc applied at build time.
+ DF_1_DISPRELPND = 0x00010000 // Disp reloc applied at run-time.
+};
+
// ElfXX_VerDef structure version (GNU versioning)
enum {
VER_DEF_NONE = 0,
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 733ab75..8d5649d 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -49,7 +49,7 @@ struct alignment_access_helper<value_type, unaligned>
namespace endian {
template<typename value_type, alignment align>
- static value_type read_le(const void *memory) {
+ inline value_type read_le(const void *memory) {
value_type t =
reinterpret_cast<const detail::alignment_access_helper
<value_type, align> *>(memory)->val;
@@ -59,7 +59,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static void write_le(void *memory, value_type value) {
+ inline void write_le(void *memory, value_type value) {
if (sys::isBigEndianHost())
value = sys::SwapByteOrder(value);
reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
@@ -67,7 +67,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static value_type read_be(const void *memory) {
+ inline value_type read_be(const void *memory) {
value_type t =
reinterpret_cast<const detail::alignment_access_helper
<value_type, align> *>(memory)->val;
@@ -77,7 +77,7 @@ namespace endian {
}
template<typename value_type, alignment align>
- static void write_be(void *memory, value_type value) {
+ inline void write_be(void *memory, value_type value) {
if (sys::isLittleEndianHost())
value = sys::SwapByteOrder(value);
reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
new file mode 100644
index 0000000..0f07164
--- /dev/null
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -0,0 +1,97 @@
+//=== FileOutputBuffer.h - File Output Buffer -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility for creating a in-memory buffer that will be written to a file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class error_code;
+template<class T> class OwningPtr;
+
+/// FileOutputBuffer - This interface provides simple way to create an in-memory
+/// buffer which will be written to a file. During the lifetime of these
+/// objects, the content or existence of the specified file is undefined. That
+/// is, creating an OutputBuffer for a file may immediately remove the file.
+/// If the FileOutputBuffer is committed, the target file's content will become
+/// the buffer content at the time of the commit. If the FileOutputBuffer is
+/// not committed, the file will be deleted in the FileOutputBuffer destructor.
+class FileOutputBuffer {
+public:
+
+ enum {
+ F_executable = 1 /// set the 'x' bit on the resulting file
+ };
+
+ /// Factory method to create an OutputBuffer object which manages a read/write
+ /// buffer of the specified size. When committed, the buffer will be written
+ /// to the file at the specified path.
+ static error_code create(StringRef FilePath, size_t Size,
+ OwningPtr<FileOutputBuffer> &Result,
+ unsigned Flags=0);
+
+
+ /// Returns a pointer to the start of the buffer.
+ uint8_t *getBufferStart() const {
+ return BufferStart;
+ }
+
+ /// Returns a pointer to the end of the buffer.
+ uint8_t *getBufferEnd() const {
+ return BufferEnd;
+ }
+
+ /// Returns size of the buffer.
+ size_t getBufferSize() const {
+ return BufferEnd - BufferStart;
+ }
+
+ /// Returns path where file will show up if buffer is committed.
+ StringRef getPath() const {
+ return FinalPath;
+ }
+
+ /// Flushes the content of the buffer to its file and deallocates the
+ /// buffer. If commit() is not called before this object's destructor
+ /// is called, the file is deleted in the destructor. The optional parameter
+ /// is used if it turns out you want the file size to be smaller than
+ /// initially requested.
+ error_code commit(int64_t NewSmallerSize = -1);
+
+ /// If this object was previously committed, the destructor just deletes
+ /// this object. If this object was not committed, the destructor
+ /// deallocates the buffer and the target file is never written.
+ ~FileOutputBuffer();
+
+
+protected:
+ FileOutputBuffer(const FileOutputBuffer &); // DO NOT IMPLEMENT
+ FileOutputBuffer &operator=(const FileOutputBuffer &); // DO NOT IMPLEMENT
+ FileOutputBuffer(uint8_t *Start, uint8_t *End,
+ StringRef Path, StringRef TempPath);
+
+ uint8_t *BufferStart;
+ uint8_t *BufferEnd;
+ SmallString<128> FinalPath;
+ SmallString<128> TempPath;
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index e6f9926..e0353f9 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -94,13 +94,62 @@ struct space_info {
uint64_t available;
};
+
+enum perms {
+ no_perms = 0,
+ owner_read = 0400,
+ owner_write = 0200,
+ owner_exe = 0100,
+ owner_all = owner_read | owner_write | owner_exe,
+ group_read = 040,
+ group_write = 020,
+ group_exe = 010,
+ group_all = group_read | group_write | group_exe,
+ others_read = 04,
+ others_write = 02,
+ others_exe = 01,
+ others_all = others_read | others_write | others_exe,
+ all_all = owner_all | group_all | others_all,
+ set_uid_on_exe = 04000,
+ set_gid_on_exe = 02000,
+ sticky_bit = 01000,
+ perms_mask = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit,
+ perms_not_known = 0xFFFF,
+ add_perms = 0x1000,
+ remove_perms = 0x2000,
+ symlink_perms = 0x4000
+};
+
+// Helper functions so that you can use & and | to manipulate perms bits:
+inline perms operator|(perms l , perms r) {
+ return static_cast<perms>(
+ static_cast<unsigned short>(l) | static_cast<unsigned short>(r));
+}
+inline perms operator&(perms l , perms r) {
+ return static_cast<perms>(
+ static_cast<unsigned short>(l) & static_cast<unsigned short>(r));
+}
+inline perms &operator|=(perms &l, perms r) {
+ l = l | r;
+ return l;
+}
+inline perms &operator&=(perms &l, perms r) {
+ l = l & r;
+ return l;
+}
+inline perms operator~(perms x) {
+ return static_cast<perms>(~static_cast<unsigned short>(x));
+}
+
+
+
/// file_status - Represents the result of a call to stat and friends. It has
/// a platform specific member to store the result.
class file_status
{
#if defined(LLVM_ON_UNIX)
- dev_t st_dev;
- ino_t st_ino;
+ dev_t fs_st_dev;
+ ino_t fs_st_ino;
#elif defined (LLVM_ON_WIN32)
uint32_t LastWriteTimeHigh;
uint32_t LastWriteTimeLow;
@@ -113,12 +162,19 @@ class file_status
friend bool equivalent(file_status A, file_status B);
friend error_code status(const Twine &path, file_status &result);
file_type Type;
+ perms Perms;
public:
- explicit file_status(file_type v=file_type::status_error)
- : Type(v) {}
+ explicit file_status(file_type v=file_type::status_error,
+ perms prms=perms_not_known)
+ : Type(v), Perms(prms) {}
+ // getters
file_type type() const { return Type; }
+ perms permissions() const { return Perms; }
+
+ // setters
void type(file_type v) { Type = v; }
+ void permissions(perms p) { Perms = p; }
};
/// file_magic - An "enum class" enumeration of file types based on magic (the first
@@ -309,6 +365,13 @@ bool equivalent(file_status A, file_status B);
/// platform specific error_code.
error_code equivalent(const Twine &A, const Twine &B, bool &result);
+/// @brief Simpler version of equivalent for clients that don't need to
+/// differentiate between an error and false.
+inline bool equivalent(const Twine &A, const Twine &B) {
+ bool result;
+ return !equivalent(A, B, result) && result;
+}
+
/// @brief Get file size.
///
/// @param path Input path.
@@ -388,6 +451,13 @@ error_code is_symlink(const Twine &path, bool &result);
/// platform specific error_code.
error_code status(const Twine &path, file_status &result);
+/// @brief Modifies permission bits on a file
+///
+/// @param path Input path.
+/// @results errc::success if permissions have been changed, otherwise a
+/// platform specific error_code.
+error_code permissions(const Twine &path, perms prms);
+
/// @brief Is status available?
///
/// @param path Input path.
@@ -422,8 +492,8 @@ error_code status_known(const Twine &path, bool &result);
/// @results errc::success if result_{fd,path} have been successfully set,
/// otherwise a platform specific error_code.
error_code unique_file(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path,
- bool makeAbsolute = true);
+ SmallVectorImpl<char> &result_path,
+ bool makeAbsolute = true, unsigned mode = 0600);
/// @brief Canonicalize path.
///
@@ -506,6 +576,33 @@ error_code FindLibrary(const Twine &short_name, SmallVectorImpl<char> &result);
error_code GetMainExecutable(const char *argv0, void *MainAddr,
SmallVectorImpl<char> &result);
+
+/// @brief Memory maps the contents of a file
+///
+/// @param path Path to file to map.
+/// @param file_offset Byte offset in file where mapping should begin.
+/// @param size_t Byte length of range of the file to map.
+/// @param map_writable If true, the file will be mapped in r/w such
+/// that changes to the mapped buffer will be flushed back
+/// to the file. If false, the file will be mapped read-only
+/// and the buffer will be read-only.
+/// @param result Set to the start address of the mapped buffer.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code map_file_pages(const Twine &path, off_t file_offset, size_t size,
+ bool map_writable, void *&result);
+
+
+/// @brief Memory unmaps the contents of a file
+///
+/// @param base Pointer to the start of the buffer.
+/// @param size Byte length of the range to unmmap.
+/// @results errc::success if result has been successfully set, otherwise a
+/// platform specific error_code.
+error_code unmap_file_pages(void *base, size_t size);
+
+
+
/// @}
/// @name Iterators
/// @{
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index 49cd87f..19e1ce8 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -63,8 +63,8 @@ public:
bool readFunctionTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\0' || Tag[3] != '\1') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\0' || Tag[3] != '\1') {
return false;
}
Cursor += 4;
@@ -76,8 +76,8 @@ public:
bool readBlockTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x41' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x41' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -89,8 +89,8 @@ public:
bool readEdgeTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x43' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x43' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -102,8 +102,8 @@ public:
bool readLineTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\x45' || Tag[3] != '\x01') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\x45' || Tag[3] != '\x01') {
return false;
}
Cursor += 4;
@@ -115,8 +115,8 @@ public:
bool readArcTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
- Tag[0] != '\0' || Tag[1] != '\0' ||
- Tag[2] != '\xa1' || Tag[3] != '\1') {
+ Tag[0] != '\0' || Tag[1] != '\0' ||
+ Tag[2] != '\xa1' || Tag[3] != '\1') {
return false;
}
Cursor += 4;
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index ae32da5..f178b0c 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -172,7 +172,7 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
- O << "|" << (void*)Node;
+ O << "|" << static_cast<const void*>(Node);
}
std::string edgeSourceLabels;
@@ -192,7 +192,7 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
- O << "|" << (void*)Node;
+ O << "|" << static_cast<const void*>(Node);
}
if (DTraits.hasEdgeDestLabels()) {
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
deleted file mode 100644
index ef00e8e..0000000
--- a/include/llvm/Support/IRBuilder.h
+++ /dev/null
@@ -1,1281 +0,0 @@
-//===---- llvm/Support/IRBuilder.h - Builder for LLVM 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 IRBuilder class, which is used as a convenient way
-// to create LLVM instructions with a consistent and simplified interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_IRBUILDER_H
-#define LLVM_SUPPORT_IRBUILDER_H
-
-#include "llvm/Instructions.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/ConstantFolder.h"
-
-namespace llvm {
- class MDNode;
-
-/// IRBuilderDefaultInserter - This provides the default implementation of the
-/// IRBuilder 'InsertHelper' method that is called whenever an instruction is
-/// created by IRBuilder and needs to be inserted. By default, this inserts the
-/// instruction at the insertion point.
-template <bool preserveNames = true>
-class IRBuilderDefaultInserter {
-protected:
- void InsertHelper(Instruction *I, const Twine &Name,
- BasicBlock *BB, BasicBlock::iterator InsertPt) const {
- if (BB) BB->getInstList().insert(InsertPt, I);
- if (preserveNames)
- I->setName(Name);
- }
-};
-
-/// IRBuilderBase - Common base class shared among various IRBuilders.
-class IRBuilderBase {
- DebugLoc CurDbgLocation;
-protected:
- BasicBlock *BB;
- BasicBlock::iterator InsertPt;
- LLVMContext &Context;
-public:
-
- IRBuilderBase(LLVMContext &context)
- : Context(context) {
- ClearInsertionPoint();
- }
-
- //===--------------------------------------------------------------------===//
- // Builder configuration methods
- //===--------------------------------------------------------------------===//
-
- /// ClearInsertionPoint - Clear the insertion point: created instructions will
- /// not be inserted into a block.
- void ClearInsertionPoint() {
- BB = 0;
- }
-
- BasicBlock *GetInsertBlock() const { return BB; }
- BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
- LLVMContext &getContext() const { return Context; }
-
- /// SetInsertPoint - This specifies that created instructions should be
- /// appended to the end of the specified block.
- void SetInsertPoint(BasicBlock *TheBB) {
- BB = TheBB;
- InsertPt = BB->end();
- }
-
- /// SetInsertPoint - This specifies that created instructions should be
- /// inserted before the specified instruction.
- void SetInsertPoint(Instruction *I) {
- BB = I->getParent();
- InsertPt = I;
- SetCurrentDebugLocation(I->getDebugLoc());
- }
-
- /// SetInsertPoint - This specifies that created instructions should be
- /// inserted at the specified point.
- void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
- BB = TheBB;
- InsertPt = IP;
- }
-
- /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and
- /// specify that created instructions should be inserted at this point.
- void SetInsertPoint(Use &U) {
- Instruction *UseInst = cast<Instruction>(U.getUser());
- if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
- BasicBlock *PredBB = Phi->getIncomingBlock(U);
- assert(U != PredBB->getTerminator() && "critical edge not split");
- SetInsertPoint(PredBB, PredBB->getTerminator());
- return;
- }
- SetInsertPoint(UseInst);
- }
-
- /// SetCurrentDebugLocation - Set location information used by debugging
- /// information.
- void SetCurrentDebugLocation(const DebugLoc &L) {
- CurDbgLocation = L;
- }
-
- /// getCurrentDebugLocation - Get location information used by debugging
- /// information.
- DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
-
- /// SetInstDebugLocation - If this builder has a current debug location, set
- /// it on the specified instruction.
- void SetInstDebugLocation(Instruction *I) const {
- if (!CurDbgLocation.isUnknown())
- I->setDebugLoc(CurDbgLocation);
- }
-
- /// getCurrentFunctionReturnType - Get the return type of the current function
- /// that we're emitting into.
- Type *getCurrentFunctionReturnType() const;
-
- /// InsertPoint - A saved insertion point.
- class InsertPoint {
- BasicBlock *Block;
- BasicBlock::iterator Point;
-
- public:
- /// Creates a new insertion point which doesn't point to anything.
- InsertPoint() : Block(0) {}
-
- /// Creates a new insertion point at the given location.
- InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint)
- : Block(InsertBlock), Point(InsertPoint) {}
-
- /// isSet - Returns true if this insert point is set.
- bool isSet() const { return (Block != 0); }
-
- llvm::BasicBlock *getBlock() const { return Block; }
- llvm::BasicBlock::iterator getPoint() const { return Point; }
- };
-
- /// saveIP - Returns the current insert point.
- InsertPoint saveIP() const {
- return InsertPoint(GetInsertBlock(), GetInsertPoint());
- }
-
- /// saveAndClearIP - Returns the current insert point, clearing it
- /// in the process.
- InsertPoint saveAndClearIP() {
- InsertPoint IP(GetInsertBlock(), GetInsertPoint());
- ClearInsertionPoint();
- return IP;
- }
-
- /// restoreIP - Sets the current insert point to a previously-saved
- /// location.
- void restoreIP(InsertPoint IP) {
- if (IP.isSet())
- SetInsertPoint(IP.getBlock(), IP.getPoint());
- else
- ClearInsertionPoint();
- }
-
- //===--------------------------------------------------------------------===//
- // Miscellaneous creation methods.
- //===--------------------------------------------------------------------===//
-
- /// CreateGlobalString - Make a new global variable with an initializer that
- /// has array of i8 type filled in with the nul terminated string value
- /// specified. The new global variable will be marked mergable with any
- /// others of the same contents. If Name is specified, it is the name of the
- /// global variable created.
- Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
-
- /// getInt1 - Get a constant value representing either true or false.
- ConstantInt *getInt1(bool V) {
- return ConstantInt::get(getInt1Ty(), V);
- }
-
- /// getTrue - Get the constant value for i1 true.
- ConstantInt *getTrue() {
- return ConstantInt::getTrue(Context);
- }
-
- /// getFalse - Get the constant value for i1 false.
- ConstantInt *getFalse() {
- return ConstantInt::getFalse(Context);
- }
-
- /// getInt8 - Get a constant 8-bit value.
- ConstantInt *getInt8(uint8_t C) {
- return ConstantInt::get(getInt8Ty(), C);
- }
-
- /// getInt16 - Get a constant 16-bit value.
- ConstantInt *getInt16(uint16_t C) {
- return ConstantInt::get(getInt16Ty(), C);
- }
-
- /// getInt32 - Get a constant 32-bit value.
- ConstantInt *getInt32(uint32_t C) {
- return ConstantInt::get(getInt32Ty(), C);
- }
-
- /// getInt64 - Get a constant 64-bit value.
- ConstantInt *getInt64(uint64_t C) {
- return ConstantInt::get(getInt64Ty(), C);
- }
-
- /// getInt - Get a constant integer value.
- ConstantInt *getInt(const APInt &AI) {
- return ConstantInt::get(Context, AI);
- }
-
- //===--------------------------------------------------------------------===//
- // Type creation methods
- //===--------------------------------------------------------------------===//
-
- /// getInt1Ty - Fetch the type representing a single bit
- IntegerType *getInt1Ty() {
- return Type::getInt1Ty(Context);
- }
-
- /// getInt8Ty - Fetch the type representing an 8-bit integer.
- IntegerType *getInt8Ty() {
- return Type::getInt8Ty(Context);
- }
-
- /// getInt16Ty - Fetch the type representing a 16-bit integer.
- IntegerType *getInt16Ty() {
- return Type::getInt16Ty(Context);
- }
-
- /// getInt32Ty - Fetch the type resepresenting a 32-bit integer.
- IntegerType *getInt32Ty() {
- return Type::getInt32Ty(Context);
- }
-
- /// getInt64Ty - Fetch the type representing a 64-bit integer.
- IntegerType *getInt64Ty() {
- return Type::getInt64Ty(Context);
- }
-
- /// getFloatTy - Fetch the type representing a 32-bit floating point value.
- Type *getFloatTy() {
- return Type::getFloatTy(Context);
- }
-
- /// getDoubleTy - Fetch the type representing a 64-bit floating point value.
- Type *getDoubleTy() {
- return Type::getDoubleTy(Context);
- }
-
- /// getVoidTy - Fetch the type representing void.
- Type *getVoidTy() {
- return Type::getVoidTy(Context);
- }
-
- PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
- return Type::getInt8PtrTy(Context, AddrSpace);
- }
-
- //===--------------------------------------------------------------------===//
- // Intrinsic creation methods
- //===--------------------------------------------------------------------===//
-
- /// CreateMemSet - Create and insert a memset to the specified pointer and the
- /// specified value. If the pointer isn't an i8*, it will be converted. If a
- /// TBAA tag is specified, it will be added to the instruction.
- CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0) {
- return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
- }
-
- CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0);
-
- /// CreateMemCpy - Create and insert a memcpy between the specified pointers.
- /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
- /// specified, it will be added to the instruction.
- CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0) {
- return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
- }
-
- CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0);
-
- /// CreateMemMove - Create and insert a memmove between the specified
- /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
- /// tag is specified, it will be added to the instruction.
- CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0) {
- return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
- }
-
- CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0);
-
- /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
- /// isn't i8* it will be converted.
- CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0);
-
- /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't
- /// i8* it will be converted.
- CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0);
-
-private:
- Value *getCastedInt8PtrValue(Value *Ptr);
-};
-
-/// IRBuilder - This provides a uniform API for creating instructions and
-/// inserting them into a basic block: either at the end of a BasicBlock, or
-/// at a specific iterator location in a block.
-///
-/// Note that the builder does not expose the full generality of LLVM
-/// instructions. For access to extra instruction properties, use the mutators
-/// (e.g. setVolatile) on the instructions after they have been created.
-/// The first template argument handles whether or not to preserve names in the
-/// final instruction output. This defaults to on. The second template argument
-/// specifies a class to use for creating constants. This defaults to creating
-/// minimally folded constants. The fourth template argument allows clients to
-/// specify custom insertion hooks that are called on every newly created
-/// insertion.
-template<bool preserveNames = true, typename T = ConstantFolder,
- typename Inserter = IRBuilderDefaultInserter<preserveNames> >
-class IRBuilder : public IRBuilderBase, public Inserter {
- T Folder;
- MDNode *DefaultFPMathTag;
-public:
- IRBuilder(LLVMContext &C, const T &F, const Inserter &I = Inserter(),
- MDNode *FPMathTag = 0)
- : IRBuilderBase(C), Inserter(I), Folder(F), DefaultFPMathTag(FPMathTag) {
- }
-
- explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = 0) : IRBuilderBase(C),
- Folder(), DefaultFPMathTag(FPMathTag) {
- }
-
- explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = 0)
- : IRBuilderBase(TheBB->getContext()), Folder(F),
- DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(TheBB);
- }
-
- explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = 0)
- : IRBuilderBase(TheBB->getContext()), Folder(),
- DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(TheBB);
- }
-
- explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = 0)
- : IRBuilderBase(IP->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(IP);
- SetCurrentDebugLocation(IP->getDebugLoc());
- }
-
- explicit IRBuilder(Use &U, MDNode *FPMathTag = 0)
- : IRBuilderBase(U->getContext()), Folder(), DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(U);
- SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
- }
-
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F,
- MDNode *FPMathTag = 0)
- : IRBuilderBase(TheBB->getContext()), Folder(F),
- DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(TheBB, IP);
- }
-
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, MDNode *FPMathTag = 0)
- : IRBuilderBase(TheBB->getContext()), Folder(),
- DefaultFPMathTag(FPMathTag) {
- SetInsertPoint(TheBB, IP);
- }
-
- /// getFolder - Get the constant folder being used.
- const T &getFolder() { return Folder; }
-
- /// getDefaultFPMathTag - Get the floating point math metadata being used.
- MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
-
- /// SetDefaultFPMathTag - Set the floating point math metadata to be used.
- void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
-
- /// isNamePreserving - Return true if this builder is configured to actually
- /// add the requested names to IR created through it.
- bool isNamePreserving() const { return preserveNames; }
-
- /// Insert - Insert and return the specified instruction.
- template<typename InstTy>
- InstTy *Insert(InstTy *I, const Twine &Name = "") const {
- this->InsertHelper(I, Name, BB, InsertPt);
- if (!getCurrentDebugLocation().isUnknown())
- this->SetInstDebugLocation(I);
- return I;
- }
-
- /// Insert - No-op overload to handle constants.
- Constant *Insert(Constant *C, const Twine& = "") const {
- return C;
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Terminators
- //===--------------------------------------------------------------------===//
-
- /// CreateRetVoid - Create a 'ret void' instruction.
- ReturnInst *CreateRetVoid() {
- return Insert(ReturnInst::Create(Context));
- }
-
- /// @verbatim
- /// CreateRet - Create a 'ret <val>' instruction.
- /// @endverbatim
- ReturnInst *CreateRet(Value *V) {
- return Insert(ReturnInst::Create(Context, V));
- }
-
- /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
- /// with one Value from the retVals array each, that build a aggregate
- /// return value one value at a time, and a ret instruction to return
- /// the resulting aggregate value. This is a convenience function for
- /// code that uses aggregate return values as a vehicle for having
- /// multiple return values.
- ///
- ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) {
- Value *V = UndefValue::get(getCurrentFunctionReturnType());
- for (unsigned i = 0; i != N; ++i)
- V = CreateInsertValue(V, retVals[i], i, "mrv");
- return Insert(ReturnInst::Create(Context, V));
- }
-
- /// CreateBr - Create an unconditional 'br label X' instruction.
- BranchInst *CreateBr(BasicBlock *Dest) {
- return Insert(BranchInst::Create(Dest));
- }
-
- /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
- /// instruction.
- BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
- return Insert(BranchInst::Create(True, False, Cond));
- }
-
- /// CreateSwitch - Create a switch instruction with the specified value,
- /// default dest, and with a hint for the number of cases that will be added
- /// (for efficient allocation).
- SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
- return Insert(SwitchInst::Create(V, Dest, NumCases));
- }
-
- /// CreateIndirectBr - Create an indirect branch instruction with the
- /// specified address operand, with an optional hint for the number of
- /// destinations that will be added (for efficient allocation).
- IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
- return Insert(IndirectBrInst::Create(Addr, NumDests));
- }
-
- InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest, const Twine &Name = "") {
- return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
- ArrayRef<Value *>()),
- Name);
- }
- InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest, Value *Arg1,
- const Twine &Name = "") {
- return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Arg1),
- Name);
- }
- InvokeInst *CreateInvoke3(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest, Value *Arg1,
- Value *Arg2, Value *Arg3,
- const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3 };
- return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
- Name);
- }
- /// CreateInvoke - Create an invoke instruction.
- InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest, ArrayRef<Value *> Args,
- const Twine &Name = "") {
- return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
- Name);
- }
-
- ResumeInst *CreateResume(Value *Exn) {
- return Insert(ResumeInst::Create(Exn));
- }
-
- UnreachableInst *CreateUnreachable() {
- return Insert(new UnreachableInst(Context));
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Binary Operators
- //===--------------------------------------------------------------------===//
-private:
- BinaryOperator *CreateInsertNUWNSWBinOp(BinaryOperator::BinaryOps Opc,
- Value *LHS, Value *RHS,
- const Twine &Name,
- bool HasNUW, bool HasNSW) {
- BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
-
- Instruction *AddFPMathTag(Instruction *I, MDNode *FPMathTag) const {
- if (!FPMathTag)
- FPMathTag = DefaultFPMathTag;
- if (FPMathTag)
- I->setMetadata(LLVMContext::MD_fpmath, FPMathTag);
- return I;
- }
-public:
- Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateAdd(LC, RC, HasNUW, HasNSW), Name);
- return CreateInsertNUWNSWBinOp(Instruction::Add, LHS, RHS, Name,
- HasNUW, HasNSW);
- }
- Value *CreateNSWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateAdd(LHS, RHS, Name, false, true);
- }
- Value *CreateNUWAdd(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateAdd(LHS, RHS, Name, true, false);
- }
- Value *CreateFAdd(Value *LHS, Value *RHS, const Twine &Name = "",
- MDNode *FPMathTag = 0) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFAdd(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFAdd(LHS, RHS),
- FPMathTag), Name);
- }
- Value *CreateSub(Value *LHS, Value *RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateSub(LC, RC), Name);
- return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name,
- HasNUW, HasNSW);
- }
- Value *CreateNSWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateSub(LHS, RHS, Name, false, true);
- }
- Value *CreateNUWSub(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateSub(LHS, RHS, Name, true, false);
- }
- Value *CreateFSub(Value *LHS, Value *RHS, const Twine &Name = "",
- MDNode *FPMathTag = 0) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFSub(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFSub(LHS, RHS),
- FPMathTag), Name);
- }
- Value *CreateMul(Value *LHS, Value *RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateMul(LC, RC), Name);
- return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name,
- HasNUW, HasNSW);
- }
- Value *CreateNSWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateMul(LHS, RHS, Name, false, true);
- }
- Value *CreateNUWMul(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateMul(LHS, RHS, Name, true, false);
- }
- Value *CreateFMul(Value *LHS, Value *RHS, const Twine &Name = "",
- MDNode *FPMathTag = 0) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFMul(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFMul(LHS, RHS),
- FPMathTag), Name);
- }
- Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "",
- bool isExact = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateUDiv(LC, RC, isExact), Name);
- if (!isExact)
- return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
- return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name);
- }
- Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateUDiv(LHS, RHS, Name, true);
- }
- Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "",
- bool isExact = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateSDiv(LC, RC, isExact), Name);
- if (!isExact)
- return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
- return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
- }
- Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateSDiv(LHS, RHS, Name, true);
- }
- Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "",
- MDNode *FPMathTag = 0) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFDiv(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFDiv(LHS, RHS),
- FPMathTag), Name);
- }
- Value *CreateURem(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateURem(LC, RC), Name);
- return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
- }
- Value *CreateSRem(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateSRem(LC, RC), Name);
- return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
- }
- Value *CreateFRem(Value *LHS, Value *RHS, const Twine &Name = "",
- MDNode *FPMathTag = 0) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFRem(LC, RC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFRem(LHS, RHS),
- FPMathTag), Name);
- }
-
- Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateShl(LC, RC, HasNUW, HasNSW), Name);
- return CreateInsertNUWNSWBinOp(Instruction::Shl, LHS, RHS, Name,
- HasNUW, HasNSW);
- }
- Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
- HasNUW, HasNSW);
- }
- Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- return CreateShl(LHS, ConstantInt::get(LHS->getType(), RHS), Name,
- HasNUW, HasNSW);
- }
-
- Value *CreateLShr(Value *LHS, Value *RHS, const Twine &Name = "",
- bool isExact = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateLShr(LC, RC, isExact), Name);
- if (!isExact)
- return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
- return Insert(BinaryOperator::CreateExactLShr(LHS, RHS), Name);
- }
- Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
- bool isExact = false) {
- return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
- }
- Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
- bool isExact = false) {
- return CreateLShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
- }
-
- Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "",
- bool isExact = false) {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateAShr(LC, RC, isExact), Name);
- if (!isExact)
- return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
- return Insert(BinaryOperator::CreateExactAShr(LHS, RHS), Name);
- }
- Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "",
- bool isExact = false) {
- return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
- }
- Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "",
- bool isExact = false) {
- return CreateAShr(LHS, ConstantInt::get(LHS->getType(), RHS), Name,isExact);
- }
-
- Value *CreateAnd(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *RC = dyn_cast<Constant>(RHS)) {
- if (isa<ConstantInt>(RC) && cast<ConstantInt>(RC)->isAllOnesValue())
- return LHS; // LHS & -1 -> LHS
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateAnd(LC, RC), Name);
- }
- return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
- }
- Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
- Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- return CreateAnd(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
-
- Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *RC = dyn_cast<Constant>(RHS)) {
- if (RC->isNullValue())
- return LHS; // LHS | 0 -> LHS
- if (Constant *LC = dyn_cast<Constant>(LHS))
- return Insert(Folder.CreateOr(LC, RC), Name);
- }
- return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
- }
- Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
- Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- return CreateOr(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
-
- Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateXor(LC, RC), Name);
- return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
- }
- Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
- return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
- Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
- return CreateXor(LHS, ConstantInt::get(LHS->getType(), RHS), Name);
- }
-
- Value *CreateBinOp(Instruction::BinaryOps Opc,
- Value *LHS, Value *RHS, const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateBinOp(Opc, LC, RC), Name);
- return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
- }
-
- Value *CreateNeg(Value *V, const Twine &Name = "",
- bool HasNUW = false, bool HasNSW = false) {
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateNeg(VC, HasNUW, HasNSW), Name);
- BinaryOperator *BO = Insert(BinaryOperator::CreateNeg(V), Name);
- if (HasNUW) BO->setHasNoUnsignedWrap();
- if (HasNSW) BO->setHasNoSignedWrap();
- return BO;
- }
- Value *CreateNSWNeg(Value *V, const Twine &Name = "") {
- return CreateNeg(V, Name, false, true);
- }
- Value *CreateNUWNeg(Value *V, const Twine &Name = "") {
- return CreateNeg(V, Name, true, false);
- }
- Value *CreateFNeg(Value *V, const Twine &Name = "", MDNode *FPMathTag = 0) {
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateFNeg(VC), Name);
- return Insert(AddFPMathTag(BinaryOperator::CreateFNeg(V), FPMathTag), Name);
- }
- Value *CreateNot(Value *V, const Twine &Name = "") {
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateNot(VC), Name);
- return Insert(BinaryOperator::CreateNot(V), Name);
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Memory Instructions
- //===--------------------------------------------------------------------===//
-
- AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0,
- const Twine &Name = "") {
- return Insert(new AllocaInst(Ty, ArraySize), Name);
- }
- // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
- // converting the string to 'bool' for the isVolatile parameter.
- LoadInst *CreateLoad(Value *Ptr, const char *Name) {
- return Insert(new LoadInst(Ptr), Name);
- }
- LoadInst *CreateLoad(Value *Ptr, const Twine &Name = "") {
- return Insert(new LoadInst(Ptr), Name);
- }
- LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const Twine &Name = "") {
- return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
- }
- StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
- return Insert(new StoreInst(Val, Ptr, isVolatile));
- }
- FenceInst *CreateFence(AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
- return Insert(new FenceInst(Context, Ordering, SynchScope));
- }
- AtomicCmpXchgInst *CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
- AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
- return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope));
- }
- AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
- AtomicOrdering Ordering,
- SynchronizationScope SynchScope = CrossThread) {
- return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope));
- }
- Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
- const Twine &Name = "") {
- if (Constant *PC = dyn_cast<Constant>(Ptr)) {
- // Every index must be constant.
- size_t i, e;
- for (i = 0, e = IdxList.size(); i != e; ++i)
- if (!isa<Constant>(IdxList[i]))
- break;
- if (i == e)
- return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
- }
- return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
- }
- Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
- const Twine &Name = "") {
- if (Constant *PC = dyn_cast<Constant>(Ptr)) {
- // Every index must be constant.
- size_t i, e;
- for (i = 0, e = IdxList.size(); i != e; ++i)
- if (!isa<Constant>(IdxList[i]))
- break;
- if (i == e)
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
- }
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
- }
- Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
- }
- Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
- }
- Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
- Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
-
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
- }
- Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
- const Twine &Name = "") {
- Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
-
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
- }
- Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
- Value *Idxs[] = {
- ConstantInt::get(Type::getInt32Ty(Context), Idx0),
- ConstantInt::get(Type::getInt32Ty(Context), Idx1)
- };
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
-
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
- }
- Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
- const Twine &Name = "") {
- Value *Idxs[] = {
- ConstantInt::get(Type::getInt32Ty(Context), Idx0),
- ConstantInt::get(Type::getInt32Ty(Context), Idx1)
- };
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
-
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
- }
- Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
- Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
-
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
- }
- Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
- const Twine &Name = "") {
- Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
-
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
- }
- Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
- const Twine &Name = "") {
- Value *Idxs[] = {
- ConstantInt::get(Type::getInt64Ty(Context), Idx0),
- ConstantInt::get(Type::getInt64Ty(Context), Idx1)
- };
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
-
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
- }
- Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
- const Twine &Name = "") {
- Value *Idxs[] = {
- ConstantInt::get(Type::getInt64Ty(Context), Idx0),
- ConstantInt::get(Type::getInt64Ty(Context), Idx1)
- };
-
- if (Constant *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
-
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
- }
- Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
- return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
- }
-
- /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer
- /// with "i8*" type instead of a pointer to array of i8.
- Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
- Value *gv = CreateGlobalString(Str, Name);
- Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
- Value *Args[] = { zero, zero };
- return CreateInBoundsGEP(gv, Args, Name);
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Cast/Conversion Operators
- //===--------------------------------------------------------------------===//
-
- Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") {
- return CreateCast(Instruction::Trunc, V, DestTy, Name);
- }
- Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") {
- return CreateCast(Instruction::ZExt, V, DestTy, Name);
- }
- Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
- return CreateCast(Instruction::SExt, V, DestTy, Name);
- }
- Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){
- return CreateCast(Instruction::FPToUI, V, DestTy, Name);
- }
- Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){
- return CreateCast(Instruction::FPToSI, V, DestTy, Name);
- }
- Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
- return CreateCast(Instruction::UIToFP, V, DestTy, Name);
- }
- Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){
- return CreateCast(Instruction::SIToFP, V, DestTy, Name);
- }
- Value *CreateFPTrunc(Value *V, Type *DestTy,
- const Twine &Name = "") {
- return CreateCast(Instruction::FPTrunc, V, DestTy, Name);
- }
- Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") {
- return CreateCast(Instruction::FPExt, V, DestTy, Name);
- }
- Value *CreatePtrToInt(Value *V, Type *DestTy,
- const Twine &Name = "") {
- return CreateCast(Instruction::PtrToInt, V, DestTy, Name);
- }
- Value *CreateIntToPtr(Value *V, Type *DestTy,
- const Twine &Name = "") {
- return CreateCast(Instruction::IntToPtr, V, DestTy, Name);
- }
- Value *CreateBitCast(Value *V, Type *DestTy,
- const Twine &Name = "") {
- return CreateCast(Instruction::BitCast, V, DestTy, Name);
- }
- Value *CreateZExtOrBitCast(Value *V, Type *DestTy,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name);
- return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name);
- }
- Value *CreateSExtOrBitCast(Value *V, Type *DestTy,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name);
- return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name);
- }
- Value *CreateTruncOrBitCast(Value *V, Type *DestTy,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name);
- return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name);
- }
- Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateCast(Op, VC, DestTy), Name);
- return Insert(CastInst::Create(Op, V, DestTy), Name);
- }
- Value *CreatePointerCast(Value *V, Type *DestTy,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreatePointerCast(VC, DestTy), Name);
- return Insert(CastInst::CreatePointerCast(V, DestTy), Name);
- }
- Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned,
- const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateIntCast(VC, DestTy, isSigned), Name);
- return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
- }
-private:
- // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time
- // error, instead of converting the string to bool for the isSigned parameter.
- Value *CreateIntCast(Value *, Type *, const char *); // DO NOT IMPLEMENT
-public:
- Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
- if (V->getType() == DestTy)
- return V;
- if (Constant *VC = dyn_cast<Constant>(V))
- return Insert(Folder.CreateFPCast(VC, DestTy), Name);
- return Insert(CastInst::CreateFPCast(V, DestTy), Name);
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Compare Instructions
- //===--------------------------------------------------------------------===//
-
- Value *CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
- }
- Value *CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_NE, LHS, RHS, Name);
- }
- Value *CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_UGT, LHS, RHS, Name);
- }
- Value *CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_UGE, LHS, RHS, Name);
- }
- Value *CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_ULT, LHS, RHS, Name);
- }
- Value *CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_ULE, LHS, RHS, Name);
- }
- Value *CreateICmpSGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_SGT, LHS, RHS, Name);
- }
- Value *CreateICmpSGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_SGE, LHS, RHS, Name);
- }
- Value *CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_SLT, LHS, RHS, Name);
- }
- Value *CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
- }
-
- Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
- }
- Value *CreateFCmpOGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OGT, LHS, RHS, Name);
- }
- Value *CreateFCmpOGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OGE, LHS, RHS, Name);
- }
- Value *CreateFCmpOLT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OLT, LHS, RHS, Name);
- }
- Value *CreateFCmpOLE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_OLE, LHS, RHS, Name);
- }
- Value *CreateFCmpONE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ONE, LHS, RHS, Name);
- }
- Value *CreateFCmpORD(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ORD, LHS, RHS, Name);
- }
- Value *CreateFCmpUNO(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UNO, LHS, RHS, Name);
- }
- Value *CreateFCmpUEQ(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UEQ, LHS, RHS, Name);
- }
- Value *CreateFCmpUGT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UGT, LHS, RHS, Name);
- }
- Value *CreateFCmpUGE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UGE, LHS, RHS, Name);
- }
- Value *CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ULT, LHS, RHS, Name);
- }
- Value *CreateFCmpULE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_ULE, LHS, RHS, Name);
- }
- Value *CreateFCmpUNE(Value *LHS, Value *RHS, const Twine &Name = "") {
- return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
- }
-
- Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateICmp(P, LC, RC), Name);
- return Insert(new ICmpInst(P, LHS, RHS), Name);
- }
- Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
- const Twine &Name = "") {
- if (Constant *LC = dyn_cast<Constant>(LHS))
- if (Constant *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFCmp(P, LC, RC), Name);
- return Insert(new FCmpInst(P, LHS, RHS), Name);
- }
-
- //===--------------------------------------------------------------------===//
- // Instruction creation methods: Other Instructions
- //===--------------------------------------------------------------------===//
-
- PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues,
- const Twine &Name = "") {
- return Insert(PHINode::Create(Ty, NumReservedValues), Name);
- }
-
- CallInst *CreateCall(Value *Callee, const Twine &Name = "") {
- return Insert(CallInst::Create(Callee), Name);
- }
- CallInst *CreateCall(Value *Callee, Value *Arg, const Twine &Name = "") {
- return Insert(CallInst::Create(Callee, Arg), Name);
- }
- CallInst *CreateCall2(Value *Callee, Value *Arg1, Value *Arg2,
- const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
- CallInst *CreateCall3(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
- CallInst *CreateCall4(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- Value *Arg4, const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
- CallInst *CreateCall5(Value *Callee, Value *Arg1, Value *Arg2, Value *Arg3,
- Value *Arg4, Value *Arg5, const Twine &Name = "") {
- Value *Args[] = { Arg1, Arg2, Arg3, Arg4, Arg5 };
- return Insert(CallInst::Create(Callee, Args), Name);
- }
-
- CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
- const Twine &Name = "") {
- return Insert(CallInst::Create(Callee, Args), Name);
- }
-
- Value *CreateSelect(Value *C, Value *True, Value *False,
- const Twine &Name = "") {
- if (Constant *CC = dyn_cast<Constant>(C))
- if (Constant *TC = dyn_cast<Constant>(True))
- if (Constant *FC = dyn_cast<Constant>(False))
- return Insert(Folder.CreateSelect(CC, TC, FC), Name);
- return Insert(SelectInst::Create(C, True, False), Name);
- }
-
- VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
- return Insert(new VAArgInst(List, Ty), Name);
- }
-
- Value *CreateExtractElement(Value *Vec, Value *Idx,
- const Twine &Name = "") {
- if (Constant *VC = dyn_cast<Constant>(Vec))
- if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateExtractElement(VC, IC), Name);
- return Insert(ExtractElementInst::Create(Vec, Idx), Name);
- }
-
- Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
- const Twine &Name = "") {
- if (Constant *VC = dyn_cast<Constant>(Vec))
- if (Constant *NC = dyn_cast<Constant>(NewElt))
- if (Constant *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateInsertElement(VC, NC, IC), Name);
- return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
- }
-
- Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
- const Twine &Name = "") {
- if (Constant *V1C = dyn_cast<Constant>(V1))
- if (Constant *V2C = dyn_cast<Constant>(V2))
- if (Constant *MC = dyn_cast<Constant>(Mask))
- return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
- return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
- }
-
- Value *CreateExtractValue(Value *Agg,
- ArrayRef<unsigned> Idxs,
- const Twine &Name = "") {
- if (Constant *AggC = dyn_cast<Constant>(Agg))
- return Insert(Folder.CreateExtractValue(AggC, Idxs), Name);
- return Insert(ExtractValueInst::Create(Agg, Idxs), Name);
- }
-
- Value *CreateInsertValue(Value *Agg, Value *Val,
- ArrayRef<unsigned> Idxs,
- const Twine &Name = "") {
- if (Constant *AggC = dyn_cast<Constant>(Agg))
- if (Constant *ValC = dyn_cast<Constant>(Val))
- return Insert(Folder.CreateInsertValue(AggC, ValC, Idxs), Name);
- return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name);
- }
-
- LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses,
- const Twine &Name = "") {
- return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name));
- }
-
- //===--------------------------------------------------------------------===//
- // Utility creation methods
- //===--------------------------------------------------------------------===//
-
- /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
- Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
- return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
- Name);
- }
-
- /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null.
- Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
- return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
- Name);
- }
-
- /// CreatePtrDiff - Return the i64 difference between two pointer values,
- /// dividing out the size of the pointed-to objects. This is intended to
- /// implement C-style pointer subtraction. As such, the pointers must be
- /// appropriately aligned for their element types and pointing into the
- /// same object.
- Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
- assert(LHS->getType() == RHS->getType() &&
- "Pointer subtraction operand types must match!");
- PointerType *ArgType = cast<PointerType>(LHS->getType());
- Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
- Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
- Value *Difference = CreateSub(LHS_int, RHS_int);
- return CreateExactSDiv(Difference,
- ConstantExpr::getSizeOf(ArgType->getElementType()),
- Name);
- }
-};
-
-}
-
-#endif
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 52de8f6..109b3cf 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -13,6 +13,8 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
@@ -145,14 +147,17 @@ public:
// visitMul to proxy to visitBinaryOperator for instance in case the user does
// not need this generality.
//
- // The one problem case we have to handle here though is that the PHINode
- // class and opcode name are the exact same. Because of this, we cannot
- // define visitPHINode (the inst version) to forward to visitPHINode (the
- // generic version) without multiply defined symbols and recursion. To handle
- // this, we do not autoexpand "Other" instructions, we do it manually.
- //
+ // These functions can also implement fan-out, when a single opcode and
+ // instruction have multiple more specific Instruction subclasses. The Call
+ // instruction currently supports this. We implement that by redirecting that
+ // instruction to a special delegation helper.
#define HANDLE_INST(NUM, OPCODE, CLASS) \
- RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+ RetTy visit##OPCODE(CLASS &I) { \
+ if (NUM == Instruction::Call) \
+ return delegateCallInst(I); \
+ else \
+ DELEGATE(CLASS); \
+ }
#include "llvm/Instruction.def"
// Specific Instruction type classes... note that all of the casts are
@@ -195,6 +200,17 @@ public:
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+ // Handle the special instrinsic instruction classes.
+ RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
+
// Call and Invoke are slightly different as they delegate first through
// a generic CallSite visitor.
RetTy visitCallInst(CallInst &I) {
@@ -234,6 +250,29 @@ public:
// Note that you MUST override this function if your return type is not void.
//
void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+
+private:
+ // Special helper function to delegate to CallInst subclass visitors.
+ RetTy delegateCallInst(CallInst &I) {
+ if (const Function *F = I.getCalledFunction()) {
+ switch ((Intrinsic::ID)F->getIntrinsicID()) {
+ default: DELEGATE(IntrinsicInst);
+ case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
+ case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
+ case Intrinsic::memcpy: DELEGATE(MemCpyInst);
+ case Intrinsic::memmove: DELEGATE(MemMoveInst);
+ case Intrinsic::memset: DELEGATE(MemSetInst);
+ case Intrinsic::not_intrinsic: break;
+ }
+ }
+ DELEGATE(CallInst);
+ }
+
+ // An overload that will never actually be called, it is used only from dead
+ // code in the dispatching from opcodes to instruction subclasses.
+ RetTy delegateCallInst(Instruction &I) {
+ llvm_unreachable("delegateCallInst called for non-CallInst");
+ }
};
#undef DELEGATE
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
new file mode 100644
index 0000000..bb9e769
--- /dev/null
+++ b/include/llvm/Support/IntegersSubset.h
@@ -0,0 +1,541 @@
+//===-- llvm/IntegersSubset.h - The subset of integers ----------*- 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 contains class that implements constant set of ranges:
+/// [<Low0,High0>,...,<LowN,HighN>]. Initially, this class was created for
+/// SwitchInst and was used for case value representation that may contain
+/// multiple ranges for a single successor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CONSTANTRANGESSET_H_
+#define CONSTANTRANGESSET_H_
+
+#include <list>
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
+
+namespace llvm {
+
+ // The IntItem is a wrapper for APInt.
+ // 1. It determines sign of integer, it allows to use
+ // comparison operators >,<,>=,<=, and as result we got shorter and cleaner
+ // constructions.
+ // 2. It helps to implement PR1255 (case ranges) as a series of small patches.
+ // 3. Currently we can interpret IntItem both as ConstantInt and as APInt.
+ // It allows to provide SwitchInst methods that works with ConstantInt for
+ // non-updated passes. And it allows to use APInt interface for new methods.
+ // 4. IntItem can be easily replaced with APInt.
+
+ // The set of macros that allows to propagate APInt operators to the IntItem.
+
+#define INT_ITEM_DEFINE_COMPARISON(op,func) \
+ bool operator op (const APInt& RHS) const { \
+ return getAPIntValue().func(RHS); \
+ }
+
+#define INT_ITEM_DEFINE_UNARY_OP(op) \
+ IntItem operator op () const { \
+ APInt res = op(getAPIntValue()); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ return IntItem(cast<ConstantInt>(NewVal)); \
+ }
+
+#define INT_ITEM_DEFINE_BINARY_OP(op) \
+ IntItem operator op (const APInt& RHS) const { \
+ APInt res = getAPIntValue() op RHS; \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ return IntItem(cast<ConstantInt>(NewVal)); \
+ }
+
+#define INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(op) \
+ IntItem& operator op (const APInt& RHS) {\
+ APInt res = getAPIntValue();\
+ res op RHS; \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return *this; \
+ }
+
+#define INT_ITEM_DEFINE_PREINCDEC(op) \
+ IntItem& operator op () { \
+ APInt res = getAPIntValue(); \
+ op(res); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return *this; \
+ }
+
+#define INT_ITEM_DEFINE_POSTINCDEC(op) \
+ IntItem& operator op (int) { \
+ APInt res = getAPIntValue();\
+ op(res); \
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res); \
+ OldConstantIntVal = ConstantIntVal; \
+ ConstantIntVal = cast<ConstantInt>(NewVal); \
+ return IntItem(OldConstantIntVal); \
+ }
+
+#define INT_ITEM_DEFINE_OP_STANDARD_INT(RetTy, op, IntTy) \
+ RetTy operator op (IntTy RHS) const { \
+ return (*this) op APInt(getAPIntValue().getBitWidth(), RHS); \
+ }
+
+class IntItem {
+ ConstantInt *ConstantIntVal;
+ const APInt* APIntVal;
+ IntItem(const ConstantInt *V) :
+ ConstantIntVal(const_cast<ConstantInt*>(V)),
+ APIntVal(&ConstantIntVal->getValue()){}
+ const APInt& getAPIntValue() const {
+ return *APIntVal;
+ }
+public:
+
+ IntItem() {}
+
+ operator const APInt&() const {
+ return getAPIntValue();
+ }
+
+ // Propagate APInt operators.
+ // Note, that
+ // /,/=,>>,>>= are not implemented in APInt.
+ // <<= is implemented for unsigned RHS, but not implemented for APInt RHS.
+
+ INT_ITEM_DEFINE_COMPARISON(<, ult)
+ INT_ITEM_DEFINE_COMPARISON(>, ugt)
+ INT_ITEM_DEFINE_COMPARISON(<=, ule)
+ INT_ITEM_DEFINE_COMPARISON(>=, uge)
+
+ INT_ITEM_DEFINE_COMPARISON(==, eq)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(bool,==,uint64_t)
+
+ INT_ITEM_DEFINE_COMPARISON(!=, ne)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(bool,!=,uint64_t)
+
+ INT_ITEM_DEFINE_BINARY_OP(*)
+ INT_ITEM_DEFINE_BINARY_OP(+)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,+,uint64_t)
+ INT_ITEM_DEFINE_BINARY_OP(-)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,-,uint64_t)
+ INT_ITEM_DEFINE_BINARY_OP(<<)
+ INT_ITEM_DEFINE_OP_STANDARD_INT(IntItem,<<,unsigned)
+ INT_ITEM_DEFINE_BINARY_OP(&)
+ INT_ITEM_DEFINE_BINARY_OP(^)
+ INT_ITEM_DEFINE_BINARY_OP(|)
+
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(*=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(+=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(-=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(&=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(^=)
+ INT_ITEM_DEFINE_ASSIGNMENT_BY_OP(|=)
+
+ // Special case for <<=
+ IntItem& operator <<= (unsigned RHS) {
+ APInt res = getAPIntValue();
+ res <<= RHS;
+ Constant *NewVal = ConstantInt::get(ConstantIntVal->getContext(), res);
+ ConstantIntVal = cast<ConstantInt>(NewVal);
+ return *this;
+ }
+
+ INT_ITEM_DEFINE_UNARY_OP(-)
+ INT_ITEM_DEFINE_UNARY_OP(~)
+
+ INT_ITEM_DEFINE_PREINCDEC(++)
+ INT_ITEM_DEFINE_PREINCDEC(--)
+
+ // The set of workarounds, since currently we use ConstantInt implemented
+ // integer.
+
+ static IntItem fromConstantInt(const ConstantInt *V) {
+ return IntItem(V);
+ }
+ static IntItem fromType(Type* Ty, const APInt& V) {
+ ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
+ return fromConstantInt(C);
+ }
+ static IntItem withImplLikeThis(const IntItem& LikeThis, const APInt& V) {
+ ConstantInt *C = cast<ConstantInt>(ConstantInt::get(
+ LikeThis.ConstantIntVal->getContext(), V));
+ return fromConstantInt(C);
+ }
+ ConstantInt *toConstantInt() const {
+ return ConstantIntVal;
+ }
+};
+
+template<class IntType>
+class IntRange {
+protected:
+ IntType Low;
+ IntType High;
+ bool IsEmpty : 1;
+ bool IsSingleNumber : 1;
+
+public:
+ typedef IntRange<IntType> self;
+ typedef std::pair<self, self> SubRes;
+
+ IntRange() : IsEmpty(true) {}
+ IntRange(const self &RHS) :
+ Low(RHS.Low), High(RHS.High),
+ IsEmpty(RHS.IsEmpty), IsSingleNumber(RHS.IsSingleNumber) {}
+ IntRange(const IntType &C) :
+ Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
+
+ IntRange(const IntType &L, const IntType &H) : Low(L), High(H),
+ IsEmpty(false), IsSingleNumber(Low == High) {}
+
+ bool isEmpty() const { return IsEmpty; }
+ bool isSingleNumber() const { return IsSingleNumber; }
+
+ const IntType& getLow() const {
+ assert(!IsEmpty && "Range is empty.");
+ return Low;
+ }
+ const IntType& getHigh() const {
+ assert(!IsEmpty && "Range is empty.");
+ return High;
+ }
+
+ bool operator<(const self &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ if (Low == RHS.Low) {
+ if (High > RHS.High)
+ return true;
+ return false;
+ }
+ if (Low < RHS.Low)
+ return true;
+ return false;
+ }
+
+ bool operator==(const self &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ return Low == RHS.Low && High == RHS.High;
+ }
+
+ bool operator!=(const self &RHS) const {
+ return !operator ==(RHS);
+ }
+
+ static bool LessBySize(const self &LHS, const self &RHS) {
+ return (LHS.High - LHS.Low) < (RHS.High - RHS.Low);
+ }
+
+ bool isInRange(const IntType &IntVal) const {
+ assert(!IsEmpty && "Range is empty.");
+ return IntVal >= Low && IntVal <= High;
+ }
+
+ SubRes sub(const self &RHS) const {
+ SubRes Res;
+
+ // RHS is either more global and includes this range or
+ // if it doesn't intersected with this range.
+ if (!isInRange(RHS.Low) && !isInRange(RHS.High)) {
+
+ // If RHS more global (it is enough to check
+ // only one border in this case.
+ if (RHS.isInRange(Low))
+ return std::make_pair(self(Low, High), self());
+
+ return Res;
+ }
+
+ if (Low < RHS.Low) {
+ Res.first.Low = Low;
+ IntType NewHigh = RHS.Low;
+ --NewHigh;
+ Res.first.High = NewHigh;
+ }
+ if (High > RHS.High) {
+ IntType NewLow = RHS.High;
+ ++NewLow;
+ Res.second.Low = NewLow;
+ Res.second.High = High;
+ }
+ return Res;
+ }
+ };
+
+//===----------------------------------------------------------------------===//
+/// IntegersSubsetGeneric - class that implements the subset of integers. It
+/// consists from ranges and single numbers.
+template <class IntTy>
+class IntegersSubsetGeneric {
+public:
+ // Use Chris Lattner idea, that was initially described here:
+ // http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120213/136954.html
+ // In short, for more compact memory consumption we can store flat
+ // numbers collection, and define range as pair of indices.
+ // In that case we can safe some memory on 32 bit machines.
+ typedef std::vector<IntTy> FlatCollectionTy;
+ typedef std::pair<IntTy*, IntTy*> RangeLinkTy;
+ typedef std::vector<RangeLinkTy> RangeLinksTy;
+ typedef typename RangeLinksTy::const_iterator RangeLinksConstIt;
+
+ typedef IntegersSubsetGeneric<IntTy> self;
+
+protected:
+
+ FlatCollectionTy FlatCollection;
+ RangeLinksTy RangeLinks;
+
+ bool IsSingleNumber;
+ bool IsSingleNumbersOnly;
+
+public:
+
+ template<class RangesCollectionTy>
+ explicit IntegersSubsetGeneric(const RangesCollectionTy& Links) {
+ assert(Links.size() && "Empty ranges are not allowed.");
+
+ // In case of big set of single numbers consumes additional RAM space,
+ // but allows to avoid additional reallocation.
+ FlatCollection.reserve(Links.size() * 2);
+ RangeLinks.reserve(Links.size());
+ IsSingleNumbersOnly = true;
+ for (typename RangesCollectionTy::const_iterator i = Links.begin(),
+ e = Links.end(); i != e; ++i) {
+ RangeLinkTy RangeLink;
+ FlatCollection.push_back(i->getLow());
+ RangeLink.first = &FlatCollection.back();
+ if (i->getLow() != i->getHigh()) {
+ FlatCollection.push_back(i->getHigh());
+ IsSingleNumbersOnly = false;
+ }
+ RangeLink.second = &FlatCollection.back();
+ RangeLinks.push_back(RangeLink);
+ }
+ IsSingleNumber = IsSingleNumbersOnly && RangeLinks.size() == 1;
+ }
+
+ IntegersSubsetGeneric(const self& RHS) {
+ *this = RHS;
+ }
+
+ self& operator=(const self& RHS) {
+ FlatCollection.clear();
+ RangeLinks.clear();
+ FlatCollection.reserve(RHS.RangeLinks.size() * 2);
+ RangeLinks.reserve(RHS.RangeLinks.size());
+ for (RangeLinksConstIt i = RHS.RangeLinks.begin(), e = RHS.RangeLinks.end();
+ i != e; ++i) {
+ RangeLinkTy RangeLink;
+ FlatCollection.push_back(*(i->first));
+ RangeLink.first = &FlatCollection.back();
+ if (i->first != i->second)
+ FlatCollection.push_back(*(i->second));
+ RangeLink.second = &FlatCollection.back();
+ RangeLinks.push_back(RangeLink);
+ }
+ IsSingleNumber = RHS.IsSingleNumber;
+ IsSingleNumbersOnly = RHS.IsSingleNumbersOnly;
+ return *this;
+ }
+
+ typedef IntRange<IntTy> Range;
+
+ /// Checks is the given constant satisfies this case. Returns
+ /// true if it equals to one of contained values or belongs to the one of
+ /// contained ranges.
+ bool isSatisfies(const IntTy &CheckingVal) const {
+ if (IsSingleNumber)
+ return FlatCollection.front() == CheckingVal;
+ if (IsSingleNumbersOnly)
+ return std::find(FlatCollection.begin(),
+ FlatCollection.end(),
+ CheckingVal) != FlatCollection.end();
+
+ for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
+ if (RangeLinks[i].first == RangeLinks[i].second) {
+ if (*RangeLinks[i].first == CheckingVal)
+ return true;
+ } else if (*RangeLinks[i].first <= CheckingVal &&
+ *RangeLinks[i].second >= CheckingVal)
+ return true;
+ }
+ return false;
+ }
+
+ /// Returns set's item with given index.
+ Range getItem(unsigned idx) const {
+ const RangeLinkTy &Link = RangeLinks[idx];
+ if (Link.first != Link.second)
+ return Range(*Link.first, *Link.second);
+ else
+ return Range(*Link.first);
+ }
+
+ /// Return number of items (ranges) stored in set.
+ unsigned getNumItems() const {
+ return RangeLinks.size();
+ }
+
+ /// Returns true if whole subset contains single element.
+ bool isSingleNumber() const {
+ return IsSingleNumber;
+ }
+
+ /// Returns true if whole subset contains only single numbers, no ranges.
+ bool isSingleNumbersOnly() const {
+ return IsSingleNumbersOnly;
+ }
+
+ /// Does the same like getItem(idx).isSingleNumber(), but
+ /// works faster, since we avoid creation of temporary range object.
+ bool isSingleNumber(unsigned idx) const {
+ return RangeLinks[idx].first == RangeLinks[idx].second;
+ }
+
+ /// Returns set the size, that equals number of all values + sizes of all
+ /// ranges.
+ /// Ranges set is considered as flat numbers collection.
+ /// E.g.: for range [<0>, <1>, <4,8>] the size will 7;
+ /// for range [<0>, <1>, <5>] the size will 3
+ unsigned getSize() const {
+ APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
+ for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
+ const APInt &Low = getItem(i).getLow();
+ const APInt &High = getItem(i).getHigh();
+ APInt S = High - Low + 1;
+ sz += S;
+ }
+ return sz.getZExtValue();
+ }
+
+ /// Allows to access single value even if it belongs to some range.
+ /// Ranges set is considered as flat numbers collection.
+ /// [<1>, <4,8>] is considered as [1,4,5,6,7,8]
+ /// For range [<1>, <4,8>] getSingleValue(3) returns 6.
+ APInt getSingleValue(unsigned idx) const {
+ APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0);
+ for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
+ const APInt &Low = getItem(i).getLow();
+ const APInt &High = getItem(i).getHigh();
+ APInt S = High - Low + 1;
+ APInt oldSz = sz;
+ sz += S;
+ if (sz.ugt(idx)) {
+ APInt Res = Low;
+ APInt Offset(oldSz.getBitWidth(), idx);
+ Offset -= oldSz;
+ Res += Offset;
+ return Res;
+ }
+ }
+ assert(0 && "Index exceeds high border.");
+ return sz;
+ }
+
+ /// Does the same as getSingleValue, but works only if subset contains
+ /// single numbers only.
+ const IntTy& getSingleNumber(unsigned idx) const {
+ assert(IsSingleNumbersOnly && "This method works properly if subset "
+ "contains single numbers only.");
+ return FlatCollection[idx];
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// IntegersSubset - currently is extension of IntegersSubsetGeneric
+/// that also supports conversion to/from Constant* object.
+class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
+
+ typedef IntegersSubsetGeneric<IntItem> ParentTy;
+
+ Constant *Holder;
+
+ static unsigned getNumItemsFromConstant(Constant *C) {
+ return cast<ArrayType>(C->getType())->getNumElements();
+ }
+
+ static Range getItemFromConstant(Constant *C, unsigned idx) {
+ const Constant *CV = C->getAggregateElement(idx);
+
+ unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
+ switch (NumEls) {
+ case 1:
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(cast<ConstantInt>(
+ cast<ConstantInt>(CV->getAggregateElement(0U)))));
+ case 2:
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(1))));
+ default:
+ assert(0 && "Only pairs and single numbers are allowed here.");
+ return Range();
+ }
+ }
+
+ std::vector<Range> rangesFromConstant(Constant *C) {
+ unsigned NumItems = getNumItemsFromConstant(C);
+ std::vector<Range> r;
+ r.reserve(NumItems);
+ for (unsigned i = 0, e = NumItems; i != e; ++i)
+ r.push_back(getItemFromConstant(C, i));
+ return r;
+ }
+
+public:
+
+ explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
+ Holder(C) {}
+
+ IntegersSubset(const IntegersSubset& RHS) :
+ ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
+ Holder(RHS.Holder) {}
+
+ template<class RangesCollectionTy>
+ explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
+ std::vector<Constant*> Elts;
+ Elts.reserve(Src.size());
+ for (typename RangesCollectionTy::const_iterator i = Src.begin(),
+ e = Src.end(); i != e; ++i) {
+ const Range &R = *i;
+ std::vector<Constant*> r;
+ if (R.isSingleNumber()) {
+ r.reserve(2);
+ // FIXME: Since currently we have ConstantInt based numbers
+ // use hack-conversion of IntItem to ConstantInt
+ r.push_back(R.getLow().toConstantInt());
+ r.push_back(R.getHigh().toConstantInt());
+ } else {
+ r.reserve(1);
+ r.push_back(R.getLow().toConstantInt());
+ }
+ Constant *CV = ConstantVector::get(r);
+ Elts.push_back(CV);
+ }
+ ArrayType *ArrTy =
+ ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
+ Holder = ConstantArray::get(ArrTy, Elts);
+ }
+
+ operator Constant*() { return Holder; }
+ operator const Constant*() const { return Holder; }
+ Constant *operator->() { return Holder; }
+ const Constant *operator->() const { return Holder; }
+};
+
+}
+
+#endif /* CONSTANTRANGESSET_H_ */
diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
new file mode 100644
index 0000000..cab18dc
--- /dev/null
+++ b/include/llvm/Support/IntegersSubsetMapping.h
@@ -0,0 +1,580 @@
+//===- IntegersSubsetMapping.h - Mapping subset ==> Successor ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file
+/// IntegersSubsetMapping is mapping from A to B, where
+/// Items in A is subsets of integers,
+/// Items in B some pointers (Successors).
+/// If user which to add another subset for successor that is already
+/// exists in mapping, IntegersSubsetMapping merges existing subset with
+/// added one.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CRSBUILDER_H_
+#define CRSBUILDER_H_
+
+#include "llvm/Support/IntegersSubset.h"
+#include <list>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+template <class SuccessorClass,
+ class IntegersSubsetTy = IntegersSubset,
+ class IntTy = IntItem>
+class IntegersSubsetMapping {
+ // FIXME: To much similar iterators typedefs, similar names.
+ // - Rename RangeIterator to the cluster iterator.
+ // - Remove unused "add" methods.
+ // - Class contents needs cleaning.
+public:
+
+ typedef IntRange<IntTy> RangeTy;
+
+ struct RangeEx : public RangeTy {
+ RangeEx() : Weight(1) {}
+ RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {}
+ RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {}
+ RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {}
+ RangeEx(const IntTy &L, const IntTy &H, unsigned W) :
+ RangeTy(L, H), Weight(W) {}
+ unsigned Weight;
+ };
+
+ typedef std::pair<RangeEx, SuccessorClass*> Cluster;
+
+ typedef std::list<RangeTy> RangesCollection;
+ typedef typename RangesCollection::iterator RangesCollectionIt;
+ typedef typename RangesCollection::const_iterator RangesCollectionConstIt;
+ typedef IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> self;
+
+protected:
+
+ typedef std::list<Cluster> CaseItems;
+ typedef typename CaseItems::iterator CaseItemIt;
+ typedef typename CaseItems::const_iterator CaseItemConstIt;
+
+ // TODO: Change unclean CRS prefixes to SubsetMap for example.
+ typedef std::map<SuccessorClass*, RangesCollection > CRSMap;
+ typedef typename CRSMap::iterator CRSMapIt;
+
+ struct ClustersCmp {
+ bool operator()(const Cluster &C1, const Cluster &C2) {
+ return C1.first < C2.first;
+ }
+ };
+
+ CaseItems Items;
+ bool Sorted;
+
+ bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
+ return LItem->first.getHigh() >= RItem->first.getLow();
+ }
+
+ bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
+ if (LItem->second != RItem->second) {
+ assert(!isIntersected(LItem, RItem) &&
+ "Intersected items with different successors!");
+ return false;
+ }
+ APInt RLow = RItem->first.getLow();
+ if (RLow != APInt::getNullValue(RLow.getBitWidth()))
+ --RLow;
+ return LItem->first.getHigh() >= RLow;
+ }
+
+ void sort() {
+ if (!Sorted) {
+ std::vector<Cluster> clustersVector;
+ clustersVector.reserve(Items.size());
+ clustersVector.insert(clustersVector.begin(), Items.begin(), Items.end());
+ std::sort(clustersVector.begin(), clustersVector.end(), ClustersCmp());
+ Items.clear();
+ Items.insert(Items.begin(), clustersVector.begin(), clustersVector.end());
+ Sorted = true;
+ }
+ }
+
+ enum DiffProcessState {
+ L_OPENED,
+ INTERSECT_OPENED,
+ R_OPENED,
+ ALL_IS_CLOSED
+ };
+
+ class DiffStateMachine {
+
+ DiffProcessState State;
+ IntTy OpenPt;
+ SuccessorClass *CurrentLSuccessor;
+ SuccessorClass *CurrentRSuccessor;
+
+ self *LeftMapping;
+ self *IntersectionMapping;
+ self *RightMapping;
+
+ public:
+
+ typedef
+ IntegersSubsetMapping<SuccessorClass, IntegersSubsetTy, IntTy> MappingTy;
+
+ DiffStateMachine(MappingTy *L,
+ MappingTy *Intersection,
+ MappingTy *R) :
+ State(ALL_IS_CLOSED),
+ LeftMapping(L),
+ IntersectionMapping(Intersection),
+ RightMapping(R)
+ {}
+
+ void onLOpen(const IntTy &Pt, SuccessorClass *S) {
+ switch (State) {
+ case R_OPENED:
+ if (Pt > OpenPt/*Don't add empty ranges.*/ && RightMapping)
+ RightMapping->add(OpenPt, Pt-1, CurrentRSuccessor);
+ State = INTERSECT_OPENED;
+ break;
+ case ALL_IS_CLOSED:
+ State = L_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentLSuccessor = S;
+ OpenPt = Pt;
+ }
+
+ void onLClose(const IntTy &Pt) {
+ switch (State) {
+ case L_OPENED:
+ assert(Pt >= OpenPt &&
+ "Subset is not sorted or contains overlapped ranges");
+ if (LeftMapping)
+ LeftMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ OpenPt = Pt + 1;
+ State = R_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ void onROpen(const IntTy &Pt, SuccessorClass *S) {
+ switch (State) {
+ case L_OPENED:
+ if (Pt > OpenPt && LeftMapping)
+ LeftMapping->add(OpenPt, Pt-1, CurrentLSuccessor);
+ State = INTERSECT_OPENED;
+ break;
+ case ALL_IS_CLOSED:
+ State = R_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentRSuccessor = S;
+ OpenPt = Pt;
+ }
+
+ void onRClose(const IntTy &Pt) {
+ switch (State) {
+ case R_OPENED:
+ assert(Pt >= OpenPt &&
+ "Subset is not sorted or contains overlapped ranges");
+ if (RightMapping)
+ RightMapping->add(OpenPt, Pt, CurrentRSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ OpenPt = Pt + 1;
+ State = L_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ void onLROpen(const IntTy &Pt,
+ SuccessorClass *LS,
+ SuccessorClass *RS) {
+ switch (State) {
+ case ALL_IS_CLOSED:
+ State = INTERSECT_OPENED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ CurrentLSuccessor = LS;
+ CurrentRSuccessor = RS;
+ OpenPt = Pt;
+ }
+
+ void onLRClose(const IntTy &Pt) {
+ switch (State) {
+ case INTERSECT_OPENED:
+ if (IntersectionMapping)
+ IntersectionMapping->add(OpenPt, Pt, CurrentLSuccessor);
+ State = ALL_IS_CLOSED;
+ break;
+ default:
+ assert(0 && "Got unexpected point.");
+ break;
+ }
+ }
+
+ bool isLOpened() { return State == L_OPENED; }
+ bool isROpened() { return State == R_OPENED; }
+ };
+
+public:
+
+ // Don't public CaseItems itself. Don't allow edit the Items directly.
+ // Just present the user way to iterate over the internal collection
+ // sharing iterator, begin() and end(). Editing should be controlled by
+ // factory.
+ typedef CaseItemIt RangeIterator;
+
+ typedef std::pair<SuccessorClass*, IntegersSubsetTy> Case;
+ typedef std::list<Case> Cases;
+ typedef typename Cases::iterator CasesIt;
+
+ IntegersSubsetMapping() {
+ Sorted = false;
+ }
+
+ bool verify() {
+ RangeIterator DummyErrItem;
+ return verify(DummyErrItem);
+ }
+
+ bool verify(RangeIterator& errItem) {
+ if (Items.empty())
+ return true;
+ sort();
+ for (CaseItemIt j = Items.begin(), i = j++, e = Items.end();
+ j != e; i = j++) {
+ if (isIntersected(i, j) && i->second != j->second) {
+ errItem = j;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool isOverlapped(self &RHS) {
+ if (Items.empty() || RHS.empty())
+ return true;
+
+ for (CaseItemIt L = Items.begin(), R = RHS.Items.begin(),
+ el = Items.end(), er = RHS.Items.end(); L != el && R != er;) {
+
+ const RangeTy &LRange = L->first;
+ const RangeTy &RRange = R->first;
+
+ if (LRange.getLow() > RRange.getLow()) {
+ if (RRange.isSingleNumber() || LRange.getLow() > RRange.getHigh())
+ ++R;
+ else
+ return true;
+ } else if (LRange.getLow() < RRange.getLow()) {
+ if (LRange.isSingleNumber() || LRange.getHigh() < RRange.getLow())
+ ++L;
+ else
+ return true;
+ } else // iRange.getLow() == jRange.getLow()
+ return true;
+ }
+ return false;
+ }
+
+
+ void optimize() {
+ if (Items.size() < 2)
+ return;
+ sort();
+ CaseItems OldItems = Items;
+ Items.clear();
+ const IntTy *Low = &OldItems.begin()->first.getLow();
+ const IntTy *High = &OldItems.begin()->first.getHigh();
+ unsigned Weight = 1;
+ SuccessorClass *Successor = OldItems.begin()->second;
+ for (CaseItemIt j = OldItems.begin(), i = j++, e = OldItems.end();
+ j != e; i = j++) {
+ if (isJoinable(i, j)) {
+ const IntTy *CurHigh = &j->first.getHigh();
+ ++Weight;
+ if (*CurHigh > *High)
+ High = CurHigh;
+ } else {
+ RangeEx R(*Low, *High, Weight);
+ add(R, Successor);
+ Low = &j->first.getLow();
+ High = &j->first.getHigh();
+ Weight = 1;
+ Successor = j->second;
+ }
+ }
+ RangeEx R(*Low, *High, Weight);
+ add(R, Successor);
+ // We recollected the Items, but we kept it sorted.
+ Sorted = true;
+ }
+
+ /// Adds a constant value.
+ void add(const IntTy &C, SuccessorClass *S = 0) {
+ RangeTy R(C);
+ add(R, S);
+ }
+
+ /// Adds a range.
+ void add(const IntTy &Low, const IntTy &High, SuccessorClass *S = 0) {
+ RangeTy R(Low, High);
+ add(R, S);
+ }
+ void add(const RangeTy &R, SuccessorClass *S = 0) {
+ RangeEx REx = R;
+ add(REx, S);
+ }
+ void add(const RangeEx &R, SuccessorClass *S = 0) {
+ Items.push_back(std::make_pair(R, S));
+ Sorted = false;
+ }
+
+ /// Adds all ranges and values from given ranges set to the current
+ /// mapping.
+ void add(const IntegersSubsetTy &CRS, SuccessorClass *S = 0) {
+ for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
+ RangeTy R = CRS.getItem(i);
+ add(R, S);
+ }
+ }
+
+ void add(self& RHS) {
+ Items.insert(Items.end(), RHS.Items.begin(), RHS.Items.end());
+ }
+
+ void add(self& RHS, SuccessorClass *S) {
+ for (CaseItemIt i = RHS.Items.begin(), e = RHS.Items.end(); i != e; ++i)
+ add(i->first, S);
+ }
+
+ void add(const RangesCollection& RHS, SuccessorClass *S = 0) {
+ for (RangesCollectionConstIt i = RHS.begin(), e = RHS.end(); i != e; ++i)
+ add(*i, S);
+ }
+
+ /// Removes items from set.
+ void removeItem(RangeIterator i) { Items.erase(i); }
+
+ /// Moves whole case from current mapping to the NewMapping object.
+ void detachCase(self& NewMapping, SuccessorClass *Succ) {
+ for (CaseItemIt i = Items.begin(); i != Items.end();)
+ if (i->second == Succ) {
+ NewMapping.add(i->first, i->second);
+ Items.erase(i++);
+ } else
+ ++i;
+ }
+
+ /// Removes all clusters for given successor.
+ void removeCase(SuccessorClass *Succ) {
+ for (CaseItemIt i = Items.begin(); i != Items.end();)
+ if (i->second == Succ) {
+ Items.erase(i++);
+ } else
+ ++i;
+ }
+
+ /// Find successor that satisfies given value.
+ SuccessorClass *findSuccessor(const IntTy& Val) {
+ for (CaseItemIt i = Items.begin(); i != Items.end(); ++i) {
+ if (i->first.isInRange(Val))
+ return i->second;
+ }
+ return 0;
+ }
+
+ /// Calculates the difference between this mapping and RHS.
+ /// THIS without RHS is placed into LExclude,
+ /// RHS without THIS is placed into RExclude,
+ /// THIS intersect RHS is placed into Intersection.
+ void diff(self *LExclude, self *Intersection, self *RExclude,
+ const self& RHS) {
+
+ DiffStateMachine Machine(LExclude, Intersection, RExclude);
+
+ CaseItemConstIt L = Items.begin(), R = RHS.Items.begin();
+ while (L != Items.end() && R != RHS.Items.end()) {
+ const Cluster &LCluster = *L;
+ const RangeEx &LRange = LCluster.first;
+ const Cluster &RCluster = *R;
+ const RangeEx &RRange = RCluster.first;
+
+ if (LRange.getHigh() < RRange.getLow()) {
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ Machine.onLClose(LRange.getHigh());
+ ++L;
+ continue;
+ }
+
+ if (LRange.getLow() > RRange.getHigh()) {
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ Machine.onRClose(RRange.getHigh());
+ ++R;
+ continue;
+ }
+
+ if (LRange.getLow() < RRange.getLow()) {
+ // May be opened in previous iteration.
+ if (!Machine.isLOpened())
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ }
+ else if (RRange.getLow() < LRange.getLow()) {
+ if (!Machine.isROpened())
+ Machine.onROpen(RRange.getLow(), RCluster.second);
+ Machine.onLOpen(LRange.getLow(), LCluster.second);
+ }
+ else
+ Machine.onLROpen(LRange.getLow(), LCluster.second, RCluster.second);
+
+ if (LRange.getHigh() < RRange.getHigh()) {
+ Machine.onLClose(LRange.getHigh());
+ ++L;
+ while(L != Items.end() && L->first.getHigh() < RRange.getHigh()) {
+ Machine.onLOpen(L->first.getLow(), L->second);
+ Machine.onLClose(L->first.getHigh());
+ ++L;
+ }
+ }
+ else if (RRange.getHigh() < LRange.getHigh()) {
+ Machine.onRClose(RRange.getHigh());
+ ++R;
+ while(R != RHS.Items.end() && R->first.getHigh() < LRange.getHigh()) {
+ Machine.onROpen(R->first.getLow(), R->second);
+ Machine.onRClose(R->first.getHigh());
+ ++R;
+ }
+ }
+ else {
+ Machine.onLRClose(LRange.getHigh());
+ ++L;
+ ++R;
+ }
+ }
+
+ if (L != Items.end()) {
+ if (Machine.isLOpened()) {
+ Machine.onLClose(L->first.getHigh());
+ ++L;
+ }
+ if (LExclude)
+ while (L != Items.end()) {
+ LExclude->add(L->first, L->second);
+ ++L;
+ }
+ } else if (R != RHS.Items.end()) {
+ if (Machine.isROpened()) {
+ Machine.onRClose(R->first.getHigh());
+ ++R;
+ }
+ if (RExclude)
+ while (R != RHS.Items.end()) {
+ RExclude->add(R->first, R->second);
+ ++R;
+ }
+ }
+ }
+
+ /// Builds the finalized case objects.
+ void getCases(Cases& TheCases, bool PreventMerging = false) {
+ //FIXME: PreventMerging is a temporary parameter.
+ //Currently a set of passes is still knows nothing about
+ //switches with case ranges, and if these passes meet switch
+ //with complex case that crashs the application.
+ if (PreventMerging) {
+ for (RangeIterator i = this->begin(); i != this->end(); ++i) {
+ RangesCollection SingleRange;
+ SingleRange.push_back(i->first);
+ TheCases.push_back(std::make_pair(i->second,
+ IntegersSubsetTy(SingleRange)));
+ }
+ return;
+ }
+ CRSMap TheCRSMap;
+ for (RangeIterator i = this->begin(); i != this->end(); ++i)
+ TheCRSMap[i->second].push_back(i->first);
+ for (CRSMapIt i = TheCRSMap.begin(), e = TheCRSMap.end(); i != e; ++i)
+ TheCases.push_back(std::make_pair(i->first, IntegersSubsetTy(i->second)));
+ }
+
+ /// Builds the finalized case objects ignoring successor values, as though
+ /// all ranges belongs to the same successor.
+ IntegersSubsetTy getCase() {
+ RangesCollection Ranges;
+ for (RangeIterator i = this->begin(); i != this->end(); ++i)
+ Ranges.push_back(i->first);
+ return IntegersSubsetTy(Ranges);
+ }
+
+ /// Returns pointer to value of case if it is single-numbered or 0
+ /// in another case.
+ const IntTy* getCaseSingleNumber(SuccessorClass *Succ) {
+ const IntTy* Res = 0;
+ for (CaseItemIt i = Items.begin(); i != Items.end(); ++i)
+ if (i->second == Succ) {
+ if (!i->first.isSingleNumber())
+ return 0;
+ if (Res)
+ return 0;
+ else
+ Res = &(i->first.getLow());
+ }
+ return Res;
+ }
+
+ /// Returns true if there is no ranges and values inside.
+ bool empty() const { return Items.empty(); }
+
+ void clear() {
+ Items.clear();
+ // Don't reset Sorted flag:
+ // 1. For empty mapping it matters nothing.
+ // 2. After first item will added Sorted flag will cleared.
+ }
+
+ // Returns number of clusters
+ unsigned size() const {
+ return Items.size();
+ }
+
+ RangeIterator begin() { return Items.begin(); }
+ RangeIterator end() { return Items.end(); }
+};
+
+class BasicBlock;
+typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
+
+}
+
+#endif /* CRSBUILDER_H_ */
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
new file mode 100644
index 0000000..00c7eea
--- /dev/null
+++ b/include/llvm/Support/LEB128.h
@@ -0,0 +1,58 @@
+//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- 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 some utility functions for encoding SLEB128 and
+// ULEB128 values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_LEB128_H
+#define LLVM_SYSTEM_LEB128_H
+
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+
+/// Utility function to encode a SLEB128 value.
+static inline void encodeSLEB128(int64_t Value, raw_ostream &OS) {
+ bool More;
+ do {
+ uint8_t Byte = Value & 0x7f;
+ // NOTE: this assumes that this signed shift is an arithmetic right shift.
+ Value >>= 7;
+ More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
+ ((Value == -1) && ((Byte & 0x40) != 0))));
+ if (More)
+ Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ OS << char(Byte);
+ } while (More);
+}
+
+/// Utility function to encode a ULEB128 value.
+static inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
+ unsigned Padding = 0) {
+ do {
+ uint8_t Byte = Value & 0x7f;
+ Value >>= 7;
+ if (Value != 0 || Padding != 0)
+ Byte |= 0x80; // Mark this byte that that more bytes will follow.
+ OS << char(Byte);
+ } while (Value != 0);
+
+ // Pad with 0x80 and emit a null byte at the end.
+ if (Padding != 0) {
+ for (; Padding != 1; --Padding)
+ OS << '\x80';
+ OS << '\x00';
+ }
+}
+
+} // namespace llvm
+
+#endif // LLVM_SYSTEM_LEB128_H
diff --git a/include/llvm/Support/MDBuilder.h b/include/llvm/Support/MDBuilder.h
deleted file mode 100644
index 40f028a..0000000
--- a/include/llvm/Support/MDBuilder.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//===---- llvm/Support/MDBuilder.h - Builder for LLVM metadata --*- 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 MDBuilder class, which is used as a convenient way to
-// create LLVM metadata with a consistent and simplified interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_MDBUILDER_H
-#define LLVM_SUPPORT_MDBUILDER_H
-
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Metadata.h"
-#include "llvm/ADT/APInt.h"
-
-namespace llvm {
-
- class MDBuilder {
- LLVMContext &Context;
-
- public:
- MDBuilder(LLVMContext &context) : Context(context) {}
-
- /// \brief Return the given string as metadata.
- MDString *createString(StringRef Str) {
- return MDString::get(Context, Str);
- }
-
- //===------------------------------------------------------------------===//
- // FPMath metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata with the given settings. The special value 0.0
- /// for the Accuracy parameter indicates the default (maximal precision)
- /// setting.
- MDNode *createFPMath(float Accuracy) {
- if (Accuracy == 0.0)
- return 0;
- assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
- Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy);
- return MDNode::get(Context, Op);
- }
-
-
- //===------------------------------------------------------------------===//
- // Range metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata describing the range [Lo, Hi).
- MDNode *createRange(const APInt &Lo, const APInt &Hi) {
- assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
- // If the range is everything then it is useless.
- if (Hi == Lo)
- return 0;
-
- // Return the range [Lo, Hi).
- Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
- Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) };
- return MDNode::get(Context, Range);
- }
-
-
- //===------------------------------------------------------------------===//
- // TBAA metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata appropriate for a TBAA root node. Each returned
- /// node is distinct from all other metadata and will never be identified
- /// (uniqued) with anything else.
- MDNode *createAnonymousTBAARoot() {
- // To ensure uniqueness the root node is self-referential.
- MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
- MDNode *Root = MDNode::get(Context, Dummy);
- // At this point we have
- // !0 = metadata !{} <- dummy
- // !1 = metadata !{metadata !0} <- root
- // Replace the dummy operand with the root node itself and delete the dummy.
- Root->replaceOperandWith(0, Root);
- MDNode::deleteTemporary(Dummy);
- // We now have
- // !1 = metadata !{metadata !1} <- self-referential root
- return Root;
- }
-
- /// \brief Return metadata appropriate for a TBAA root node with the given
- /// name. This may be identified (uniqued) with other roots with the same
- /// name.
- MDNode *createTBAARoot(StringRef Name) {
- return MDNode::get(Context, createString(Name));
- }
-
- /// \brief Return metadata for a non-root TBAA node with the given name,
- /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
- MDNode *createTBAANode(StringRef Name, MDNode *Parent,
- bool isConstant = false) {
- if (isConstant) {
- Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
- Value *Ops[3] = { createString(Name), Parent, Flags };
- return MDNode::get(Context, Ops);
- } else {
- Value *Ops[2] = { createString(Name), Parent };
- return MDNode::get(Context, Ops);
- }
- }
-
- };
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index 44a7a79..7f28c3f 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -174,50 +174,50 @@ namespace llvm {
RebaseTypePointer = 1u, // REBASE_TYPE_POINTER
RebaseTypeTextAbsolute32 = 2u, // REBASE_TYPE_TEXT_ABSOLUTE32
- RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
+ RebaseTypeTextPCRelative32 = 3u, // REBASE_TYPE_TEXT_PCREL32
RebaseOpcodeMask = 0xF0u, // REBASE_OPCODE_MASK
RebaseImmediateMask = 0x0Fu, // REBASE_IMMEDIATE_MASK
RebaseOpcodeDone = 0x00u, // REBASE_OPCODE_DONE
RebaseOpcodeSetTypeImmediate = 0x10u, // REBASE_OPCODE_SET_TYPE_IMM
- RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
+ RebaseOpcodeSetSegmentAndOffsetULEB = 0x20u, // REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
RebaseOpcodeAddAddressULEB = 0x30u, // REBASE_OPCODE_ADD_ADDR_ULEB
- RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
- RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
+ RebaseOpcodeAddAddressImmediateScaled = 0x40u, // REBASE_OPCODE_ADD_ADDR_IMM_SCALED
+ RebaseOpcodeDoRebaseImmediateTimes = 0x50u, // REBASE_OPCODE_DO_REBASE_IMM_TIMES
RebaseOpcodeDoRebaseULEBTimes = 0x60u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES
RebaseOpcodeDoRebaseAddAddressULEB = 0x70u, // REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB
RebaseOpcodeDoRebaseULEBTimesSkippingULEB = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
BindTypePointer = 1u, // BIND_TYPE_POINTER
- BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
- BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
+ BindTypeTextAbsolute32 = 2u, // BIND_TYPE_TEXT_ABSOLUTE32
+ BindTypeTextPCRelative32 = 3u, // BIND_TYPE_TEXT_PCREL32
BindSpecialDylibSelf = 0u, // BIND_SPECIAL_DYLIB_SELF
BindSpecialDylibMainExecutable = -1u, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
BindSpecialDylibFlatLookup = -2u, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
BindSymbolFlagsWeakImport = 0x1u, // BIND_SYMBOL_FLAGS_WEAK_IMPORT
- BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
+ BindSymbolFlagsNonWeakDefinition = 0x8u, // BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION
BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
BindOpcodeDone = 0x00u, // BIND_OPCODE_DONE
BindOpcodeSetDylibOrdinalImmediate = 0x10u, // BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
BindOpcodeSetDylibOrdinalULEB = 0x20u, // BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB
- BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
- BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
- BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
+ BindOpcodeSetDylibSpecialImmediate = 0x30u, // BIND_OPCODE_SET_DYLIB_SPECIAL_IMM
+ BindOpcodeSetSymbolTrailingFlagsImmediate = 0x40u, // BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
+ BindOpcodeSetTypeImmediate = 0x50u, // BIND_OPCODE_SET_TYPE_IMM
BindOpcodeSetAppendSLEB = 0x60u, // BIND_OPCODE_SET_ADDEND_SLEB
BindOpcodeSetSegmentAndOffsetULEB = 0x70u, // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
BindOpcodeAddAddressULEB = 0x80u, // BIND_OPCODE_ADD_ADDR_ULEB
BindOpcodeDoBind = 0x90u, // BIND_OPCODE_DO_BIND
- BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
- BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
+ BindOpcodeDoBindAddAddressULEB = 0xA0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB
+ BindOpcodeDoBindAddAddressImmediateScaled = 0xB0u, // BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
BindOpcodeDoBindULEBTimesSkippingULEB = 0xC0u, // BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
ExportSymbolFlagsKindMask = 0x03u, // EXPORT_SYMBOL_FLAGS_KIND_MASK
- ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
+ ExportSymbolFlagsKindRegular = 0x00u, // EXPORT_SYMBOL_FLAGS_KIND_REGULAR
ExportSymbolFlagsKindThreadLocal = 0x01u, // EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
ExportSymbolFlagsWeakDefinition = 0x04u, // EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION
ExportSymbolFlagsIndirectDefinition = 0x08u, // EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION
@@ -227,7 +227,7 @@ namespace llvm {
// Constant masks for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64
NlistMaskStab = 0xe0, // N_STAB
- NlistMaskPrivateExternal = 0x10, // N_PEXT
+ NlistMaskPrivateExternal = 0x10, // N_PEXT
NlistMaskType = 0x0e, // N_TYPE
NlistMaskExternal = 0x01, // N_EXT
@@ -249,35 +249,35 @@ namespace llvm {
// Constant values for the "n_type" field in llvm::MachO::nlist and
// llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0"
- StabGlobalSymbol = 0x20u, // N_GSYM
- StabFunctionName = 0x22u, // N_FNAME
- StabFunction = 0x24u, // N_FUN
- StabStaticSymbol = 0x26u, // N_STSYM
- StabLocalCommon = 0x28u, // N_LCSYM
+ StabGlobalSymbol = 0x20u, // N_GSYM
+ StabFunctionName = 0x22u, // N_FNAME
+ StabFunction = 0x24u, // N_FUN
+ StabStaticSymbol = 0x26u, // N_STSYM
+ StabLocalCommon = 0x28u, // N_LCSYM
StabBeginSymbol = 0x2Eu, // N_BNSYM
- StabSourceFileOptions = 0x3Cu, // N_OPT
- StabRegisterSymbol = 0x40u, // N_RSYM
- StabSourceLine = 0x44u, // N_SLINE
+ StabSourceFileOptions = 0x3Cu, // N_OPT
+ StabRegisterSymbol = 0x40u, // N_RSYM
+ StabSourceLine = 0x44u, // N_SLINE
StabEndSymbol = 0x4Eu, // N_ENSYM
- StabStructureType = 0x60u, // N_SSYM
- StabSourceFileName = 0x64u, // N_SO
- StabObjectFileName = 0x66u, // N_OSO
- StabLocalSymbol = 0x80u, // N_LSYM
- StabBeginIncludeFileName = 0x82u, // N_BINCL
- StabIncludeFileName = 0x84u, // N_SOL
+ StabStructureType = 0x60u, // N_SSYM
+ StabSourceFileName = 0x64u, // N_SO
+ StabObjectFileName = 0x66u, // N_OSO
+ StabLocalSymbol = 0x80u, // N_LSYM
+ StabBeginIncludeFileName = 0x82u, // N_BINCL
+ StabIncludeFileName = 0x84u, // N_SOL
StabCompilerParameters = 0x86u, // N_PARAMS
StabCompilerVersion = 0x88u, // N_VERSION
StabCompilerOptLevel = 0x8Au, // N_OLEVEL
- StabParameter = 0xA0u, // N_PSYM
- StabEndIncludeFile = 0xA2u, // N_EINCL
- StabAlternateEntry = 0xA4u, // N_ENTRY
- StabLeftBracket = 0xC0u, // N_LBRAC
- StabDeletedIncludeFile = 0xC2u, // N_EXCL
- StabRightBracket = 0xE0u, // N_RBRAC
- StabBeginCommon = 0xE2u, // N_BCOMM
- StabEndCommon = 0xE4u, // N_ECOMM
- StabEndCommonLocal = 0xE8u, // N_ECOML
- StabLength = 0xFEu // N_LENG
+ StabParameter = 0xA0u, // N_PSYM
+ StabEndIncludeFile = 0xA2u, // N_EINCL
+ StabAlternateEntry = 0xA4u, // N_ENTRY
+ StabLeftBracket = 0xC0u, // N_LBRAC
+ StabDeletedIncludeFile = 0xC2u, // N_EXCL
+ StabRightBracket = 0xE0u, // N_RBRAC
+ StabBeginCommon = 0xE2u, // N_BCOMM
+ StabEndCommon = 0xE4u, // N_ECOMM
+ StabEndCommonLocal = 0xE8u, // N_ECOML
+ StabLength = 0xFEu // N_LENG
};
@@ -490,12 +490,12 @@ namespace llvm {
uint32_t nextrel;
uint32_t locreloff;
uint32_t nlocrel;
- };
+ };
struct dylib_table_of_contents {
uint32_t symbol_index;
uint32_t module_index;
- };
+ };
struct dylib_module {
uint32_t module_name;
@@ -511,7 +511,7 @@ namespace llvm {
uint32_t ninit_nterm;
uint32_t objc_module_info_addr;
uint32_t objc_module_info_size;
- };
+ };
struct dylib_module_64 {
uint32_t module_name;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index d085c94..4005161 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -414,14 +414,14 @@ int IsInf(double d);
/// MinAlign - A and B are either alignments or offsets. Return the minimum
/// alignment that may be assumed after adding the two together.
-static inline uint64_t MinAlign(uint64_t A, uint64_t B) {
+inline uint64_t MinAlign(uint64_t A, uint64_t B) {
// The largest power of 2 that divides both A and B.
return (A | B) & -(A | B);
}
/// NextPowerOf2 - Returns the next power of two (in 64-bits)
/// that is strictly greater than A. Returns zero on overflow.
-static inline uint64_t NextPowerOf2(uint64_t A) {
+inline uint64_t NextPowerOf2(uint64_t A) {
A |= (A >> 1);
A |= (A >> 2);
A |= (A >> 4);
diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h
index 6d38c95..8d79709 100644
--- a/include/llvm/Support/PathV2.h
+++ b/include/llvm/Support/PathV2.h
@@ -47,9 +47,9 @@ namespace path {
/// C:\foo\bar => C:,/,foo,bar
///
class const_iterator {
- StringRef Path; //< The entire path.
- StringRef Component; //< The current component. Not necessarily in Path.
- size_t Position; //< The iterators current position within Path.
+ StringRef Path; ///< The entire path.
+ StringRef Component; ///< The current component. Not necessarily in Path.
+ size_t Position; ///< The iterators current position within Path.
// An end iterator has Position = Path.size() + 1.
friend const_iterator begin(StringRef path);
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index d796b79..088897c 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -1,4 +1,4 @@
-//===- llvm/Support/Process.h ------------------------------------*- C++ -*-===//
+//===- llvm/Support/Process.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -97,6 +97,10 @@ namespace sys {
/// the user rather than being put on a pipe or stored in a file.
static bool FileDescriptorIsDisplayed(int fd);
+ /// This function determines if the given file descriptor is displayd and
+ /// supports colors.
+ static bool FileDescriptorHasColors(int fd);
+
/// This function determines the number of columns in the window
/// if standard output is connected to a "tty" or "console"
/// window. If standard output is not connected to a tty or
@@ -142,6 +146,10 @@ namespace sys {
/// Resets the terminals colors, or returns an escape sequence to do so.
static const char *ResetColor();
+
+ /// Get the result of a process wide random number generator. The
+ /// generator will be automatically seeded in non-deterministic fashion.
+ static unsigned GetRandomNumber();
/// @}
};
}
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index d48bfcc..1bf810b 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -24,7 +24,6 @@ class SMLoc {
const char *Ptr;
public:
SMLoc() : Ptr(0) {}
- SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {}
bool isValid() const { return Ptr != 0; }
@@ -48,7 +47,7 @@ public:
SMLoc Start, End;
SMRange() {}
- SMRange(SMLoc Start, SMLoc End) : Start(Start), End(End) {
+ SMRange(SMLoc St, SMLoc En) : Start(St), End(En) {
assert(Start.isValid() == End.isValid() &&
"Start and end should either both be valid or both be invalid!");
}
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index 76967db..8949a3a 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -123,7 +123,14 @@ public:
/// FindLineNumber - Find the line number for the specified location in the
/// specified file. This is not a fast method.
- unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const;
+ unsigned FindLineNumber(SMLoc Loc, int BufferID = -1) const {
+ return getLineAndColumn(Loc, BufferID).first;
+ }
+
+ /// getLineAndColumn - Find the line and column number for the specified
+ /// location in the specified file. This is not a fast method.
+ std::pair<unsigned, unsigned>
+ getLineAndColumn(SMLoc Loc, int BufferID = -1) const;
/// PrintMessage - Emit a message about the specified location with the
/// specified string.
@@ -169,9 +176,9 @@ public:
SMDiagnostic()
: SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
- SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Kind,
+ SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd,
const std::string &Msg)
- : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Kind),
+ : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
// Diagnostic with a location.
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 8808130..c0be8f1 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -108,6 +108,7 @@ namespace llvm {
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI);
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx);
typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T,
@@ -405,11 +406,12 @@ namespace llvm {
/// createMCCodeEmitter - Create a target specific code emitter.
MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx) const {
if (!MCCodeEmitterCtorFn)
return 0;
- return MCCodeEmitterCtorFn(II, STI, Ctx);
+ return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
}
/// createMCObjectStreamer - Create a target specific MCStreamer.
@@ -510,6 +512,21 @@ namespace llvm {
static const Target *lookupTarget(const std::string &Triple,
std::string &Error);
+ /// lookupTarget - Lookup a target based on an architecture name
+ /// and a target triple. If the architecture name is non-empty,
+ /// then the lookup is done by architecture. Otherwise, the target
+ /// triple is used.
+ ///
+ /// \param ArchName - The architecture to use for finding a target.
+ /// \param TheTriple - The triple to use for finding a target. The
+ /// triple is updated with canonical architecture name if a lookup
+ /// by architecture is done.
+ /// \param Error - On failure, an error string describing why no target was
+ /// found.
+ static const Target *lookupTarget(const std::string &ArchName,
+ Triple &TheTriple,
+ std::string &Error);
+
/// getClosestTargetForJIT - Pick the best target that is compatible with
/// the current host. If no close target can be found, this returns null
/// and sets the Error string to a reason.
@@ -1129,6 +1146,7 @@ namespace llvm {
private:
static MCCodeEmitter *Allocator(const MCInstrInfo &II,
+ const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new MCCodeEmitterImpl();
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index 15350a7..62ec90a 100644
--- a/include/llvm/Support/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -15,6 +15,7 @@
#define LLVM_SYSTEM_THREAD_LOCAL_H
#include "llvm/Support/Threading.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
@@ -22,7 +23,15 @@ namespace llvm {
// ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
// YOU SHOULD NEVER USE THIS DIRECTLY.
class ThreadLocalImpl {
- void* data;
+ typedef uint64_t ThreadLocalDataTy;
+ /// \brief Platform-specific thread local data.
+ ///
+ /// This is embedded in the class and we avoid malloc'ing/free'ing it,
+ /// to make this class more safe for use along with CrashRecoveryContext.
+ union {
+ char data[sizeof(ThreadLocalDataTy)];
+ ThreadLocalDataTy align_data;
+ };
public:
ThreadLocalImpl();
virtual ~ThreadLocalImpl();
diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h
deleted file mode 100644
index c756069..0000000
--- a/include/llvm/Support/TypeBuilder.h
+++ /dev/null
@@ -1,399 +0,0 @@
-//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- 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 TypeBuilder class, which is used as a convenient way to
-// create LLVM types with a consistent and simplified interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_TYPEBUILDER_H
-#define LLVM_SUPPORT_TYPEBUILDER_H
-
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include <limits.h>
-
-namespace llvm {
-
-/// TypeBuilder - This provides a uniform API for looking up types
-/// known at compile time. To support cross-compilation, we define a
-/// series of tag types in the llvm::types namespace, like i<N>,
-/// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be
-/// any of these, a native C type (whose size may depend on the host
-/// compiler), or a pointer, function, or struct type built out of
-/// these. TypeBuilder<T, true> removes native C types from this set
-/// to guarantee that its result is suitable for cross-compilation.
-/// We define the primitive types, pointer types, and functions up to
-/// 5 arguments here, but to use this class with your own types,
-/// you'll need to specialize it. For example, say you want to call a
-/// function defined externally as:
-///
-/// struct MyType {
-/// int32 a;
-/// int32 *b;
-/// void *array[1]; // Intended as a flexible array.
-/// };
-/// int8 AFunction(struct MyType *value);
-///
-/// You'll want to use
-/// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
-/// to declare the function, but when you first try this, your compiler will
-/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
-/// write:
-///
-/// namespace llvm {
-/// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
-/// public:
-/// static StructType *get(LLVMContext &Context) {
-/// // If you cache this result, be sure to cache it separately
-/// // for each LLVMContext.
-/// return StructType::get(
-/// TypeBuilder<types::i<32>, xcompile>::get(Context),
-/// TypeBuilder<types::i<32>*, xcompile>::get(Context),
-/// TypeBuilder<types::i<8>*[], xcompile>::get(Context),
-/// NULL);
-/// }
-///
-/// // You may find this a convenient place to put some constants
-/// // to help with getelementptr. They don't have any effect on
-/// // the operation of TypeBuilder.
-/// enum Fields {
-/// FIELD_A,
-/// FIELD_B,
-/// FIELD_ARRAY
-/// };
-/// }
-/// } // namespace llvm
-///
-/// TypeBuilder cannot handle recursive types or types you only know at runtime.
-/// If you try to give it a recursive type, it will deadlock, infinitely
-/// recurse, or do something similarly undesirable.
-template<typename T, bool cross_compilable> class TypeBuilder {};
-
-// Types for use with cross-compilable TypeBuilders. These correspond
-// exactly with an LLVM-native type.
-namespace types {
-/// i<N> corresponds to the LLVM IntegerType with N bits.
-template<uint32_t num_bits> class i {};
-
-// The following classes represent the LLVM floating types.
-class ieee_float {};
-class ieee_double {};
-class x86_fp80 {};
-class fp128 {};
-class ppc_fp128 {};
-// X86 MMX.
-class x86_mmx {};
-} // namespace types
-
-// LLVM doesn't have const or volatile types.
-template<typename T, bool cross> class TypeBuilder<const T, cross>
- : public TypeBuilder<T, cross> {};
-template<typename T, bool cross> class TypeBuilder<volatile T, cross>
- : public TypeBuilder<T, cross> {};
-template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
- : public TypeBuilder<T, cross> {};
-
-// Pointers
-template<typename T, bool cross> class TypeBuilder<T*, cross> {
-public:
- static PointerType *get(LLVMContext &Context) {
- return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
- }
-};
-
-/// There is no support for references
-template<typename T, bool cross> class TypeBuilder<T&, cross> {};
-
-// Arrays
-template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
-public:
- static ArrayType *get(LLVMContext &Context) {
- return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
- }
-};
-/// LLVM uses an array of length 0 to represent an unknown-length array.
-template<typename T, bool cross> class TypeBuilder<T[], cross> {
-public:
- static ArrayType *get(LLVMContext &Context) {
- return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
- }
-};
-
-// Define the C integral types only for TypeBuilder<T, false>.
-//
-// C integral types do not have a defined size. It would be nice to use the
-// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
-// following problem:
-//
-// On an ILP32 machine, stdint.h might define:
-//
-// typedef int int32_t;
-// typedef long long int64_t;
-// typedef long size_t;
-//
-// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
-// TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in
-// addition to the defined-size types because we'd get duplicate definitions on
-// platforms where stdint.h instead defines:
-//
-// typedef int int32_t;
-// typedef long long int64_t;
-// typedef int size_t;
-//
-// So we define all the primitive C types and nothing else.
-#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
-template<> class TypeBuilder<T, false> { \
-public: \
- static IntegerType *get(LLVMContext &Context) { \
- return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
- } \
-}; \
-template<> class TypeBuilder<T, true> { \
- /* We provide a definition here so users don't accidentally */ \
- /* define these types to work. */ \
-}
-DEFINE_INTEGRAL_TYPEBUILDER(char);
-DEFINE_INTEGRAL_TYPEBUILDER(signed char);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
-DEFINE_INTEGRAL_TYPEBUILDER(short);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
-DEFINE_INTEGRAL_TYPEBUILDER(int);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
-DEFINE_INTEGRAL_TYPEBUILDER(long);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
-#ifdef _MSC_VER
-DEFINE_INTEGRAL_TYPEBUILDER(__int64);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
-#else /* _MSC_VER */
-DEFINE_INTEGRAL_TYPEBUILDER(long long);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
-#endif /* _MSC_VER */
-#undef DEFINE_INTEGRAL_TYPEBUILDER
-
-template<uint32_t num_bits, bool cross>
-class TypeBuilder<types::i<num_bits>, cross> {
-public:
- static IntegerType *get(LLVMContext &C) {
- return IntegerType::get(C, num_bits);
- }
-};
-
-template<> class TypeBuilder<float, false> {
-public:
- static Type *get(LLVMContext& C) {
- return Type::getFloatTy(C);
- }
-};
-template<> class TypeBuilder<float, true> {};
-
-template<> class TypeBuilder<double, false> {
-public:
- static Type *get(LLVMContext& C) {
- return Type::getDoubleTy(C);
- }
-};
-template<> class TypeBuilder<double, true> {};
-
-template<bool cross> class TypeBuilder<types::ieee_float, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
-};
-template<bool cross> class TypeBuilder<types::ieee_double, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
-};
-template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::fp128, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
-public:
- static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
-};
-
-template<bool cross> class TypeBuilder<void, cross> {
-public:
- static Type *get(LLVMContext &C) {
- return Type::getVoidTy(C);
- }
-};
-
-/// void* is disallowed in LLVM types, but it occurs often enough in C code that
-/// we special case it.
-template<> class TypeBuilder<void*, false>
- : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<const void*, false>
- : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<volatile void*, false>
- : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<const volatile void*, false>
- : public TypeBuilder<types::i<8>*, false> {};
-
-template<typename R, bool cross> class TypeBuilder<R(), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
- }
-};
-template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, false);
- }
-};
-template<typename R, typename A1, typename A2, bool cross>
-class TypeBuilder<R(A1, A2), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, false);
- }
-};
-template<typename R, typename A1, typename A2, typename A3, bool cross>
-class TypeBuilder<R(A1, A2, A3), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, false);
- }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
- bool cross>
-class TypeBuilder<R(A1, A2, A3, A4), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- TypeBuilder<A4, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, false);
- }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- TypeBuilder<A4, cross>::get(Context),
- TypeBuilder<A5, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, false);
- }
-};
-
-template<typename R, bool cross> class TypeBuilder<R(...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
- }
-};
-template<typename R, typename A1, bool cross>
-class TypeBuilder<R(A1, ...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
- }
-};
-template<typename R, typename A1, typename A2, bool cross>
-class TypeBuilder<R(A1, A2, ...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, true);
- }
-};
-template<typename R, typename A1, typename A2, typename A3, bool cross>
-class TypeBuilder<R(A1, A2, A3, ...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, true);
- }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
- bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- TypeBuilder<A4, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, true);
- }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
-public:
- static FunctionType *get(LLVMContext &Context) {
- Type *params[] = {
- TypeBuilder<A1, cross>::get(Context),
- TypeBuilder<A2, cross>::get(Context),
- TypeBuilder<A3, cross>::get(Context),
- TypeBuilder<A4, cross>::get(Context),
- TypeBuilder<A5, cross>::get(Context),
- };
- return FunctionType::get(TypeBuilder<R, cross>::get(Context),
- params, true);
- }
-};
-
-} // namespace llvm
-
-#endif
diff --git a/include/llvm/Support/ValueHandle.h b/include/llvm/Support/ValueHandle.h
index b7210b2..61e21b8 100644
--- a/include/llvm/Support/ValueHandle.h
+++ b/include/llvm/Support/ValueHandle.h
@@ -110,11 +110,12 @@ protected:
V != DenseMapInfo<Value *>::getTombstoneKey();
}
-private:
+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(); }
@@ -367,7 +368,7 @@ protected:
CallbackVH(const CallbackVH &RHS)
: ValueHandleBase(Callback, RHS) {}
- virtual ~CallbackVH();
+ virtual ~CallbackVH() {}
void setValPtr(Value *P) {
ValueHandleBase::operator=(P);
@@ -389,15 +390,13 @@ public:
///
/// All implementations must remove the reference from this object to the
/// Value that's being destroyed.
- virtual void deleted() {
- setValPtr(NULL);
- }
+ virtual void deleted();
/// 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 *) {}
+ virtual void allUsesReplacedWith(Value *);
};
// Specialize simplify_type to allow CallbackVH to participate in
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 47206b3..98910eb 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -130,7 +130,7 @@ public:
void setError(const Twine &Message, Token &Location) const;
bool failed() const;
- virtual void skip() {};
+ virtual void skip() {}
unsigned int getType() const { return TypeID; }
static inline bool classof(const Node *) { return true; }
@@ -336,7 +336,7 @@ public:
enum MappingType {
MT_Block,
MT_Flow,
- MT_Inline //< An inline mapping node is used for "[key: value]".
+ MT_Inline ///< An inline mapping node is used for "[key: value]".
};
MappingNode(OwningPtr<Document> &D, StringRef Anchor, MappingType MT)
@@ -513,37 +513,44 @@ private:
/// @brief Iterator abstraction for Documents over a Stream.
class document_iterator {
public:
- document_iterator() : Doc(NullDoc) {}
- document_iterator(OwningPtr<Document> &D) : Doc(D) {}
+ document_iterator() : Doc(0) {}
+ document_iterator(OwningPtr<Document> &D) : Doc(&D) {}
bool operator ==(const document_iterator &Other) {
- return Doc == Other.Doc;
+ if (isAtEnd() || Other.isAtEnd())
+ return isAtEnd() && Other.isAtEnd();
+
+ return *Doc == *Other.Doc;
}
bool operator !=(const document_iterator &Other) {
return !(*this == Other);
}
document_iterator operator ++() {
- if (!Doc->skip()) {
- Doc.reset(0);
+ assert(Doc != 0 && "incrementing iterator past the end.");
+ if (!(*Doc)->skip()) {
+ Doc->reset(0);
} else {
- Stream &S = Doc->stream;
- Doc.reset(new Document(S));
+ Stream &S = (*Doc)->stream;
+ Doc->reset(new Document(S));
}
return *this;
}
Document &operator *() {
- return *Doc;
+ return *Doc->get();
}
OwningPtr<Document> &operator ->() {
- return Doc;
+ return *Doc;
}
private:
- static OwningPtr<Document> NullDoc;
- OwningPtr<Document> &Doc;
+ bool isAtEnd() const {
+ return Doc == 0 || *Doc == 0;
+ }
+
+ OwningPtr<Document> *Doc;
};
}
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 6c5d478..5de749a 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -230,6 +230,9 @@ public:
/// rather than being put on a pipe or stored in a file.
virtual bool is_displayed() const { return false; }
+ /// This function determines if this stream is displayed and supports colors.
+ virtual bool has_colors() const { return is_displayed(); }
+
//===--------------------------------------------------------------------===//
// Subclass Interface
//===--------------------------------------------------------------------===//
@@ -386,10 +389,12 @@ public:
virtual bool is_displayed() const;
+ virtual bool has_colors() const;
+
/// has_error - Return the value of the flag in this raw_fd_ostream indicating
/// whether an output error has been encountered.
/// This doesn't implicitly flush any pending output. Also, it doesn't
- /// guarantee to detect all errors unless the the stream has been closed.
+ /// guarantee to detect all errors unless the stream has been closed.
bool has_error() const {
return Error;
}
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index a3a551f..7b97547 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -21,6 +21,11 @@
#include <cstddef>
#include <utility>
+#ifndef __has_feature
+#define LLVM_DEFINED_HAS_FEATURE
+#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
@@ -58,9 +63,15 @@ struct is_class
/// type can be copied around with memcpy instead of running ctors etc.
template <typename T>
struct isPodLike {
+#if __has_feature(is_trivially_copyable)
+ // If the compiler supports the is_trivially_copyable trait use it, as it
+ // matches the definition of isPodLike closely.
+ static const bool value = __is_trivially_copyable(T);
+#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;
+#endif
};
// std::pair's are pod-like if their elements are.
@@ -202,4 +213,8 @@ struct conditional<false, T, F> { typedef F type; };
}
+#ifdef LLVM_DEFINED_HAS_FEATURE
+#undef __has_feature
+#endif
+
#endif
OpenPOWER on IntegriCloud