diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 |
commit | 7b3392326c40c3c20697816acae597ba7b3144eb (patch) | |
tree | 2cbcf22585e99f8a87d12d5ff94f392c0d266819 /include/llvm/Support | |
parent | 1176aa52646fe641a4243a246aa7f960c708a274 (diff) | |
download | FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.zip FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.tar.gz |
Vendor import of llvm release_30 branch r142614:
http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
Diffstat (limited to 'include/llvm/Support')
32 files changed, 2876 insertions, 773 deletions
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h new file mode 100644 index 0000000..554b784 --- /dev/null +++ b/include/llvm/Support/BlockFrequency.h @@ -0,0 +1,63 @@ +//===-------- BlockFrequency.h - Block Frequency Wrapper --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements Block Frequency class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H +#define LLVM_SUPPORT_BLOCKFREQUENCY_H + +namespace llvm { + +class raw_ostream; +class BranchProbability; + +// This class represents Block Frequency as a 64-bit value. +class BlockFrequency { + + uint64_t Frequency; + static const int64_t ENTRY_FREQ = 1024; + +public: + BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { } + + static uint64_t getEntryFrequency() { return ENTRY_FREQ; } + uint64_t getFrequency() const { return Frequency; } + + BlockFrequency &operator*=(const BranchProbability &Prob); + const BlockFrequency operator*(const BranchProbability &Prob) const; + + BlockFrequency &operator+=(const BlockFrequency &Freq); + const BlockFrequency operator+(const BlockFrequency &Freq) const; + + bool operator<(const BlockFrequency &RHS) const { + return Frequency < RHS.Frequency; + } + + bool operator<=(const BlockFrequency &RHS) const { + return Frequency <= RHS.Frequency; + } + + bool operator>(const BlockFrequency &RHS) const { + return Frequency > RHS.Frequency; + } + + bool operator>=(const BlockFrequency &RHS) const { + return Frequency >= RHS.Frequency; + } + + void print(raw_ostream &OS) const; +}; + +raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq); + +} + +#endif diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index 2e81490..05c24d4 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -1,4 +1,4 @@ -//===- BranchProbability.h - Branch Probability Analysis --------*- C++ -*-===// +//===- BranchProbability.h - Branch Probability Wrapper ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -34,13 +34,13 @@ public: uint32_t getNumerator() const { return N; } uint32_t getDenominator() const { return D; } - + // Return (1 - Probability). BranchProbability getCompl() { return BranchProbability(D - N, D); } - raw_ostream &print(raw_ostream &OS) const; + void print(raw_ostream &OS) const; void dump() const; }; diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index 8a998a8..04b8c4e 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -147,7 +147,7 @@ public: /// getType - Return the type of the instruction that generated this call site /// - const Type *getType() const { return (*this)->getType(); } + Type *getType() const { return (*this)->getType(); } /// getCaller - Return the caller function for this call site /// diff --git a/include/llvm/Support/Capacity.h b/include/llvm/Support/Capacity.h new file mode 100644 index 0000000..d8cda43 --- /dev/null +++ b/include/llvm/Support/Capacity.h @@ -0,0 +1,30 @@ +//===--- Capacity.h - Generic computation of ADT memory use -----*- 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 capacity function that computes the amount of +// memory used by an ADT. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CAPACITY_H +#define LLVM_SUPPORT_CAPACITY_H + +namespace llvm { + +template <typename T> +static inline size_t capacity_in_bytes(const T &x) { + // This default definition of capacity should work for things like std::vector + // and friends. More specialized versions will work for others. + return x.capacity() * sizeof(typename T::value_type); +} + +} // end namespace llvm + +#endif + diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h new file mode 100644 index 0000000..41351dc --- /dev/null +++ b/include/llvm/Support/CodeGen.h @@ -0,0 +1,32 @@ +//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file define some types which define code generation concepts. For +// example, relocation model. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CODEGEN_H +#define LLVM_SUPPORT_CODEGEN_H + +namespace llvm { + + // Relocation model types. + namespace Reloc { + enum Model { Default, Static, PIC_, DynamicNoPIC }; + } + + // Code model types. + namespace CodeModel { + enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; + } + +} // end llvm namespace + +#endif diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index d609871..c6b62a8 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -59,6 +59,15 @@ void ParseEnvironmentOptions(const char *progName, const char *envvar, /// CommandLine utilities to print their own version string. void SetVersionPrinter(void (*func)()); +///===---------------------------------------------------------------------===// +/// AddExtraVersionPrinter - Add an extra printer to use in addition to the +/// default one. This can be called multiple times, +/// and each time it adds a new function to the list +/// which will be called after the basic LLVM version +/// printing is complete. Each can then add additional +/// information specific to the tool. +void AddExtraVersionPrinter(void (*func)()); + // PrintOptionValues - Print option values. // With -print-options print the difference between option values and defaults. @@ -797,6 +806,28 @@ public: EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>); //-------------------------------------------------- +// parser<unsigned long long> +// +template<> +class parser<unsigned long long> : public basic_parser<unsigned long long> { +public: + // parse - Return true on error. + bool parse(Option &O, StringRef ArgName, StringRef Arg, + unsigned long long &Val); + + // getValueName - Overload in subclass to provide a better default value. + virtual const char *getValueName() const { return "uint"; } + + void printOptionDiff(const Option &O, unsigned long long V, OptVal Default, + size_t GlobalWidth) const; + + // An out-of-line virtual method to provide a 'home' for this class. + virtual void anchor(); +}; + +EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>); + +//-------------------------------------------------- // parser<double> // template<> diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index 7330235..93aa343 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -118,22 +118,34 @@ public: // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return ConstantExpr::getGetElementPtr(C, Idx); + } + Constant *CreateGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return ConstantExpr::getInBoundsGetElementPtr(C, Idx); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } //===--------------------------------------------------------------------===// @@ -141,37 +153,37 @@ public: //===--------------------------------------------------------------------===// Constant *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { return ConstantExpr::getCast(Op, C, DestTy); } - Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + Constant *CreatePointerCast(Constant *C, Type *DestTy) const { return ConstantExpr::getPointerCast(C, DestTy); } - Constant *CreateIntCast(Constant *C, const Type *DestTy, + Constant *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { return ConstantExpr::getIntegerCast(C, DestTy, isSigned); } - Constant *CreateFPCast(Constant *C, const Type *DestTy) const { + Constant *CreateFPCast(Constant *C, Type *DestTy) const { return ConstantExpr::getFPCast(C, DestTy); } - Constant *CreateBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getZExtOrBitCast(C, DestTy); } - Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getSExtOrBitCast(C, DestTy); } - Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getTruncOrBitCast(C, DestTy); } diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h new file mode 100644 index 0000000..506ec96 --- /dev/null +++ b/include/llvm/Support/DataExtractor.h @@ -0,0 +1,352 @@ +//===-- DataExtractor.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H +#define LLVM_SUPPORT_DATAEXTRACTOR_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class DataExtractor { + StringRef Data; + uint8_t IsLittleEndian; + uint8_t PointerSize; +public: + /// Construct with a buffer that is owned by the caller. + /// + /// This constructor allows us to use data that is owned by the + /// caller. The data must stay around as long as this object is + /// valid. + DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize) + : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {} + + /// getData - Get the data pointed to by this extractor. + StringRef getData() const { return Data; } + /// isLittleEndian - Get the endianess for this extractor. + bool isLittleEndian() const { return IsLittleEndian; } + /// getAddressSize - Get the address size for this extractor. + uint8_t getAddressSize() const { return PointerSize; } + + /// Extract a C string from \a *offset_ptr. + /// + /// Returns a pointer to a C String from the data at the offset + /// pointed to by \a offset_ptr. A variable length NULL terminated C + /// string will be extracted and the \a offset_ptr will be + /// updated with the offset of the byte that follows the NULL + /// terminator byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// A pointer to the C string value in the data. If the offset + /// pointed to by \a offset_ptr is out of bounds, or if the + /// offset plus the length of the C string is out of bounds, + /// NULL will be returned. + const char *getCStr(uint32_t *offset_ptr) const; + + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to eight since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The unsigned integer value that was extracted, or zero on + /// failure. + uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const; + + /// Extract an signed integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The sign extended signed integer value that was extracted, + /// or zero on failure. + int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; + + //------------------------------------------------------------------ + /// Extract an pointer from \a *offset_ptr. + /// + /// Extract a single pointer from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted pointer + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any pointer values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted pointer value as a 64 integer. + uint64_t getAddress(uint32_t *offset_ptr) const { + return getUnsigned(offset_ptr, PointerSize); + } + + /// Extract a uint8_t value from \a *offset_ptr. + /// + /// Extract a single uint8_t from the binary data at the offset + /// pointed to by \a offset_ptr, and advance the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint8_t value. + uint8_t getU8(uint32_t *offset_ptr) const; + + /// Extract \a count uint8_t values from \a *offset_ptr. + /// + /// Extract \a count uint8_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint8_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint8_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint16_t value from \a *offset_ptr. + /// + /// Extract a single uint16_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint16_t value. + //------------------------------------------------------------------ + uint16_t getU16(uint32_t *offset_ptr) const; + + /// Extract \a count uint16_t values from \a *offset_ptr. + /// + /// Extract \a count uint16_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint16_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint16_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const; + + /// Extract a uint32_t value from \a *offset_ptr. + /// + /// Extract a single uint32_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint32_t value. + uint32_t getU32(uint32_t *offset_ptr) const; + + /// Extract \a count uint32_t values from \a *offset_ptr. + /// + /// Extract \a count uint32_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint32_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint32_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const; + + /// Extract a uint64_t value from \a *offset_ptr. + /// + /// Extract a single uint64_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint64_t value. + uint64_t getU64(uint32_t *offset_ptr) const; + + /// Extract \a count uint64_t values from \a *offset_ptr. + /// + /// Extract \a count uint64_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint64_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint64_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const; + + /// Extract a signed LEB128 value from \a *offset_ptr. + /// + /// Extracts an signed LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted signed integer value. + int64_t getSLEB128(uint32_t *offset_ptr) const; + + /// Extract a unsigned LEB128 value from \a *offset_ptr. + /// + /// Extracts an unsigned LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted unsigned integer value. + uint64_t getULEB128(uint32_t *offset_ptr) const; + + /// Test the validity of \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset into the data in this + /// object, \b false otherwise. + bool isValidOffset(uint32_t offset) const { return Data.size() > offset; } + + /// Test the availability of \a length bytes of data from \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset and there are \a + /// length bytes available at that offset, \b false otherwise. + bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const { + return offset + length >= offset && isValidOffset(offset + length - 1); + } +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index 72c4518..8c0220a 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -15,12 +15,14 @@ |* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*| |* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *| |* *| -|* No library is required when using these functinons. *| +|* No library is required when using these functions. *| |* *| |*===----------------------------------------------------------------------===*/ /* Please leave this file C-compatible. */ +/* Please keep this file in sync with DataTypes.h.in */ + #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -131,7 +133,8 @@ typedef signed int ssize_t; # define INT32_MAX 2147483647 #endif #ifndef INT32_MIN -# define INT32_MIN -2147483648 +/* MSC treats -2147483648 as -(2147483648U). */ +# define INT32_MIN (-INT32_MAX - 1) #endif #ifndef UINT32_MAX # define UINT32_MAX 4294967295U @@ -163,6 +166,11 @@ typedef signed int ssize_t; #ifndef UINT64_C # define UINT64_C(C) C##ui64 #endif + +#ifndef PRIx64 +# define PRIx64 "I64x" +#endif + #endif /* _MSC_VER */ /* Set defaults for constants which we cannot find. */ diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in index 5965e8c..425805a 100644 --- a/include/llvm/Support/DataTypes.h.in +++ b/include/llvm/Support/DataTypes.h.in @@ -1,4 +1,4 @@ -/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\ +/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| @@ -21,6 +21,8 @@ /* Please leave this file C-compatible. */ +/* Please keep this file in sync with DataTypes.h.cmake */ + #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -36,17 +38,19 @@ #include <math.h> #endif +#ifndef _MSC_VER + /* Note that this header's correct operation depends on __STDC_LIMIT_MACROS being defined. We would define it here, but in order to prevent Bad Things happening when system headers or C++ STL headers include stdint.h before we define it here, we define it on the g++ command line (in Makefile.rules). */ #if !defined(__STDC_LIMIT_MACROS) -# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h" +# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h" #endif #if !defined(__STDC_CONSTANT_MACROS) # error "Must #define __STDC_CONSTANT_MACROS before " \ - "#including System/DataTypes.h" + "#including Support/DataTypes.h" #endif /* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */ @@ -87,6 +91,88 @@ typedef u_int64_t uint64_t; #define UINT32_MAX 4294967295U #endif +#else /* _MSC_VER */ +/* Visual C++ doesn't provide standard integer headers, but it does provide + built-in data types. */ +#include <stdlib.h> +#include <stddef.h> +#include <sys/types.h> +#ifdef __cplusplus +#include <cmath> +#else +#include <math.h> +#endif +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed int ssize_t; +#ifndef INT8_MAX +# define INT8_MAX 127 +#endif +#ifndef INT8_MIN +# define INT8_MIN -128 +#endif +#ifndef UINT8_MAX +# define UINT8_MAX 255 +#endif +#ifndef INT16_MAX +# define INT16_MAX 32767 +#endif +#ifndef INT16_MIN +# define INT16_MIN -32768 +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535 +#endif +#ifndef INT32_MAX +# define INT32_MAX 2147483647 +#endif +#ifndef INT32_MIN +/* MSC treats -2147483648 as -(2147483648U). */ +# define INT32_MIN (-INT32_MAX - 1) +#endif +#ifndef UINT32_MAX +# define UINT32_MAX 4294967295U +#endif +/* Certain compatibility updates to VC++ introduce the `cstdint' + * header, which defines the INT*_C macros. On default installs they + * are absent. */ +#ifndef INT8_C +# define INT8_C(C) C##i8 +#endif +#ifndef UINT8_C +# define UINT8_C(C) C##ui8 +#endif +#ifndef INT16_C +# define INT16_C(C) C##i16 +#endif +#ifndef UINT16_C +# define UINT16_C(C) C##ui16 +#endif +#ifndef INT32_C +# define INT32_C(C) C##i32 +#endif +#ifndef UINT32_C +# define UINT32_C(C) C##ui32 +#endif +#ifndef INT64_C +# define INT64_C(C) C##i64 +#endif +#ifndef UINT64_C +# define UINT64_C(C) C##ui64 +#endif + +#ifndef PRIx64 +# define PRIx64 "I64x" +#endif + +#endif /* _MSC_VER */ + /* Set defaults for constants which we cannot find. */ #if !defined(INT64_MAX) # define INT64_MAX 9223372036854775807LL diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 70bac0c..30f9187 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -22,8 +22,10 @@ namespace llvm { // Debug info constants. enum { - LLVMDebugVersion = (9 << 16), // Current version of debug information. - LLVMDebugVersion8 = (8 << 16), // Cconstant for version 8. + LLVMDebugVersion = (11 << 16), // Current version of debug information. + LLVMDebugVersion10 = (10 << 16), // Constant for version 10. + LLVMDebugVersion9 = (9 << 16), // Constant for version 9. + LLVMDebugVersion8 = (8 << 16), // Constant for version 8. LLVMDebugVersion7 = (7 << 16), // Constant for version 7. LLVMDebugVersion6 = (6 << 16), // Constant for version 6. LLVMDebugVersion5 = (5 << 16), // Constant for version 5. @@ -117,7 +119,16 @@ enum dwarf_constants { DW_TAG_imported_unit = 0x3d, DW_TAG_condition = 0x3f, DW_TAG_shared_type = 0x40, - DW_TAG_rvalue_reference_type = 0x41, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + DW_TAG_MIPS_loop = 0x4081, + DW_TAG_format_label = 0x4101, + DW_TAG_function_template = 0x4102, + DW_TAG_class_template = 0x4103, + DW_TAG_GNU_template_template_param = 0x4106, + DW_TAG_GNU_template_parameter_pack = 0x4107, + DW_TAG_GNU_formal_parameter_pack = 0x4108, DW_TAG_lo_user = 0x4080, DW_TAG_hi_user = 0xffff, @@ -212,14 +223,36 @@ enum dwarf_constants { DW_AT_elemental = 0x66, DW_AT_pure = 0x67, DW_AT_recursive = 0x68, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, - DW_AT_sf_names = 0x2101, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_MIPS_stride_byte = 0x200c, + DW_AT_MIPS_stride_elem = 0x200d, + DW_AT_MIPS_ptr_dopetype = 0x200e, + DW_AT_MIPS_allocatable_dopetype = 0x200f, + DW_AT_MIPS_assumed_shape_dopetype = 0x2010, + DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, + DW_AT_GNU_template_name = 0x2110, + DW_AT_MIPS_assumed_size = 0x2011, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, @@ -259,6 +292,10 @@ enum dwarf_constants { DW_FORM_ref8 = 0x14, DW_FORM_ref_udata = 0x15, DW_FORM_indirect = 0x16, + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_ref_sig8 = 0x20, // Operation encodings DW_OP_addr = 0x03, @@ -413,6 +450,8 @@ enum dwarf_constants { DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, DW_OP_bit_piece = 0x9d, + DW_OP_implicit_value = 0x9e, + DW_OP_stack_value = 0x9f, DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff, @@ -432,6 +471,7 @@ enum dwarf_constants { DW_ATE_signed_fixed = 0x0d, DW_ATE_unsigned_fixed = 0x0e, DW_ATE_decimal_float = 0x0f, + DW_ATE_UTF = 0x10, DW_ATE_lo_user = 0x80, DW_ATE_hi_user = 0xff, @@ -484,6 +524,7 @@ enum dwarf_constants { DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, + DW_LANG_Python = 0x0014, DW_LANG_lo_user = 0x8000, DW_LANG_hi_user = 0xffff, @@ -533,6 +574,7 @@ enum dwarf_constants { DW_LNE_end_sequence = 0x01, DW_LNE_set_address = 0x02, DW_LNE_define_file = 0x03, + DW_LNE_set_discriminator = 0x04, DW_LNE_lo_user = 0x80, DW_LNE_hi_user = 0xff, @@ -571,6 +613,9 @@ enum dwarf_constants { DW_CFA_val_offset = 0x14, DW_CFA_val_offset_sf = 0x15, DW_CFA_val_expression = 0x16, + DW_CFA_MIPS_advance_loc8 = 0x1d, + DW_CFA_GNU_window_save = 0x2d, + DW_CFA_GNU_args_size = 0x2e, DW_CFA_lo_user = 0x1c, DW_CFA_hi_user = 0x3f, diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h index e6d9ff5..288936b 100644 --- a/include/llvm/Support/DynamicLibrary.h +++ b/include/llvm/Support/DynamicLibrary.h @@ -28,36 +28,62 @@ namespace sys { /// It also allows for symbols to be defined which don't live in any library, /// but rather the main program itself, useful on Windows where the main /// executable cannot be searched. + /// + /// Note: there is currently no interface for temporarily loading a library, + /// or for unloading libraries when the LLVM library is unloaded. class DynamicLibrary { - DynamicLibrary(); // DO NOT IMPLEMENT + // Placeholder whose address represents an invalid library. + // We use this instead of NULL or a pointer-int pair because the OS library + // might define 0 or 1 to be "special" handles, such as "search all". + static char Invalid; + + // Opaque data used to interface with OS-specific dynamic library handling. + void *Data; + + explicit DynamicLibrary(void *data = &Invalid) : Data(data) {} public: - /// This function allows a library to be loaded without instantiating a - /// DynamicLibrary object. Consequently, it is marked as being permanent - /// and will only be unloaded when the program terminates. This returns - /// false on success or returns true and fills in *ErrMsg on failure. - /// @brief Open a dynamic library permanently. + /// Returns true if the object refers to a valid library. + bool isValid() { return Data != &Invalid; } + + /// Searches through the library for the symbol \p symbolName. If it is + /// found, the address of that symbol is returned. If not, NULL is returned. + /// Note that NULL will also be returned if the library failed to load. + /// Use isValid() to distinguish these cases if it is important. + /// Note that this will \e not search symbols explicitly registered by + /// AddSymbol(). + void *getAddressOfSymbol(const char *symbolName); + + /// This function permanently loads the dynamic library at the given path. + /// The library will only be unloaded when the program terminates. + /// This returns a valid DynamicLibrary instance on success and an invalid + /// instance on failure (see isValid()). \p *errMsg will only be modified + /// if the library fails to load. /// - /// NOTE: This function is not thread safe. + /// It is safe to call this function multiple times for the same library. + /// @brief Open a dynamic library permanently. + static DynamicLibrary getPermanentLibrary(const char *filename, + std::string *errMsg = 0); + + /// This function permanently loads the dynamic library at the given path. + /// Use this instead of getPermanentLibrary() when you won't need to get + /// symbols from the library itself. /// - static bool LoadLibraryPermanently(const char *filename, - std::string *ErrMsg = 0); + /// It is safe to call this function multiple times for the same library. + static bool LoadLibraryPermanently(const char *Filename, + std::string *ErrMsg = 0) { + return !getPermanentLibrary(Filename, ErrMsg).isValid(); + } /// This function will search through all previously loaded dynamic - /// libraries for the symbol \p symbolName. If it is found, the addressof + /// libraries for the symbol \p symbolName. If it is found, the address of /// that symbol is returned. If not, null is returned. Note that this will - /// search permanently loaded libraries (LoadLibraryPermanently) as well - /// as ephemerally loaded libraries (constructors). + /// search permanently loaded libraries (getPermanentLibrary()) as well + /// as explicitly registered symbols (AddSymbol()). /// @throws std::string on error. /// @brief Search through libraries for address of a symbol - /// - /// NOTE: This function is not thread safe. - /// static void *SearchForAddressOfSymbol(const char *symbolName); /// @brief Convenience function for C++ophiles. - /// - /// NOTE: This function is not thread safe. - /// static void *SearchForAddressOfSymbol(const std::string &symbolName) { return SearchForAddressOfSymbol(symbolName.c_str()); } @@ -66,18 +92,7 @@ namespace sys { /// value \p symbolValue. These symbols are searched before any /// libraries. /// @brief Add searchable symbol/value pair. - /// - /// NOTE: This function is not thread safe. - /// - static void AddSymbol(const char *symbolName, void *symbolValue); - - /// @brief Convenience function for C++ophiles. - /// - /// NOTE: This function is not thread safe. - /// - static void AddSymbol(const std::string &symbolName, void *symbolValue) { - AddSymbol(symbolName.c_str(), symbolValue); - } + static void AddSymbol(StringRef symbolName, void *symbolValue); }; } // End sys namespace diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index be48112..c5b85e2 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -28,20 +28,18 @@ namespace llvm { namespace ELF { typedef uint32_t Elf32_Addr; // Program address -typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Off; // File offset -typedef int32_t Elf32_Sword; +typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; typedef uint64_t Elf64_Addr; typedef uint64_t Elf64_Off; -typedef int32_t Elf64_Shalf; -typedef int32_t Elf64_Sword; +typedef uint16_t Elf64_Half; typedef uint32_t Elf64_Word; -typedef int64_t Elf64_Sxword; +typedef int32_t Elf64_Sword; typedef uint64_t Elf64_Xword; -typedef uint32_t Elf64_Half; -typedef uint16_t Elf64_Quarter; +typedef int64_t Elf64_Sxword; // Object file magic string. static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' }; @@ -87,19 +85,19 @@ struct Elf32_Ehdr { // types (see above). struct Elf64_Ehdr { unsigned char e_ident[EI_NIDENT]; - Elf64_Quarter e_type; - Elf64_Quarter e_machine; - Elf64_Half e_version; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; - Elf64_Half e_flags; - Elf64_Quarter e_ehsize; - Elf64_Quarter e_phentsize; - Elf64_Quarter e_phnum; - Elf64_Quarter e_shentsize; - Elf64_Quarter e_shnum; - Elf64_Quarter e_shstrndx; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; bool checkMagic() const { return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0; } @@ -126,22 +124,170 @@ enum { // Machine architectures enum { - EM_NONE = 0, // No machine - EM_M32 = 1, // AT&T WE 32100 - EM_SPARC = 2, // SPARC - EM_386 = 3, // Intel 386 - EM_68K = 4, // Motorola 68000 - EM_88K = 5, // Motorola 88000 - EM_486 = 6, // Intel 486 (deprecated) - EM_860 = 7, // Intel 80860 - EM_MIPS = 8, // MIPS R3000 - EM_PPC = 20, // PowerPC - EM_PPC64 = 21, // PowerPC64 - EM_ARM = 40, // ARM - EM_ALPHA = 41, // DEC Alpha - EM_SPARCV9 = 43, // SPARC V9 - EM_X86_64 = 62, // AMD64 - EM_MBLAZE = 47787 // Xilinx MicroBlaze + EM_NONE = 0, // No machine + EM_M32 = 1, // AT&T WE 32100 + EM_SPARC = 2, // SPARC + EM_386 = 3, // Intel 386 + EM_68K = 4, // Motorola 68000 + EM_88K = 5, // Motorola 88000 + EM_486 = 6, // Intel 486 (deprecated) + EM_860 = 7, // Intel 80860 + EM_MIPS = 8, // MIPS R3000 + EM_S370 = 9, // IBM System/370 + EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian + EM_PARISC = 15, // Hewlett-Packard PA-RISC + EM_VPP500 = 17, // Fujitsu VPP500 + EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC + EM_960 = 19, // Intel 80960 + EM_PPC = 20, // PowerPC + EM_PPC64 = 21, // PowerPC64 + EM_S390 = 22, // IBM System/390 + EM_SPU = 23, // IBM SPU/SPC + EM_V800 = 36, // NEC V800 + EM_FR20 = 37, // Fujitsu FR20 + EM_RH32 = 38, // TRW RH-32 + EM_RCE = 39, // Motorola RCE + EM_ARM = 40, // ARM + EM_ALPHA = 41, // DEC Alpha + EM_SH = 42, // Hitachi SH + EM_SPARCV9 = 43, // SPARC V9 + EM_TRICORE = 44, // Siemens TriCore + EM_ARC = 45, // Argonaut RISC Core + EM_H8_300 = 46, // Hitachi H8/300 + EM_H8_300H = 47, // Hitachi H8/300H + EM_H8S = 48, // Hitachi H8S + EM_H8_500 = 49, // Hitachi H8/500 + EM_IA_64 = 50, // Intel IA-64 processor architecture + EM_MIPS_X = 51, // Stanford MIPS-X + EM_COLDFIRE = 52, // Motorola ColdFire + EM_68HC12 = 53, // Motorola M68HC12 + EM_MMA = 54, // Fujitsu MMA Multimedia Accelerator + EM_PCP = 55, // Siemens PCP + EM_NCPU = 56, // Sony nCPU embedded RISC processor + EM_NDR1 = 57, // Denso NDR1 microprocessor + EM_STARCORE = 58, // Motorola Star*Core processor + EM_ME16 = 59, // Toyota ME16 processor + EM_ST100 = 60, // STMicroelectronics ST100 processor + EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor family + EM_X86_64 = 62, // AMD x86-64 architecture + EM_PDSP = 63, // Sony DSP Processor + EM_PDP10 = 64, // Digital Equipment Corp. PDP-10 + EM_PDP11 = 65, // Digital Equipment Corp. PDP-11 + EM_FX66 = 66, // Siemens FX66 microcontroller + EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller + EM_ST7 = 68, // STMicroelectronics ST7 8-bit microcontroller + EM_68HC16 = 69, // Motorola MC68HC16 Microcontroller + EM_68HC11 = 70, // Motorola MC68HC11 Microcontroller + EM_68HC08 = 71, // Motorola MC68HC08 Microcontroller + EM_68HC05 = 72, // Motorola MC68HC05 Microcontroller + EM_SVX = 73, // Silicon Graphics SVx + EM_ST19 = 74, // STMicroelectronics ST19 8-bit microcontroller + EM_VAX = 75, // Digital VAX + EM_CRIS = 76, // Axis Communications 32-bit embedded processor + EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded processor + EM_FIREPATH = 78, // Element 14 64-bit DSP Processor + EM_ZSP = 79, // LSI Logic 16-bit DSP Processor + EM_MMIX = 80, // Donald Knuth's educational 64-bit processor + EM_HUANY = 81, // Harvard University machine-independent object files + EM_PRISM = 82, // SiTera Prism + EM_AVR = 83, // Atmel AVR 8-bit microcontroller + EM_FR30 = 84, // Fujitsu FR30 + EM_D10V = 85, // Mitsubishi D10V + EM_D30V = 86, // Mitsubishi D30V + EM_V850 = 87, // NEC v850 + EM_M32R = 88, // Mitsubishi M32R + EM_MN10300 = 89, // Matsushita MN10300 + EM_MN10200 = 90, // Matsushita MN10200 + EM_PJ = 91, // picoJava + EM_OPENRISC = 92, // OpenRISC 32-bit embedded processor + EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old + // spelling/synonym: EM_ARC_A5) + EM_XTENSA = 94, // Tensilica Xtensa Architecture + EM_VIDEOCORE = 95, // Alphamosaic VideoCore processor + EM_TMM_GPP = 96, // Thompson Multimedia General Purpose Processor + EM_NS32K = 97, // National Semiconductor 32000 series + EM_TPC = 98, // Tenor Network TPC processor + EM_SNP1K = 99, // Trebia SNP 1000 processor + EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200 + EM_IP2K = 101, // Ubicom IP2xxx microcontroller family + EM_MAX = 102, // MAX Processor + EM_CR = 103, // National Semiconductor CompactRISC microprocessor + EM_F2MC16 = 104, // Fujitsu F2MC16 + EM_MSP430 = 105, // Texas Instruments embedded microcontroller msp430 + EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor + EM_SE_C33 = 107, // S1C33 Family of Seiko Epson processors + EM_SEP = 108, // Sharp embedded microprocessor + EM_ARCA = 109, // Arca RISC Microprocessor + EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC + // of Peking University + EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded CPU + EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution Processor + EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core processor + EM_CRX = 114, // National Semiconductor CompactRISC CRX + EM_XGATE = 115, // Motorola XGATE embedded processor + EM_C166 = 116, // Infineon C16x/XC16x processor + EM_M16C = 117, // Renesas M16C series microprocessors + EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal + // Controller + EM_CE = 119, // Freescale Communication Engine RISC core + EM_M32C = 120, // Renesas M32C series microprocessors + EM_TSK3000 = 131, // Altium TSK3000 core + EM_RS08 = 132, // Freescale RS08 embedded processor + EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP + // processors + EM_ECOG2 = 134, // Cyan Technology eCOG2 microprocessor + EM_SCORE7 = 135, // Sunplus S+core7 RISC processor + EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor + EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor + EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture + EM_SE_C17 = 139, // Seiko Epson C17 family + EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family + EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family + EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP family + EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal Processor + 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_8051 = 165, // Intel 8051 and variants + EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable + // and extensible RISC processors + EM_NDS32 = 167, // Andes Technology compact code size embedded RISC + // processor family + EM_ECOG1 = 168, // Cyan Technology eCOG1X family + EM_ECOG1X = 168, // Cyan Technology eCOG1X family + EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers + EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP Processor + EM_MANIK = 171, // M2000 Reconfigurable RISC Microprocessor + EM_CRAYNV2 = 172, // Cray Inc. NV2 vector architecture + EM_RX = 173, // Renesas RX family + EM_METAG = 174, // Imagination Technologies META processor + // architecture + EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware architecture + EM_ECOG16 = 176, // Cyan Technology eCOG16 family + EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit + // microprocessor + EM_ETPU = 178, // Freescale Extended Time Processing Unit + EM_SLE9X = 179, // Infineon Technologies SLE9X core + EM_L10M = 180, // Intel L10M + EM_K10M = 181, // Intel K10M + EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family + EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller + EM_TILE64 = 187, // Tilera TILE64 multicore architecture family + EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family + EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core + EM_CUDA = 190, // NVIDIA CUDA architecture + EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family + EM_CLOUDSHIELD = 192, // CloudShield architecture family + EM_COREA_1ST = 193, // KIPO-KAIST Core-A 1st generation processor family + EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor family + EM_ARC_COMPACT2 = 195, // Synopsys ARCompact V2 + EM_OPEN8 = 196, // Open8 8-bit RISC soft processor core + EM_RL78 = 197, // Renesas RL78 family + EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor + EM_78KOR = 199, // Renesas 78KOR family + EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC) + EM_MBLAZE = 47787 // Xilinx MicroBlaze }; // Object file classes. @@ -211,6 +357,11 @@ enum { R_X86_64_PC64 = 24, R_X86_64_GOTOFF64 = 25, R_X86_64_GOTPC32 = 26, + R_X86_64_GOT64 = 27, + R_X86_64_GOTPCREL64 = 28, + R_X86_64_GOTPC64 = 29, + R_X86_64_GOTPLT64 = 30, + R_X86_64_PLTOFF64 = 31, R_X86_64_SIZE32 = 32, R_X86_64_SIZE64 = 33, R_X86_64_GOTPC32_TLSDESC = 34, @@ -290,6 +441,23 @@ enum { R_MICROBLAZE_COPY = 21 }; +enum { + R_PPC_NONE = 0, /* No relocation. */ + R_PPC_ADDR32 = 1, + R_PPC_ADDR24 = 2, + R_PPC_ADDR16 = 3, + R_PPC_ADDR16_LO = 4, + R_PPC_ADDR16_HI = 5, + R_PPC_ADDR16_HA = 6, + R_PPC_ADDR14 = 7, + R_PPC_ADDR14_BRTAKEN = 8, + R_PPC_ADDR14_BRNTAKEN = 9, + R_PPC_REL24 = 10, + R_PPC_REL14 = 11, + R_PPC_REL14_BRTAKEN = 12, + R_PPC_REL14_BRNTAKEN = 13, + R_PPC_REL32 = 26 +}; // ARM Specific e_flags enum { EF_ARM_EABIMASK = 0xFF000000U }; @@ -431,7 +599,61 @@ enum { R_ARM_THM_TLS_DESCSEQ32 = 0x82 }; - +// ELF Relocation types for Mips +enum { + R_MIPS_NONE = 0, + R_MIPS_16 = 1, + R_MIPS_32 = 2, + R_MIPS_REL32 = 3, + R_MIPS_26 = 4, + R_MIPS_HI16 = 5, + R_MIPS_LO16 = 6, + R_MIPS_GPREL16 = 7, + R_MIPS_LITERAL = 8, + R_MIPS_GOT16 = 9, + R_MIPS_PC16 = 10, + R_MIPS_CALL16 = 11, + R_MIPS_GPREL32 = 12, + R_MIPS_SHIFT5 = 16, + R_MIPS_SHIFT6 = 17, + R_MIPS_64 = 18, + R_MIPS_GOT_DISP = 19, + R_MIPS_GOT_PAGE = 20, + R_MIPS_GOT_OFST = 21, + R_MIPS_GOT_HI16 = 22, + R_MIPS_GOT_LO16 = 23, + R_MIPS_SUB = 24, + R_MIPS_INSERT_A = 25, + R_MIPS_INSERT_B = 26, + R_MIPS_DELETE = 27, + R_MIPS_HIGHER = 28, + R_MIPS_HIGHEST = 29, + R_MIPS_CALL_HI16 = 30, + R_MIPS_CALL_LO16 = 31, + R_MIPS_SCN_DISP = 32, + R_MIPS_REL16 = 33, + R_MIPS_ADD_IMMEDIATE = 34, + R_MIPS_PJUMP = 35, + R_MIPS_RELGOT = 36, + R_MIPS_JALR = 37, + R_MIPS_TLS_DTPMOD32 = 38, + R_MIPS_TLS_DTPREL32 = 39, + R_MIPS_TLS_DTPMOD64 = 40, + R_MIPS_TLS_DTPREL64 = 41, + R_MIPS_TLS_GD = 42, + R_MIPS_TLS_LDM = 43, + R_MIPS_TLS_DTPREL_HI16 = 44, + R_MIPS_TLS_DTPREL_LO16 = 45, + R_MIPS_TLS_GOTTPREL = 46, + R_MIPS_TLS_TPREL32 = 47, + R_MIPS_TLS_TPREL64 = 48, + R_MIPS_TLS_TPREL_HI16 = 49, + R_MIPS_TLS_TPREL_LO16 = 50, + R_MIPS_GLOB_DAT = 51, + R_MIPS_COPY = 126, + R_MIPS_JUMP_SLOT = 127, + R_MIPS_NUM = 218 +}; // Section header. struct Elf32_Shdr { @@ -449,14 +671,14 @@ struct Elf32_Shdr { // Section header for ELF64 - same fields as ELF32, different types. struct Elf64_Shdr { - Elf64_Half sh_name; - Elf64_Half sh_type; + Elf64_Word sh_name; + Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; - Elf64_Half sh_link; - Elf64_Half sh_info; + Elf64_Word sh_link; + Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; }; @@ -467,6 +689,8 @@ enum { SHN_LORESERVE = 0xff00, // Lowest reserved index SHN_LOPROC = 0xff00, // Lowest processor-specific index SHN_HIPROC = 0xff1f, // Highest processor-specific index + SHN_LOOS = 0xff20, // Lowest operating system-specific index + SHN_HIOS = 0xff3f, // Highest operating system-specific index SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE @@ -557,8 +781,19 @@ enum { /// set to the start of the section by the boot code. XCORE_SHF_DP_SECTION = 0x1000U, + SHF_MASKOS = 0x0ff00000, + // Bits indicating processor-specific flags. - SHF_MASKPROC = 0xf0000000 + SHF_MASKPROC = 0xf0000000, + + // If an object file section does not have this flag set, then it may not hold + // more than 2GB and can be freely referred to in objects using smaller code + // models. Otherwise, only objects using larger code models can refer to them. + // For example, a medium code model object can refer to data in a section that + // sets this flag besides being able to refer to data in a section that does + // not set it; likewise, a small code model object can refer only to code in a + // section that does not set this flag. + SHF_X86_64_LARGE = 0x10000000 }; // Section Group Flags @@ -619,6 +854,8 @@ enum { STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def STB_GLOBAL = 1, // Global symbol, visible to all object files being combined STB_WEAK = 2, // Weak symbol, like global but lower-precedence + STB_LOOS = 10, // Lowest operating system-specific binding type + STB_HIOS = 12, // Highest operating system-specific binding type STB_LOPROC = 13, // Lowest processor-specific binding type STB_HIPROC = 15 // Highest processor-specific binding type }; @@ -632,6 +869,8 @@ enum { STT_FILE = 4, // Local, absolute symbol that refers to a file STT_COMMON = 5, // An uninitialized common block STT_TLS = 6, // Thread local data object + STT_LOOS = 7, // Lowest operating system-specific symbol type + STT_HIOS = 8, // Highest operating system-specific symbol type STT_LOPROC = 13, // Lowest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type }; @@ -746,6 +985,16 @@ enum { PT_NOTE = 4, // Auxiliary information. PT_SHLIB = 5, // Reserved. PT_PHDR = 6, // The program header table itself. + PT_TLS = 7, // The thread-local storage template. + PT_LOOS = 0x60000000, // Lowest operating system-specific pt entry type. + + // x86-64 program header types. + // These all contain stack unwind tables. + PT_GNU_EH_FRAME = 0x6474e550, + PT_SUNW_EH_FRAME = 0x6474e550, + PT_SUNW_UNWIND = 0x6464e550, + + 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. }; @@ -755,7 +1004,8 @@ enum { PF_X = 1, // Execute PF_W = 2, // Write PF_R = 4, // Read - PF_MASKPROC = 0xf0000000 // Unspecified + PF_MASKOS = 0x0ff00000,// Bits for operating system-specific semantics. + PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics. }; // Dynamic table entry for ELF32. @@ -811,12 +1061,29 @@ enum { DT_FINI_ARRAY = 26, // Pointer to array of termination functions. DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY. DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY. + DT_RUNPATH = 29, // String table offset of lib search path. + DT_FLAGS = 30, // Flags. + DT_ENCODING = 32, // Values from here to DT_LOOS follow the rules + // for the interpretation of the d_un union. + + DT_PREINIT_ARRAY = 32, // Pointer to array of preinit functions. + DT_PREINIT_ARRAYSZ = 33, // Size of the DT_PREINIT_ARRAY array. + 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_FLAGS values. +enum { + DF_ORIGIN = 0x01, // The object may reference $ORIGIN. + DF_SYMBOLIC = 0x02, // Search the shared lib before searching the exe. + DF_TEXTREL = 0x04, // Relocations may modify a non-writable segment. + DF_BIND_NOW = 0x08, // Process all relocations on load. + DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically. +}; + } // end namespace ELF } // end namespace llvm diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 4f013f8..a868e5f 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -201,30 +201,6 @@ error_code rename(const Twine &from, const Twine &to); /// platform specific error_code. error_code resize_file(const Twine &path, uint64_t size); -/// @brief Make file readable. -/// -/// @param path Input path. -/// @param value If true, make readable, else, make unreadable. -/// @results errc::success if readability has been successfully set, otherwise a -/// platform specific error_code. -error_code set_read(const Twine &path, bool value); - -/// @brief Make file writeable. -/// -/// @param path Input path. -/// @param value If true, make writeable, else, make unwriteable. -/// @results errc::success if writeability has been successfully set, otherwise -/// a platform specific error_code. -error_code set_write(const Twine &path, bool value); - -/// @brief Make file executable. -/// -/// @param path Input path. -/// @param value If true, make executable, else, make unexecutable. -/// @results errc::success if executability has been successfully set, otherwise -/// a platform specific error_code. -error_code set_execute(const Twine &path, bool value); - /// @} /// @name Physical Observers /// @{ @@ -245,6 +221,13 @@ bool exists(file_status status); /// platform specific error_code. error_code exists(const Twine &path, bool &result); +/// @brief Simpler version of exists for clients that don't need to +/// differentiate between an error and false. +inline bool exists(const Twine &path) { + bool result; + return !exists(path, result) && result; +} + /// @brief Do file_status's represent the same thing? /// /// @param A Input file_status. @@ -289,15 +272,6 @@ bool is_directory(file_status status); /// platform specific error_code. error_code is_directory(const Twine &path, bool &result); -/// @brief Is path an empty file? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a an empty file, false if it is not. -/// Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_empty(const Twine &path, bool &result); - /// @brief Does status represent a regular file? /// /// @param status A file_status previously returned from status. @@ -346,40 +320,6 @@ bool is_symlink(file_status status); /// platform specific error_code. error_code is_symlink(const Twine &path, bool &result); -/// @brief Get last write time without changing it. -/// -/// @param path Input path. -/// @param result Set to the last write time (UNIX time) of \a path if it -/// exists. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code last_write_time(const Twine &path, std::time_t &result); - -/// @brief Set last write time. -/// -/// @param path Input path. -/// @param value Time to set (UNIX time) \a path's last write time to. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code set_last_write_time(const Twine &path, std::time_t value); - -/// @brief Read a symlink's value. -/// -/// @param path Input path. -/// @param result Set to the value of the symbolic link \a path. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code read_symlink(const Twine &path, SmallVectorImpl<char> &result); - -/// @brief Get disk space usage information. -/// -/// @param path Input path. -/// @param result Set to the capacity, free, and available space on the device -/// \a path is on. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code disk_space(const Twine &path, space_info &result); - /// @brief Get file status as if by POSIX stat(). /// /// @param path Input path. @@ -402,16 +342,6 @@ bool status_known(file_status s); /// platform specific error_code. error_code status_known(const Twine &path, bool &result); -/// @brief Get file status as if by POSIX lstat(). -/// -/// Does not resolve symlinks. -/// -/// @param path Input path. -/// @param result Set to the file status. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code symlink_status(const Twine &path, file_status &result); - /// @brief Generate a unique path and open it as a file. /// /// Generates a unique path suitable for a temporary file and then opens it as a @@ -427,10 +357,13 @@ error_code symlink_status(const Twine &path, file_status &result); /// @param model Name to base unique path off of. /// @param result_fs Set to the opened file's file descriptor. /// @param result_path Set to the opened file's absolute path. +/// @param makeAbsolute If true and @model is not an absolute path, a temp +/// directory will be prepended. /// @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); + SmallVectorImpl<char> &result_path, + bool makeAbsolute = true); /// @brief Canonicalize path. /// @@ -472,60 +405,6 @@ error_code get_magic(const Twine &path, uint32_t len, /// platform specific error_code. error_code identify_magic(const Twine &path, LLVMFileType &result); -/// @brief Is file bitcode? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a bitcode file, false if it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_bitcode(const Twine &path, bool &result); - -/// @brief Is file a dynamic library? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a dynamic library, false if it is -/// not, undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_dynamic_library(const Twine &path, bool &result); - -/// @brief Is an object file? -/// -/// @param path Input path. -/// @param result Set to true if \a path is an object file, false if it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_object_file(const Twine &path, bool &result); - -/// @brief Can file be read? -/// -/// @param path Input path. -/// @param result Set to true if \a path is readable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_read(const Twine &path, bool &result); - -/// @brief Can file be written? -/// -/// @param path Input path. -/// @param result Set to true if \a path is writeable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_write(const Twine &path, bool &result); - -/// @brief Can file be executed? -/// -/// @param path Input path. -/// @param result Set to true if \a path is executable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_execute(const Twine &path, bool &result); - /// @brief Get library paths the system linker uses. /// /// @param result Set to the list of system library paths. @@ -569,35 +448,28 @@ error_code GetMainExecutable(const char *argv0, void *MainAddr, /// @{ /// directory_entry - A single entry in a directory. Caches the status either -/// from the result of the iteration syscall, or the first time status or -/// symlink_status is called. +/// from the result of the iteration syscall, or the first time status is +/// called. class directory_entry { std::string Path; mutable file_status Status; - mutable file_status SymlinkStatus; public: - explicit directory_entry(const Twine &path, file_status st = file_status(), - file_status symlink_st = file_status()) + explicit directory_entry(const Twine &path, file_status st = file_status()) : Path(path.str()) - , Status(st) - , SymlinkStatus(symlink_st) {} + , Status(st) {} directory_entry() {} - void assign(const Twine &path, file_status st = file_status(), - file_status symlink_st = file_status()) { + void assign(const Twine &path, file_status st = file_status()) { Path = path.str(); Status = st; - SymlinkStatus = symlink_st; } - void replace_filename(const Twine &filename, file_status st = file_status(), - file_status symlink_st = file_status()); + void replace_filename(const Twine &filename, file_status st = file_status()); const std::string &path() const { return Path; } error_code status(file_status &result) const; - error_code symlink_status(file_status &result) const; bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; } bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); } diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index f64e3db..59812d9 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -126,6 +126,50 @@ public: } }; +/// format_object4 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template <typename T1, typename T2, typename T3, typename T4> +class format_object4 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; +public: + format_object4(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); + } +}; + +/// format_object5 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class format_object5 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; + T5 Val5; +public: + format_object5(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4, const T5 &val5) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), + Val5(val5) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); + } +}; + /// format - This is a helper function that is used to produce formatted output. /// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; template <typename T> @@ -149,6 +193,24 @@ template <typename T1, typename T2, typename T3> return format_object3<T1, T2, T3>(Fmt, Val1, Val2, Val3); } +/// format - This is a helper function that is used to produce formatted output. +/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +template <typename T1, typename T2, typename T3, typename T4> +inline format_object4<T1, T2, T3, T4> format(const char *Fmt, const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4) { + return format_object4<T1, T2, T3, T4>(Fmt, Val1, Val2, Val3, Val4); +} + +/// format - This is a helper function that is used to produce formatted output. +/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +template <typename T1, typename T2, typename T3, typename T4, typename T5> +inline format_object5<T1, T2, T3, T4, T5> format(const char *Fmt,const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4, const T5 &Val5) { + return format_object5<T1, T2, T3, T4, T5>(Fmt, Val1, Val2, Val3, Val4, Val5); +} + } // end namespace llvm #endif diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h new file mode 100644 index 0000000..49cd87f --- /dev/null +++ b/include/llvm/Support/GCOV.h @@ -0,0 +1,224 @@ +//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header provides the interface to read and write coverage files that +// use 'gcov' format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_GCOV_H +#define LLVM_GCOV_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +class GCOVFunction; +class GCOVBlock; +class GCOVLines; +class FileInfo; + +enum GCOVFormat { + InvalidGCOV, + GCNO_402, + GCNO_404, + GCDA_402, + GCDA_404 +}; + +/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific +/// read operations. +class GCOVBuffer { +public: + GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} + + /// readGCOVFormat - Read GCOV signature at the beginning of buffer. + enum GCOVFormat readGCOVFormat() { + StringRef Magic = Buffer->getBuffer().slice(0, 12); + Cursor = 12; + if (Magic == "oncg*404MVLL") + return GCNO_404; + else if (Magic == "oncg*204MVLL") + return GCNO_402; + else if (Magic == "adcg*404MVLL") + return GCDA_404; + else if (Magic == "adcg*204MVLL") + return GCDA_402; + + Cursor = 0; + return InvalidGCOV; + } + + /// readFunctionTag - If cursor points to a function tag then increment the + /// cursor and return true otherwise return false. + 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') { + return false; + } + Cursor += 4; + return true; + } + + /// readBlockTag - If cursor points to a block tag then increment the + /// cursor and return true otherwise return false. + 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') { + return false; + } + Cursor += 4; + return true; + } + + /// readEdgeTag - If cursor points to an edge tag then increment the + /// cursor and return true otherwise return false. + 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') { + return false; + } + Cursor += 4; + return true; + } + + /// readLineTag - If cursor points to a line tag then increment the + /// cursor and return true otherwise return false. + 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') { + return false; + } + Cursor += 4; + return true; + } + + /// readArcTag - If cursor points to an gcda arc tag then increment the + /// cursor and return true otherwise return false. + 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') { + return false; + } + Cursor += 4; + return true; + } + + uint32_t readInt() { + uint32_t Result; + StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); + assert (Str.empty() == false && "Unexpected memory buffer end!"); + Cursor += 4; + Result = *(uint32_t *)(Str.data()); + return Result; + } + + uint64_t readInt64() { + uint64_t Lo = readInt(); + uint64_t Hi = readInt(); + uint64_t Result = Lo | (Hi << 32); + return Result; + } + + StringRef readString() { + uint32_t Len = readInt() * 4; + StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len); + Cursor += Len; + return Str; + } + + uint64_t getCursor() const { return Cursor; } +private: + MemoryBuffer *Buffer; + uint64_t Cursor; +}; + +/// GCOVFile - Collects coverage information for one pair of coverage file +/// (.gcno and .gcda). +class GCOVFile { +public: + GCOVFile() {} + ~GCOVFile(); + bool read(GCOVBuffer &Buffer); + void dump(); + void collectLineCounts(FileInfo &FI); +private: + SmallVector<GCOVFunction *, 16> Functions; +}; + +/// GCOVFunction - Collects function information. +class GCOVFunction { +public: + GCOVFunction() : Ident(0), LineNumber(0) {} + ~GCOVFunction(); + bool read(GCOVBuffer &Buffer, GCOVFormat Format); + void dump(); + void collectLineCounts(FileInfo &FI); +private: + uint32_t Ident; + uint32_t LineNumber; + StringRef Name; + StringRef Filename; + SmallVector<GCOVBlock *, 16> Blocks; +}; + +/// GCOVBlock - Collects block information. +class GCOVBlock { +public: + GCOVBlock(uint32_t N) : Number(N), Counter(0) {} + ~GCOVBlock(); + void addEdge(uint32_t N) { Edges.push_back(N); } + void addLine(StringRef Filename, uint32_t LineNo); + void addCount(uint64_t N) { Counter = N; } + void dump(); + void collectLineCounts(FileInfo &FI); +private: + uint32_t Number; + uint64_t Counter; + SmallVector<uint32_t, 16> Edges; + StringMap<GCOVLines *> Lines; +}; + +/// GCOVLines - A wrapper around a vector of int to keep track of line nos. +class GCOVLines { +public: + ~GCOVLines() { Lines.clear(); } + void add(uint32_t N) { Lines.push_back(N); } + void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count); + void dump(); + +private: + SmallVector<uint32_t, 4> Lines; +}; + +typedef SmallVector<uint32_t, 16> LineCounts; +class FileInfo { +public: + void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count); + void print(); +private: + StringMap<LineCounts> LineInfo; +}; + +} + +#endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h index e5e7fc7..ef92c95 100644 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/include/llvm/Support/GetElementPtrTypeIterator.h @@ -21,16 +21,16 @@ namespace llvm { template<typename ItTy = User::const_op_iterator> class generic_gep_type_iterator - : public std::iterator<std::forward_iterator_tag, const Type *, ptrdiff_t> { + : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { typedef std::iterator<std::forward_iterator_tag, - const Type *, ptrdiff_t> super; + Type *, ptrdiff_t> super; ItTy OpIt; - const Type *CurTy; + Type *CurTy; generic_gep_type_iterator() {} public: - static generic_gep_type_iterator begin(const Type *Ty, ItTy It) { + static generic_gep_type_iterator begin(Type *Ty, ItTy It) { generic_gep_type_iterator I; I.CurTy = Ty; I.OpIt = It; @@ -50,23 +50,23 @@ namespace llvm { return !operator==(x); } - const Type *operator*() const { + Type *operator*() const { return CurTy; } - const Type *getIndexedType() const { - const CompositeType *CT = cast<CompositeType>(CurTy); + Type *getIndexedType() const { + CompositeType *CT = cast<CompositeType>(CurTy); return CT->getTypeAtIndex(getOperand()); } // This is a non-standard operator->. It allows you to call methods on the // current type directly. - const Type *operator->() const { return operator*(); } + Type *operator->() const { return operator*(); } Value *getOperand() const { return *OpIt; } generic_gep_type_iterator& operator++() { // Preincrement - if (const CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { + if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { CurTy = CT->getTypeAtIndex(getOperand()); } else { CurTy = 0; @@ -97,16 +97,16 @@ namespace llvm { return gep_type_iterator::end(GEP.op_end()); } - template<typename ItTy> - inline generic_gep_type_iterator<ItTy> - gep_type_begin(const Type *Op0, ItTy I, ItTy E) { - return generic_gep_type_iterator<ItTy>::begin(Op0, I); + template<typename T> + inline generic_gep_type_iterator<const T *> + gep_type_begin(Type *Op0, ArrayRef<T> A) { + return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); } - template<typename ItTy> - inline generic_gep_type_iterator<ItTy> - gep_type_end(const Type *Op0, ItTy I, ItTy E) { - return generic_gep_type_iterator<ItTy>::end(E); + template<typename T> + inline generic_gep_type_iterator<const T *> + gep_type_end(Type *Op0, ArrayRef<T> A) { + return generic_gep_type_iterator<const T *>::end(A.end()); } } // end namespace llvm diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 91cd78e..7828001 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -475,8 +475,8 @@ public: Name); } - UnwindInst *CreateUnwind() { - return Insert(new UnwindInst(Context)); + ResumeInst *CreateResume(Value *Exn) { + return Insert(ResumeInst::Create(Exn)); } UnreachableInst *CreateUnreachable() { @@ -744,7 +744,7 @@ public: // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// - AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0, + AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0, const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } @@ -762,71 +762,74 @@ public: StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } - template<typename RandomAccessIterator> - Value *CreateGEP(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + 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. - RandomAccessIterator i; - for (i = IdxBegin; i < IdxEnd; ++i) - if (!isa<Constant>(*i)) + size_t i, e; + for (i = 0, e = IdxList.size(); i != e; ++i) + if (!isa<Constant>(IdxList[i])) break; - if (i == IdxEnd) - return Insert(Folder.CreateGetElementPtr(PC, &IdxBegin[0], - IdxEnd - IdxBegin), - Name); + if (i == e) + return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name); + return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name); } - template<typename RandomAccessIterator> - Value *CreateInBoundsGEP(Value *Ptr, RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &Name = "") { if (Constant *PC = dyn_cast<Constant>(Ptr)) { // Every index must be constant. - RandomAccessIterator i; - for (i = IdxBegin; i < IdxEnd; ++i) - if (!isa<Constant>(*i)) + size_t i, e; + for (i = 0, e = IdxList.size(); i != e; ++i) + if (!isa<Constant>(IdxList[i])) break; - if (i == IdxEnd) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, - &IdxBegin[0], - IdxEnd - IdxBegin), - Name); + if (i == e) + return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd), - 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, 1), Name); + 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, 1), Name); + 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, 1), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), 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, 1), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); } Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -836,9 +839,9 @@ public: }; if (Constant *PC = dyn_cast<Constant>(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -848,26 +851,26 @@ public: }; if (Constant *PC = dyn_cast<Constant>(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), 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, 1), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), 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, 1), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); } Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -877,9 +880,9 @@ public: }; if (Constant *PC = dyn_cast<Constant>(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -889,9 +892,9 @@ public: }; if (Constant *PC = dyn_cast<Constant>(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); } Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); @@ -903,54 +906,54 @@ public: Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; - return CreateInBoundsGEP(gv, Args, Args+2, Name); + return CreateInBoundsGEP(gv, Args, Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// - Value *CreateTrunc(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::Trunc, V, DestTy, Name); } - Value *CreateZExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::ZExt, V, DestTy, Name); } - Value *CreateSExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } - Value *CreateFPToUI(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToUI, V, DestTy, Name); } - Value *CreateFPToSI(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToSI, V, DestTy, Name); } - Value *CreateUIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::UIToFP, V, DestTy, Name); } - Value *CreateSIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::SIToFP, V, DestTy, Name); } - Value *CreateFPTrunc(Value *V, const Type *DestTy, + Value *CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPTrunc, V, DestTy, Name); } - Value *CreateFPExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPExt, V, DestTy, Name); } - Value *CreatePtrToInt(Value *V, const Type *DestTy, + Value *CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::PtrToInt, V, DestTy, Name); } - Value *CreateIntToPtr(Value *V, const Type *DestTy, + Value *CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::IntToPtr, V, DestTy, Name); } - Value *CreateBitCast(Value *V, const Type *DestTy, + Value *CreateBitCast(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::BitCast, V, DestTy, Name); } - Value *CreateZExtOrBitCast(Value *V, const Type *DestTy, + Value *CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -958,7 +961,7 @@ public: return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name); } - Value *CreateSExtOrBitCast(Value *V, const Type *DestTy, + Value *CreateSExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -966,7 +969,7 @@ public: return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name); } - Value *CreateTruncOrBitCast(Value *V, const Type *DestTy, + Value *CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -974,7 +977,7 @@ public: return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name); } - Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy, + Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -982,7 +985,7 @@ public: return Insert(Folder.CreateCast(Op, VC, DestTy), Name); return Insert(CastInst::Create(Op, V, DestTy), Name); } - Value *CreatePointerCast(Value *V, const Type *DestTy, + Value *CreatePointerCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -990,7 +993,7 @@ public: return Insert(Folder.CreatePointerCast(VC, DestTy), Name); return Insert(CastInst::CreatePointerCast(V, DestTy), Name); } - Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned, + Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -1001,9 +1004,9 @@ public: 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 *, const Type *, const char *); // DO NOT IMPLEMENT + Value *CreateIntCast(Value *, Type *, const char *); // DO NOT IMPLEMENT public: - Value *CreateFPCast(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (Constant *VC = dyn_cast<Constant>(V)) @@ -1108,7 +1111,7 @@ public: // Instruction creation methods: Other Instructions //===--------------------------------------------------------------------===// - PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues, + PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name = "") { return Insert(PHINode::Create(Ty, NumReservedValues), Name); } @@ -1142,7 +1145,7 @@ public: CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args, const Twine &Name = "") { - return Insert(CallInst::Create(Callee, Args, Name)); + return Insert(CallInst::Create(Callee, Args), Name); } Value *CreateSelect(Value *C, Value *True, Value *False, @@ -1154,7 +1157,7 @@ public: return Insert(SelectInst::Create(C, True, False), Name); } - VAArgInst *CreateVAArg(Value *List, const Type *Ty, const Twine &Name = "") { + VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") { return Insert(new VAArgInst(List, Ty), Name); } @@ -1201,6 +1204,11 @@ public: 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 //===--------------------------------------------------------------------===// diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index b2e5d58..a661c4f 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -163,12 +163,16 @@ public: RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} + RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } + RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I){ DELEGATE(Instruction); } + RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction); } + RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); } @@ -191,6 +195,7 @@ public: RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } + RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } // Next level propagators: If the user does not overload a specific // instruction type, they can overload one of these to get the whole class diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 6841a0f..5b68586 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -110,6 +110,10 @@ namespace llvm { LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB + LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX + LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS + LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS + LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT // Constant bits for the "flags" field in llvm::MachO::segment_command SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM @@ -569,6 +573,13 @@ namespace llvm { uint32_t cryptid; }; + struct version_min_command { + uint32_t cmd; + uint32_t cmdsize; + uint32_t version; + uint32_t reserved; + }; + struct dyld_info_command { uint32_t cmd; uint32_t cmdsize; diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 5e55bd9..06816de 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -75,9 +75,9 @@ public: /// return a MemoryBuffer. static error_code getOpenFile(int FD, const char *Filename, OwningPtr<MemoryBuffer> &result, - size_t FileSize = -1, - size_t MapSize = -1, - off_t Offset = 0, + uint64_t FileSize = -1, + uint64_t MapSize = -1, + int64_t Offset = 0, bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 94359a5..75c1a79 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -177,22 +177,22 @@ public: // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Instruction *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx); + Instruction *CreateGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return GetElementPtrInst::Create(C, IdxList); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } - Instruction *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx); + Instruction *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return GetElementPtrInst::CreateInBounds(C, IdxList); } //===--------------------------------------------------------------------===// @@ -200,37 +200,37 @@ public: //===--------------------------------------------------------------------===// Instruction *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { return CastInst::Create(Op, C, DestTy); } - Instruction *CreatePointerCast(Constant *C, const Type *DestTy) const { + Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { return CastInst::CreatePointerCast(C, DestTy); } - Instruction *CreateIntCast(Constant *C, const Type *DestTy, + Instruction *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { return CastInst::CreateIntegerCast(C, DestTy, isSigned); } - Instruction *CreateFPCast(Constant *C, const Type *DestTy) const { + Instruction *CreateFPCast(Constant *C, Type *DestTy) const { return CastInst::CreateFPCast(C, DestTy); } - Instruction *CreateBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Instruction *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Instruction *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Instruction *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateZExtOrBitCast(C, DestTy); } - Instruction *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateSExtOrBitCast(C, DestTy); } - Instruction *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateTruncOrBitCast(C, DestTy); } diff --git a/include/llvm/Support/PassManagerBuilder.h b/include/llvm/Support/PassManagerBuilder.h deleted file mode 100644 index b0cec6e..0000000 --- a/include/llvm/Support/PassManagerBuilder.h +++ /dev/null @@ -1,331 +0,0 @@ -//===-- llvm/Support/PassManagerBuilder.h - Build Standard Pass -*- 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 PassManagerBuilder class, which is used to set up a -// "standard" optimization sequence suitable for languages like C and C++. -// -// These are implemented as inline functions so that we do not have to worry -// about link issues. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H -#define LLVM_SUPPORT_PASSMANAGERBUILDER_H - -#include "llvm/PassManager.h" -#include "llvm/DefaultPasses.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Target/TargetLibraryInfo.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/IPO.h" - -namespace llvm { - -/// PassManagerBuilder - This class is used to set up a standard optimization -/// sequence for languages like C and C++, allowing some APIs to customize the -/// pass sequence in various ways. A simple example of using it would be: -/// -/// PassManagerBuilder Builder; -/// Builder.OptLevel = 2; -/// Builder.populateFunctionPassManager(FPM); -/// Builder.populateModulePassManager(MPM); -/// -/// In addition to setting up the basic passes, PassManagerBuilder allows -/// frontends to vend a plugin API, where plugins are allowed to add extensions -/// to the default pass manager. They do this by specifying where in the pass -/// pipeline they want to be added, along with a callback function that adds -/// the pass(es). For example, a plugin that wanted to add a loop optimization -/// could do something like this: -/// -/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) { -/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0) -/// PM.add(createMyAwesomePass()); -/// } -/// ... -/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, -/// addMyLoopPass); -/// ... -class PassManagerBuilder { -public: - - /// Extensions are passed the builder itself (so they can see how it is - /// configured) as well as the pass manager to add stuff to. - typedef void (*ExtensionFn)(const PassManagerBuilder &Builder, - PassManagerBase &PM); - enum ExtensionPointTy { - /// EP_EarlyAsPossible - This extension point allows adding passes before - /// any other transformations, allowing them to see the code as it is coming - /// out of the frontend. - EP_EarlyAsPossible, - - /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to - /// the end of the loop optimizer. - EP_LoopOptimizerEnd, - - /// EP_ScalarOptimizerLate - This extension point allows adding optimization - /// passes after most of the main optimizations, but before the last - /// cleanup-ish optimizations. - EP_ScalarOptimizerLate - }; - - /// The Optimization Level - Specify the basic optimization level. - /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 - unsigned OptLevel; - - /// SizeLevel - How much we're optimizing for size. - /// 0 = none, 1 = -Os, 2 = -Oz - unsigned SizeLevel; - - /// LibraryInfo - Specifies information about the runtime library for the - /// optimizer. If this is non-null, it is added to both the function and - /// per-module pass pipeline. - TargetLibraryInfo *LibraryInfo; - - /// Inliner - Specifies the inliner to use. If this is non-null, it is - /// added to the per-module passes. - Pass *Inliner; - - bool DisableSimplifyLibCalls; - bool DisableUnitAtATime; - bool DisableUnrollLoops; - -private: - /// ExtensionList - This is list of all of the extensions that are registered. - std::vector<std::pair<ExtensionPointTy, ExtensionFn> > Extensions; - -public: - PassManagerBuilder() { - OptLevel = 2; - SizeLevel = 0; - LibraryInfo = 0; - Inliner = 0; - DisableSimplifyLibCalls = false; - DisableUnitAtATime = false; - DisableUnrollLoops = false; - } - - ~PassManagerBuilder() { - delete LibraryInfo; - delete Inliner; - } - - void addExtension(ExtensionPointTy Ty, ExtensionFn Fn) { - Extensions.push_back(std::make_pair(Ty, Fn)); - } - -private: - void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const { - for (unsigned i = 0, e = Extensions.size(); i != e; ++i) - if (Extensions[i].first == ETy) - Extensions[i].second(*this, PM); - } - - void addInitialAliasAnalysisPasses(PassManagerBase &PM) const { - // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that - // BasicAliasAnalysis wins if they disagree. This is intended to help - // support "obvious" type-punning idioms. - PM.add(createTypeBasedAliasAnalysisPass()); - PM.add(createBasicAliasAnalysisPass()); - } -public: - - /// populateFunctionPassManager - This fills in the function pass manager, - /// which is expected to be run on each function immediately as it is - /// generated. The idea is to reduce the size of the IR in memory. - void populateFunctionPassManager(FunctionPassManager &FPM) { - addExtensionsToPM(EP_EarlyAsPossible, FPM); - - // Add LibraryInfo if we have some. - if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); - - if (OptLevel == 0) return; - - addInitialAliasAnalysisPasses(FPM); - - FPM.add(createCFGSimplificationPass()); - FPM.add(createScalarReplAggregatesPass()); - FPM.add(createEarlyCSEPass()); - FPM.add(createLowerExpectIntrinsicPass()); - } - - /// populateModulePassManager - This sets up the primary pass manager. - void populateModulePassManager(PassManagerBase &MPM) { - // If all optimizations are disabled, just run the always-inline pass. - if (OptLevel == 0) { - if (Inliner) { - MPM.add(Inliner); - Inliner = 0; - } - return; - } - - // Add LibraryInfo if we have some. - if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo)); - - addInitialAliasAnalysisPasses(MPM); - - if (!DisableUnitAtATime) { - MPM.add(createGlobalOptimizerPass()); // Optimize out global vars - - MPM.add(createIPSCCPPass()); // IP SCCP - MPM.add(createDeadArgEliminationPass()); // Dead argument elimination - - MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE - MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - } - - // Start of CallGraph SCC passes. - if (!DisableUnitAtATime) - MPM.add(createPruneEHPass()); // Remove dead EH info - if (Inliner) { - MPM.add(Inliner); - Inliner = 0; - } - if (!DisableUnitAtATime) - MPM.add(createFunctionAttrsPass()); // Set readonly/readnone attrs - if (OptLevel > 2) - MPM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - // Start of function pass. - // Break up aggregate allocas, using SSAUpdater. - MPM.add(createScalarReplAggregatesPass(-1, false)); - MPM.add(createEarlyCSEPass()); // Catch trivial redundancies - if (!DisableSimplifyLibCalls) - MPM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - MPM.add(createJumpThreadingPass()); // Thread jumps. - MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Combine silly seq's - - MPM.add(createTailCallEliminationPass()); // Eliminate tail calls - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createReassociatePass()); // Reassociate expressions - MPM.add(createLoopRotatePass()); // Rotate Loop - MPM.add(createLICMPass()); // Hoist loop invariants - MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); - MPM.add(createInstructionCombiningPass()); - MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars - MPM.add(createLoopIdiomPass()); // Recognize idioms like memset. - MPM.add(createLoopDeletionPass()); // Delete dead loops - if (!DisableUnrollLoops) - MPM.add(createLoopUnrollPass()); // Unroll small loops - addExtensionsToPM(EP_LoopOptimizerEnd, MPM); - - if (OptLevel > 1) - MPM.add(createGVNPass()); // Remove redundancies - MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset - MPM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - MPM.add(createInstructionCombiningPass()); - MPM.add(createJumpThreadingPass()); // Thread jumps - MPM.add(createCorrelatedValuePropagationPass()); - MPM.add(createDeadStoreEliminationPass()); // Delete dead stores - - addExtensionsToPM(EP_ScalarOptimizerLate, MPM); - - MPM.add(createAggressiveDCEPass()); // Delete dead instructions - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Clean up after everything. - - if (!DisableUnitAtATime) { - // FIXME: We shouldn't bother with this anymore. - MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - - // GlobalOpt already deletes dead functions and globals, at -O3 try a - // late pass of GlobalDCE. It is capable of deleting dead cycles. - if (OptLevel > 2) - MPM.add(createGlobalDCEPass()); // Remove dead fns and globals. - - if (OptLevel > 1) - MPM.add(createConstantMergePass()); // Merge dup global constants - } - } - - void populateLTOPassManager(PassManagerBase &PM, bool Internalize, - bool RunInliner) { - // Provide AliasAnalysis services for optimizations. - addInitialAliasAnalysisPasses(PM); - - // Now that composite has been compiled, scan through the module, looking - // for a main function. If main is defined, mark all other functions - // internal. - if (Internalize) - PM.add(createInternalizePass(true)); - - // Propagate constants at call sites into the functions they call. This - // opens opportunities for globalopt (and inlining) by substituting function - // pointers passed as arguments to direct uses of functions. - PM.add(createIPSCCPPass()); - - // Now that we internalized some globals, see if we can hack on them! - PM.add(createGlobalOptimizerPass()); - - // Linking modules together can lead to duplicated global constants, only - // keep one copy of each constant. - PM.add(createConstantMergePass()); - - // Remove unused arguments from functions. - PM.add(createDeadArgEliminationPass()); - - // Reduce the code after globalopt and ipsccp. Both can open up significant - // simplification opportunities, and both can propagate functions through - // function pointers. When this happens, we often have to resolve varargs - // calls, etc, so let instcombine do this. - PM.add(createInstructionCombiningPass()); - - // Inline small functions - if (RunInliner) - PM.add(createFunctionInliningPass()); - - PM.add(createPruneEHPass()); // Remove dead EH info. - - // Optimize globals again if we ran the inliner. - if (RunInliner) - PM.add(createGlobalOptimizerPass()); - PM.add(createGlobalDCEPass()); // Remove dead functions. - - // If we didn't decide to inline a function, check to see if we can - // transform it to pass arguments by value instead of by reference. - PM.add(createArgumentPromotionPass()); - - // The IPO passes may leave cruft around. Clean up after them. - PM.add(createInstructionCombiningPass()); - PM.add(createJumpThreadingPass()); - // Break up allocas - PM.add(createScalarReplAggregatesPass()); - - // Run a few AA driven optimizations here and now, to cleanup the code. - PM.add(createFunctionAttrsPass()); // Add nocapture. - PM.add(createGlobalsModRefPass()); // IP alias analysis. - - PM.add(createLICMPass()); // Hoist loop invariants. - PM.add(createGVNPass()); // Remove redundancies. - PM.add(createMemCpyOptPass()); // Remove dead memcpys. - // Nuke dead stores. - PM.add(createDeadStoreEliminationPass()); - - // Cleanup and simplify the code after the scalar optimizations. - PM.add(createInstructionCombiningPass()); - - PM.add(createJumpThreadingPass()); - - // Delete basic blocks, which optimization passes may have killed. - PM.add(createCFGSimplificationPass()); - - // Now that we have optimized the program, discard unreachable functions. - PM.add(createGlobalDCEPass()); - } -}; - - -} // end namespace llvm -#endif diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h index 024bb39..45165de 100644 --- a/include/llvm/Support/PathV1.h +++ b/include/llvm/Support/PathV1.h @@ -733,6 +733,7 @@ namespace sys { Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker Mach_O_Bundle_FileType, ///< Mach-O Bundle file Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub + Mach_O_DSYMCompanion_FileType, ///< Mach-O dSYM companion file COFF_FileType ///< COFF object file or lib }; diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h index 2515633..6d38c95 100644 --- a/include/llvm/Support/PathV2.h +++ b/include/llvm/Support/PathV2.h @@ -187,7 +187,7 @@ const StringRef root_name(StringRef path); /// @result The root directory of \a path if it has one, otherwise /// "". const StringRef root_directory(StringRef path); - + /// @brief Get root path. /// /// Equivalent to root_name + root_directory. @@ -264,6 +264,17 @@ const StringRef extension(StringRef path); /// @result true if \a value is a path separator character on the host OS bool is_separator(char value); +/// @brief Get the typical temporary directory for the system, e.g., +/// "/var/tmp" or "C:/TEMP" +/// +/// @param erasedOnReboot Whether to favor a path that is erased on reboot +/// rather than one that potentially persists longer. This parameter will be +/// ignored if the user or system has set the typical environment variable +/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. +/// +/// @param Result Holds the resulting path name. +void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); + /// @brief Has root name? /// /// root_name != "" diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 3379922..27ef267 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -138,6 +138,9 @@ namespace sys { /// Resets the terminals colors, or returns an escape sequence to do so. static const char *ResetColor(); + + /// Change the program working directory to that given by \arg Path. + static void SetWorkingDirectory(std::string Path); /// @} }; } diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h index 967bf14..02db327 100644 --- a/include/llvm/Support/SMLoc.h +++ b/include/llvm/Support/SMLoc.h @@ -18,19 +18,19 @@ namespace llvm { // SMLoc - Represents a location in source code. -class SMLoc { +class SMLoc { const char *Ptr; public: SMLoc() : Ptr(0) {} SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {} - + bool isValid() const { return Ptr != 0; } - + bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } - + const char *getPointer() const { return Ptr; } - + static SMLoc getFromPointer(const char *Ptr) { SMLoc L; L.Ptr = Ptr; diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 030db8f..deb8caf 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -78,6 +78,9 @@ public: DiagContext = Ctx; } + DiagHandlerTy getDiagHandler() const { return DiagHandler; } + void *getDiagContext() const { return DiagContext; } + const SrcBuffer &getBufferInfo(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i]; @@ -138,8 +141,12 @@ public: const Twine &Msg, const char *Type, bool ShowLine = true) const; - -private: + /// PrintIncludeStack - Prints the names of included files and the line of the + /// file they were included from. A diagnostic handler can use this before + /// printing its custom formatted message. + /// + /// @param IncludeLoc - The line of the include. + /// @param OS the raw_ostream to print on. void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const; }; diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 3233a98..c65faa6 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -130,22 +130,34 @@ public: // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); } - Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return Fold(ConstantExpr::getGetElementPtr(C, Idx)); + } + Constant *CreateGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Constant *> IdxList) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef<Constant *> or + // ArrayRef<Value *>. + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef<Value *> IdxList) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); } //===--------------------------------------------------------------------===// @@ -153,40 +165,40 @@ public: //===--------------------------------------------------------------------===// Constant *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getCast(Op, C, DestTy)); } - Constant *CreateIntCast(Constant *C, const Type *DestTy, + Constant *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); } - Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + Constant *CreatePointerCast(Constant *C, Type *DestTy) const { return ConstantExpr::getPointerCast(C, DestTy); } - Constant *CreateBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); } - Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); } - Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h new file mode 100644 index 0000000..45f249d --- /dev/null +++ b/include/llvm/Support/TargetRegistry.h @@ -0,0 +1,1124 @@ +//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file exposes the TargetRegistry interface, which tools can use to access +// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.) +// which have been registered. +// +// Target specific class implementations should register themselves using the +// appropriate TargetRegistry interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_TARGETREGISTRY_H +#define LLVM_SUPPORT_TARGETREGISTRY_H + +#include "llvm/Support/CodeGen.h" +#include "llvm/ADT/Triple.h" +#include <string> +#include <cassert> + +namespace llvm { + class AsmPrinter; + class Module; + class MCAssembler; + class MCAsmBackend; + class MCAsmInfo; + class MCAsmParser; + class MCCodeEmitter; + class MCCodeGenInfo; + class MCContext; + class MCDisassembler; + class MCInstrAnalysis; + class MCInstPrinter; + class MCInstrInfo; + class MCRegisterInfo; + class MCStreamer; + class MCSubtargetInfo; + class MCTargetAsmLexer; + class MCTargetAsmParser; + class TargetMachine; + class raw_ostream; + class formatted_raw_ostream; + + MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, + bool isVerboseAsm, + bool useLoc, bool useCFI, + MCInstPrinter *InstPrint, + MCCodeEmitter *CE, + MCAsmBackend *TAB, + bool ShowInst); + + /// Target - Wrapper for Target specific information. + /// + /// For registration purposes, this is a POD type so that targets can be + /// registered without the use of static constructors. + /// + /// Targets should implement a single global instance of this class (which + /// will be zero initialized), and pass that instance to the TargetRegistry as + /// part of their initialization. + class Target { + public: + friend struct TargetRegistry; + + typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT); + + typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, + StringRef TT); + typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, + Reloc::Model RM, + CodeModel::Model CM); + typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); + typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info); + typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT); + typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, + StringRef CPU, + StringRef Features); + typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, + StringRef TT, + StringRef CPU, + StringRef Features, + Reloc::Model RM, + CodeModel::Model CM); + typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, + MCStreamer &Streamer); + typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT); + typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T, + const MCRegisterInfo &MRI, + const MCAsmInfo &MAI); + typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, + MCAsmParser &P); + typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, + const MCSubtargetInfo &STI); + typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI); + typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx); + typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T, + StringRef TT, + MCContext &Ctx, + MCAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll, + bool NoExecStack); + typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, + formatted_raw_ostream &OS, + bool isVerboseAsm, + bool useLoc, + bool useCFI, + MCInstPrinter *InstPrint, + MCCodeEmitter *CE, + MCAsmBackend *TAB, + bool ShowInst); + + private: + /// Next - The next registered target in the linked list, maintained by the + /// TargetRegistry. + Target *Next; + + /// TripleMatchQualityFn - The target function for rating the match quality + /// of a triple. + TripleMatchQualityFnTy TripleMatchQualityFn; + + /// Name - The target name. + const char *Name; + + /// ShortDesc - A short description of the target. + const char *ShortDesc; + + /// HasJIT - Whether this target supports the JIT. + bool HasJIT; + + /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if + /// registered. + MCAsmInfoCtorFnTy MCAsmInfoCtorFn; + + /// MCCodeGenInfoCtorFn - Constructor function for this target's MCCodeGenInfo, + /// if registered. + MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn; + + /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, + /// if registered. + MCInstrInfoCtorFnTy MCInstrInfoCtorFn; + + /// MCInstrAnalysisCtorFn - Constructor function for this target's + /// MCInstrAnalysis, if registered. + MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn; + + /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, + /// if registered. + MCRegInfoCtorFnTy MCRegInfoCtorFn; + + /// MCSubtargetInfoCtorFn - Constructor function for this target's + /// MCSubtargetInfo, if registered. + MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; + + /// TargetMachineCtorFn - Construction function for this target's + /// TargetMachine, if registered. + TargetMachineCtorTy TargetMachineCtorFn; + + /// MCAsmBackendCtorFn - Construction function for this target's + /// MCAsmBackend, if registered. + MCAsmBackendCtorTy MCAsmBackendCtorFn; + + /// MCAsmLexerCtorFn - Construction function for this target's + /// MCTargetAsmLexer, if registered. + MCAsmLexerCtorTy MCAsmLexerCtorFn; + + /// MCAsmParserCtorFn - Construction function for this target's + /// MCTargetAsmParser, if registered. + MCAsmParserCtorTy MCAsmParserCtorFn; + + /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, + /// if registered. + AsmPrinterCtorTy AsmPrinterCtorFn; + + /// MCDisassemblerCtorFn - Construction function for this target's + /// MCDisassembler, if registered. + MCDisassemblerCtorTy MCDisassemblerCtorFn; + + /// MCInstPrinterCtorFn - Construction function for this target's + /// MCInstPrinter, if registered. + MCInstPrinterCtorTy MCInstPrinterCtorFn; + + /// MCCodeEmitterCtorFn - Construction function for this target's + /// CodeEmitter, if registered. + MCCodeEmitterCtorTy MCCodeEmitterCtorFn; + + /// MCObjectStreamerCtorFn - Construction function for this target's + /// MCObjectStreamer, if registered. + MCObjectStreamerCtorTy MCObjectStreamerCtorFn; + + /// AsmStreamerCtorFn - Construction function for this target's + /// AsmStreamer, if registered (default = llvm::createAsmStreamer). + AsmStreamerCtorTy AsmStreamerCtorFn; + + public: + Target() : AsmStreamerCtorFn(llvm::createAsmStreamer) {} + + /// @name Target Information + /// @{ + + // getNext - Return the next registered target. + const Target *getNext() const { return Next; } + + /// getName - Get the target name. + const char *getName() const { return Name; } + + /// getShortDescription - Get a short description of the target. + const char *getShortDescription() const { return ShortDesc; } + + /// @} + /// @name Feature Predicates + /// @{ + + /// hasJIT - Check if this targets supports the just-in-time compilation. + bool hasJIT() const { return HasJIT; } + + /// hasTargetMachine - Check if this target supports code generation. + bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } + + /// hasMCAsmBackend - Check if this target supports .o generation. + bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; } + + /// hasMCAsmLexer - Check if this target supports .s lexing. + bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; } + + /// hasAsmParser - Check if this target supports .s parsing. + bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; } + + /// hasAsmPrinter - Check if this target supports .s printing. + bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } + + /// hasMCDisassembler - Check if this target has a disassembler. + bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; } + + /// hasMCInstPrinter - Check if this target has an instruction printer. + bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; } + + /// hasMCCodeEmitter - Check if this target supports instruction encoding. + bool hasMCCodeEmitter() const { return MCCodeEmitterCtorFn != 0; } + + /// hasMCObjectStreamer - Check if this target supports streaming to files. + bool hasMCObjectStreamer() const { return MCObjectStreamerCtorFn != 0; } + + /// hasAsmStreamer - Check if this target supports streaming to files. + bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; } + + /// @} + /// @name Feature Constructors + /// @{ + + /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified + /// target triple. + /// + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. + MCAsmInfo *createMCAsmInfo(StringRef Triple) const { + if (!MCAsmInfoCtorFn) + return 0; + return MCAsmInfoCtorFn(*this, Triple); + } + + /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. + /// + MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM, + CodeModel::Model CM) const { + if (!MCCodeGenInfoCtorFn) + return 0; + return MCCodeGenInfoCtorFn(Triple, RM, CM); + } + + /// createMCInstrInfo - Create a MCInstrInfo implementation. + /// + MCInstrInfo *createMCInstrInfo() const { + if (!MCInstrInfoCtorFn) + return 0; + return MCInstrInfoCtorFn(); + } + + /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation. + /// + MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const { + if (!MCInstrAnalysisCtorFn) + return 0; + return MCInstrAnalysisCtorFn(Info); + } + + /// createMCRegInfo - Create a MCRegisterInfo implementation. + /// + MCRegisterInfo *createMCRegInfo(StringRef Triple) const { + if (!MCRegInfoCtorFn) + return 0; + return MCRegInfoCtorFn(Triple); + } + + /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. + /// + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. + /// \arg CPU - This specifies the name of the target CPU. + /// \arg Features - This specifies the string representation of the + /// additional target features. + MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU, + StringRef Features) const { + if (!MCSubtargetInfoCtorFn) + return 0; + return MCSubtargetInfoCtorFn(Triple, CPU, Features); + } + + /// createTargetMachine - Create a target specific machine implementation + /// for the specified \arg Triple. + /// + /// \arg Triple - This argument is used to determine the target machine + /// feature set; it should always be provided. Generally this should be + /// either the target triple from the module, or the target triple of the + /// host if that does not exist. + TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU, + StringRef Features, + Reloc::Model RM = Reloc::Default, + CodeModel::Model CM = CodeModel::Default) const { + if (!TargetMachineCtorFn) + return 0; + return TargetMachineCtorFn(*this, Triple, CPU, Features, RM, CM); + } + + /// createMCAsmBackend - Create a target specific assembly parser. + /// + /// \arg Triple - The target triple string. + /// \arg Backend - The target independent assembler object. + MCAsmBackend *createMCAsmBackend(StringRef Triple) const { + if (!MCAsmBackendCtorFn) + return 0; + return MCAsmBackendCtorFn(*this, Triple); + } + + /// createMCAsmLexer - Create a target specific assembly lexer. + /// + MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI, + const MCAsmInfo &MAI) const { + if (!MCAsmLexerCtorFn) + return 0; + return MCAsmLexerCtorFn(*this, MRI, MAI); + } + + /// createMCAsmParser - Create a target specific assembly parser. + /// + /// \arg Parser - The target independent parser implementation to use for + /// parsing and lexing. + MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, + MCAsmParser &Parser) const { + if (!MCAsmParserCtorFn) + return 0; + return MCAsmParserCtorFn(STI, Parser); + } + + /// createAsmPrinter - Create a target specific assembly printer pass. This + /// takes ownership of the MCStreamer object. + AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{ + if (!AsmPrinterCtorFn) + return 0; + return AsmPrinterCtorFn(TM, Streamer); + } + + MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const { + if (!MCDisassemblerCtorFn) + return 0; + return MCDisassemblerCtorFn(*this, STI); + } + + MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI) const { + if (!MCInstPrinterCtorFn) + return 0; + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, STI); + } + + + /// createMCCodeEmitter - Create a target specific code emitter. + MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx) const { + if (!MCCodeEmitterCtorFn) + return 0; + return MCCodeEmitterCtorFn(II, STI, Ctx); + } + + /// createMCObjectStreamer - Create a target specific MCStreamer. + /// + /// \arg TT - The target triple. + /// \arg Ctx - The target context. + /// \arg TAB - The target assembler backend object. Takes ownership. + /// \arg _OS - The stream object. + /// \arg _Emitter - The target independent assembler object.Takes ownership. + /// \arg RelaxAll - Relax all fixups? + /// \arg NoExecStack - Mark file as not needing a executable stack. + MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx, + MCAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll, + bool NoExecStack) const { + if (!MCObjectStreamerCtorFn) + return 0; + return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, + RelaxAll, NoExecStack); + } + + /// createAsmStreamer - Create a target specific MCStreamer. + MCStreamer *createAsmStreamer(MCContext &Ctx, + formatted_raw_ostream &OS, + bool isVerboseAsm, + bool useLoc, + bool useCFI, + MCInstPrinter *InstPrint, + MCCodeEmitter *CE, + MCAsmBackend *TAB, + bool ShowInst) const { + // AsmStreamerCtorFn is default to llvm::createAsmStreamer + return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI, + InstPrint, CE, TAB, ShowInst); + } + + /// @} + }; + + /// TargetRegistry - Generic interface to target specific features. + struct TargetRegistry { + class iterator { + const Target *Current; + explicit iterator(Target *T) : Current(T) {} + friend struct TargetRegistry; + public: + iterator(const iterator &I) : Current(I.Current) {} + iterator() : Current(0) {} + + bool operator==(const iterator &x) const { + return Current == x.Current; + } + bool operator!=(const iterator &x) const { + return !operator==(x); + } + + // Iterator traversal: forward iteration only + iterator &operator++() { // Preincrement + assert(Current && "Cannot increment end iterator!"); + Current = Current->getNext(); + return *this; + } + iterator operator++(int) { // Postincrement + iterator tmp = *this; + ++*this; + return tmp; + } + + const Target &operator*() const { + assert(Current && "Cannot dereference end iterator!"); + return *Current; + } + + const Target *operator->() const { + return &operator*(); + } + }; + + /// printRegisteredTargetsForVersion - Print the registered targets + /// appropriately for inclusion in a tool's version output. + static void printRegisteredTargetsForVersion(); + + /// @name Registry Access + /// @{ + + static iterator begin(); + + static iterator end() { return iterator(); } + + /// lookupTarget - Lookup a target based on a target triple. + /// + /// \param Triple - The triple to use for finding a target. + /// \param Error - On failure, an error string describing why no target was + /// found. + static const Target *lookupTarget(const std::string &Triple, + 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. + /// + /// Maintained for compatibility through 2.6. + static const Target *getClosestTargetForJIT(std::string &Error); + + /// @} + /// @name Target Registration + /// @{ + + /// RegisterTarget - Register the given target. Attempts to register a + /// target which has already been registered will be ignored. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Name - The target name. This should be a static string. + /// @param ShortDesc - A short target description. This should be a static + /// string. + /// @param TQualityFn - The triple match quality computation function for + /// this target. + /// @param HasJIT - Whether the target supports JIT code + /// generation. + static void RegisterTarget(Target &T, + const char *Name, + const char *ShortDesc, + Target::TripleMatchQualityFnTy TQualityFn, + bool HasJIT = false); + + /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCAsmInfo for the target. + static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCAsmInfoCtorFn) + T.MCAsmInfoCtorFn = Fn; + } + + /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCCodeGenInfo for the target. + static void RegisterMCCodeGenInfo(Target &T, + Target::MCCodeGenInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCCodeGenInfoCtorFn) + T.MCCodeGenInfoCtorFn = Fn; + } + + /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCInstrInfo for the target. + static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCInstrInfoCtorFn) + T.MCInstrInfoCtorFn = Fn; + } + + /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for + /// the given target. + static void RegisterMCInstrAnalysis(Target &T, + Target::MCInstrAnalysisCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCInstrAnalysisCtorFn) + T.MCInstrAnalysisCtorFn = Fn; + } + + /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCRegisterInfo for the target. + static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCRegInfoCtorFn) + T.MCRegInfoCtorFn = Fn; + } + + /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for + /// the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCSubtargetInfo for the target. + static void RegisterMCSubtargetInfo(Target &T, + Target::MCSubtargetInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCSubtargetInfoCtorFn) + T.MCSubtargetInfoCtorFn = Fn; + } + + /// RegisterTargetMachine - Register a TargetMachine implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a TargetMachine for the target. + static void RegisterTargetMachine(Target &T, + Target::TargetMachineCtorTy Fn) { + // Ignore duplicate registration. + if (!T.TargetMachineCtorFn) + T.TargetMachineCtorFn = Fn; + } + + /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an AsmBackend for the target. + static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { + if (!T.MCAsmBackendCtorFn) + T.MCAsmBackendCtorFn = Fn; + } + + /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCAsmLexer for the target. + static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) { + if (!T.MCAsmLexerCtorFn) + T.MCAsmLexerCtorFn = Fn; + } + + /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for + /// the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCTargetAsmParser for the target. + static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) { + if (!T.MCAsmParserCtorFn) + T.MCAsmParserCtorFn = Fn; + } + + /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given + /// target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an AsmPrinter for the target. + static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { + // Ignore duplicate registration. + if (!T.AsmPrinterCtorFn) + T.AsmPrinterCtorFn = Fn; + } + + /// RegisterMCDisassembler - Register a MCDisassembler implementation for + /// the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCDisassembler for the target. + static void RegisterMCDisassembler(Target &T, + Target::MCDisassemblerCtorTy Fn) { + if (!T.MCDisassemblerCtorFn) + T.MCDisassemblerCtorFn = Fn; + } + + /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCInstPrinter for the target. + static void RegisterMCInstPrinter(Target &T, + Target::MCInstPrinterCtorTy Fn) { + if (!T.MCInstPrinterCtorFn) + T.MCInstPrinterCtorFn = Fn; + } + + /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCCodeEmitter for the target. + static void RegisterMCCodeEmitter(Target &T, + Target::MCCodeEmitterCtorTy Fn) { + if (!T.MCCodeEmitterCtorFn) + T.MCCodeEmitterCtorFn = Fn; + } + + /// RegisterMCObjectStreamer - Register a object code MCStreamer + /// implementation for the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCStreamer for the target. + static void RegisterMCObjectStreamer(Target &T, + Target::MCObjectStreamerCtorTy Fn) { + if (!T.MCObjectStreamerCtorFn) + T.MCObjectStreamerCtorFn = Fn; + } + + /// RegisterAsmStreamer - Register an assembly MCStreamer implementation + /// for the given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct an MCStreamer for the target. + static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) { + if (T.AsmStreamerCtorFn == createAsmStreamer) + T.AsmStreamerCtorFn = Fn; + } + + /// @} + }; + + + //===--------------------------------------------------------------------===// + + /// RegisterTarget - Helper template for registering a target, for use in the + /// target's initialization function. Usage: + /// + /// + /// Target TheFooTarget; // The global target instance. + /// + /// extern "C" void LLVMInitializeFooTargetInfo() { + /// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description"); + /// } + template<Triple::ArchType TargetArchType = Triple::InvalidArch, + bool HasJIT = false> + struct RegisterTarget { + RegisterTarget(Target &T, const char *Name, const char *Desc) { + TargetRegistry::RegisterTarget(T, Name, Desc, + &getTripleMatchQuality, + HasJIT); + } + + static unsigned getTripleMatchQuality(const std::string &TT) { + if (Triple(TT).getArch() == TargetArchType) + return 20; + return 0; + } + }; + + /// RegisterMCAsmInfo - Helper template for registering a target assembly info + /// implementation. This invokes the static "Create" method on the class to + /// actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); + /// } + template<class MCAsmInfoImpl> + struct RegisterMCAsmInfo { + RegisterMCAsmInfo(Target &T) { + TargetRegistry::RegisterMCAsmInfo(T, &Allocator); + } + private: + static MCAsmInfo *Allocator(const Target &T, StringRef TT) { + return new MCAsmInfoImpl(T, TT); + } + + }; + + /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info + /// implementation. This invokes the specified function to do the + /// construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCAsmInfoFn { + RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCAsmInfo(T, Fn); + } + }; + + /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info + /// implementation. This invokes the static "Create" method on the class + /// to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget); + /// } + template<class MCCodeGenInfoImpl> + struct RegisterMCCodeGenInfo { + RegisterMCCodeGenInfo(Target &T) { + TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator); + } + private: + static MCCodeGenInfo *Allocator(StringRef TT, + Reloc::Model RM, CodeModel::Model CM) { + return new MCCodeGenInfoImpl(); + } + }; + + /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen + /// info implementation. This invokes the specified function to do the + /// construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCCodeGenInfoFn { + RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCCodeGenInfo(T, Fn); + } + }; + + /// RegisterMCInstrInfo - Helper template for registering a target instruction + /// info implementation. This invokes the static "Create" method on the class + /// to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); + /// } + template<class MCInstrInfoImpl> + struct RegisterMCInstrInfo { + RegisterMCInstrInfo(Target &T) { + TargetRegistry::RegisterMCInstrInfo(T, &Allocator); + } + private: + static MCInstrInfo *Allocator() { + return new MCInstrInfoImpl(); + } + }; + + /// RegisterMCInstrInfoFn - Helper template for registering a target + /// instruction info implementation. This invokes the specified function to + /// do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCInstrInfoFn { + RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCInstrInfo(T, Fn); + } + }; + + /// RegisterMCInstrAnalysis - Helper template for registering a target + /// instruction analyzer implementation. This invokes the static "Create" + /// method on the class to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget); + /// } + template<class MCInstrAnalysisImpl> + struct RegisterMCInstrAnalysis { + RegisterMCInstrAnalysis(Target &T) { + TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator); + } + private: + static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) { + return new MCInstrAnalysisImpl(Info); + } + }; + + /// RegisterMCInstrAnalysisFn - Helper template for registering a target + /// instruction analyzer implementation. This invokes the specified function + /// to do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCInstrAnalysisFn { + RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) { + TargetRegistry::RegisterMCInstrAnalysis(T, Fn); + } + }; + + /// RegisterMCRegInfo - Helper template for registering a target register info + /// implementation. This invokes the static "Create" method on the class to + /// actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); + /// } + template<class MCRegisterInfoImpl> + struct RegisterMCRegInfo { + RegisterMCRegInfo(Target &T) { + TargetRegistry::RegisterMCRegInfo(T, &Allocator); + } + private: + static MCRegisterInfo *Allocator(StringRef TT) { + return new MCRegisterInfoImpl(); + } + }; + + /// RegisterMCRegInfoFn - Helper template for registering a target register + /// info implementation. This invokes the specified function to do the + /// construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCRegInfoFn { + RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCRegInfo(T, Fn); + } + }; + + /// RegisterMCSubtargetInfo - Helper template for registering a target + /// subtarget info implementation. This invokes the static "Create" method + /// on the class to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); + /// } + template<class MCSubtargetInfoImpl> + struct RegisterMCSubtargetInfo { + RegisterMCSubtargetInfo(Target &T) { + TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); + } + private: + static MCSubtargetInfo *Allocator(StringRef TT, StringRef CPU, + StringRef FS) { + return new MCSubtargetInfoImpl(); + } + }; + + /// RegisterMCSubtargetInfoFn - Helper template for registering a target + /// subtarget info implementation. This invokes the specified function to + /// do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCSubtargetInfoFn { + RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCSubtargetInfo(T, Fn); + } + }; + + /// RegisterTargetMachine - Helper template for registering a target machine + /// implementation, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget); + /// } + template<class TargetMachineImpl> + struct RegisterTargetMachine { + RegisterTargetMachine(Target &T) { + TargetRegistry::RegisterTargetMachine(T, &Allocator); + } + + private: + static TargetMachine *Allocator(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, + Reloc::Model RM, + CodeModel::Model CM) { + return new TargetMachineImpl(T, TT, CPU, FS, RM, CM); + } + }; + + /// RegisterMCAsmBackend - Helper template for registering a target specific + /// assembler backend. Usage: + /// + /// extern "C" void LLVMInitializeFooMCAsmBackend() { + /// extern Target TheFooTarget; + /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget); + /// } + template<class MCAsmBackendImpl> + struct RegisterMCAsmBackend { + RegisterMCAsmBackend(Target &T) { + TargetRegistry::RegisterMCAsmBackend(T, &Allocator); + } + + private: + static MCAsmBackend *Allocator(const Target &T, StringRef Triple) { + return new MCAsmBackendImpl(T, Triple); + } + }; + + /// RegisterMCAsmLexer - Helper template for registering a target specific + /// assembly lexer, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooMCAsmLexer() { + /// extern Target TheFooTarget; + /// RegisterMCAsmLexer<FooMCAsmLexer> X(TheFooTarget); + /// } + template<class MCAsmLexerImpl> + struct RegisterMCAsmLexer { + RegisterMCAsmLexer(Target &T) { + TargetRegistry::RegisterMCAsmLexer(T, &Allocator); + } + + private: + static MCTargetAsmLexer *Allocator(const Target &T, + const MCRegisterInfo &MRI, + const MCAsmInfo &MAI) { + return new MCAsmLexerImpl(T, MRI, MAI); + } + }; + + /// RegisterMCAsmParser - Helper template for registering a target specific + /// assembly parser, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooMCAsmParser() { + /// extern Target TheFooTarget; + /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); + /// } + template<class MCAsmParserImpl> + struct RegisterMCAsmParser { + RegisterMCAsmParser(Target &T) { + TargetRegistry::RegisterMCAsmParser(T, &Allocator); + } + + private: + static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { + return new MCAsmParserImpl(STI, P); + } + }; + + /// RegisterAsmPrinter - Helper template for registering a target specific + /// assembly printer, for use in the target machine initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooAsmPrinter() { + /// extern Target TheFooTarget; + /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); + /// } + template<class AsmPrinterImpl> + struct RegisterAsmPrinter { + RegisterAsmPrinter(Target &T) { + TargetRegistry::RegisterAsmPrinter(T, &Allocator); + } + + private: + static AsmPrinter *Allocator(TargetMachine &TM, MCStreamer &Streamer) { + return new AsmPrinterImpl(TM, Streamer); + } + }; + + /// RegisterMCCodeEmitter - Helper template for registering a target specific + /// machine code emitter, for use in the target initialization + /// function. Usage: + /// + /// extern "C" void LLVMInitializeFooMCCodeEmitter() { + /// extern Target TheFooTarget; + /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget); + /// } + template<class MCCodeEmitterImpl> + struct RegisterMCCodeEmitter { + RegisterMCCodeEmitter(Target &T) { + TargetRegistry::RegisterMCCodeEmitter(T, &Allocator); + } + + private: + static MCCodeEmitter *Allocator(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx) { + return new MCCodeEmitterImpl(); + } + }; + +} + +#endif diff --git a/include/llvm/Support/TargetSelect.h b/include/llvm/Support/TargetSelect.h new file mode 100644 index 0000000..83ff68c --- /dev/null +++ b/include/llvm/Support/TargetSelect.h @@ -0,0 +1,154 @@ +//===- TargetSelect.h - Target Selection & Registration ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides utilities to make sure that certain classes of targets are +// linked into the main application executable, and initialize them as +// appropriate. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_TARGETSELECT_H +#define LLVM_SUPPORT_TARGETSELECT_H + +#include "llvm/Config/llvm-config.h" + +extern "C" { + // Declare all of the target-initialization functions that are available. +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo(); +#include "llvm/Config/Targets.def" + +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); +#include "llvm/Config/Targets.def" + + // Declare all of the target-MC-initialization functions that are available. +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC(); +#include "llvm/Config/Targets.def" + + // Declare all of the available assembly printer initialization functions. +#define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); +#include "llvm/Config/AsmPrinters.def" + + // Declare all of the available assembly parser initialization functions. +#define LLVM_ASM_PARSER(TargetName) void LLVMInitialize##TargetName##AsmParser(); +#include "llvm/Config/AsmParsers.def" + + // Declare all of the available disassembler initialization functions. +#define LLVM_DISASSEMBLER(TargetName) \ + void LLVMInitialize##TargetName##Disassembler(); +#include "llvm/Config/Disassemblers.def" +} + +namespace llvm { + /// InitializeAllTargetInfos - The main program should call this function if + /// it wants access to all available targets that LLVM is configured to + /// support, to make them available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllTargetInfos() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo(); +#include "llvm/Config/Targets.def" + } + + /// InitializeAllTargets - The main program should call this function if it + /// wants access to all available target machines that LLVM is configured to + /// support, to make them available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllTargets() { + // FIXME: Remove this, clients should do it. + InitializeAllTargetInfos(); + +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target(); +#include "llvm/Config/Targets.def" + } + + /// InitializeAllTargetMCs - The main program should call this function if it + /// wants access to all available target MC that LLVM is configured to + /// support, to make them available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllTargetMCs() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC(); +#include "llvm/Config/Targets.def" + } + + /// InitializeAllAsmPrinters - The main program should call this function if + /// it wants all asm printers that LLVM is configured to support, to make them + /// available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllAsmPrinters() { +#define LLVM_ASM_PRINTER(TargetName) LLVMInitialize##TargetName##AsmPrinter(); +#include "llvm/Config/AsmPrinters.def" + } + + /// InitializeAllAsmParsers - The main program should call this function if it + /// wants all asm parsers that LLVM is configured to support, to make them + /// available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllAsmParsers() { +#define LLVM_ASM_PARSER(TargetName) LLVMInitialize##TargetName##AsmParser(); +#include "llvm/Config/AsmParsers.def" + } + + /// InitializeAllDisassemblers - The main program should call this function if + /// it wants all disassemblers that LLVM is configured to support, to make + /// them available via the TargetRegistry. + /// + /// It is legal for a client to make multiple calls to this function. + inline void InitializeAllDisassemblers() { +#define LLVM_DISASSEMBLER(TargetName) LLVMInitialize##TargetName##Disassembler(); +#include "llvm/Config/Disassemblers.def" + } + + /// InitializeNativeTarget - The main program should call this function to + /// initialize the native target corresponding to the host. This is useful + /// for JIT applications to ensure that the target gets linked in correctly. + /// + /// It is legal for a client to make multiple calls to this function. + inline bool InitializeNativeTarget() { + // If we have a native target, initialize it to ensure it is linked in. +#ifdef LLVM_NATIVE_TARGET + LLVM_NATIVE_TARGETINFO(); + LLVM_NATIVE_TARGET(); + LLVM_NATIVE_TARGETMC(); + return false; +#else + return true; +#endif + } + + /// InitializeNativeTargetAsmPrinter - The main program should call + /// this function to initialize the native target asm printer. + inline bool InitializeNativeTargetAsmPrinter() { + // If we have a native target, initialize the corresponding asm printer. +#ifdef LLVM_NATIVE_ASMPRINTER + LLVM_NATIVE_ASMPRINTER(); + return false; +#else + return true; +#endif + } + + /// InitializeNativeTargetAsmParser - The main program should call + /// this function to initialize the native target asm parser. + inline bool InitializeNativeTargetAsmParser() { + // If we have a native target, initialize the corresponding asm parser. +#ifdef LLVM_NATIVE_ASMPARSER + LLVM_NATIVE_ASMPARSER(); + return false; +#else + return true; +#endif + } + +} + +#endif diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index 1800778..c756069 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -18,7 +18,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" #include <limits.h> -#include <vector> namespace llvm { @@ -254,9 +253,9 @@ public: template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(1); - params.push_back(TypeBuilder<A1, cross>::get(Context)); + Type *params[] = { + TypeBuilder<A1, cross>::get(Context), + }; return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, false); } @@ -265,10 +264,10 @@ template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(2); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); + Type *params[] = { + TypeBuilder<A1, cross>::get(Context), + TypeBuilder<A2, cross>::get(Context), + }; return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, false); } @@ -277,11 +276,11 @@ template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(3); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(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); } @@ -292,12 +291,12 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(4); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(Context)); - params.push_back(TypeBuilder<A4, cross>::get(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); } @@ -308,13 +307,13 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(5); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(Context)); - params.push_back(TypeBuilder<A4, cross>::get(Context)); - params.push_back(TypeBuilder<A5, cross>::get(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); } @@ -330,9 +329,9 @@ template<typename R, typename A1, bool cross> class TypeBuilder<R(A1, ...), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(1); - params.push_back(TypeBuilder<A1, cross>::get(Context)); + Type *params[] = { + TypeBuilder<A1, cross>::get(Context), + }; return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); } }; @@ -340,10 +339,10 @@ template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2, ...), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(2); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); + Type *params[] = { + TypeBuilder<A1, cross>::get(Context), + TypeBuilder<A2, cross>::get(Context), + }; return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true); } @@ -352,11 +351,11 @@ template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3, ...), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(3); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(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); } @@ -367,12 +366,12 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(4); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(Context)); - params.push_back(TypeBuilder<A4, cross>::get(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); } @@ -383,13 +382,13 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { public: static FunctionType *get(LLVMContext &Context) { - std::vector<Type*> params; - params.reserve(5); - params.push_back(TypeBuilder<A1, cross>::get(Context)); - params.push_back(TypeBuilder<A2, cross>::get(Context)); - params.push_back(TypeBuilder<A3, cross>::get(Context)); - params.push_back(TypeBuilder<A4, cross>::get(Context)); - params.push_back(TypeBuilder<A5, cross>::get(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); } |