diff options
author | dim <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 |
commit | 2b066988909948dc3d53d01760bc2d71d32f3feb (patch) | |
tree | fc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /include | |
parent | c80ac9d286b8fcc6d1ee5d76048134cf80aa9edc (diff) | |
download | FreeBSD-src-2b066988909948dc3d53d01760bc2d71d32f3feb.zip FreeBSD-src-2b066988909948dc3d53d01760bc2d71d32f3feb.tar.gz |
Vendor import of llvm trunk r130700:
http://llvm.org/svn/llvm-project/llvm/trunk@130700
Diffstat (limited to 'include')
167 files changed, 2792 insertions, 1212 deletions
diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h new file mode 100644 index 0000000..9f10973 --- /dev/null +++ b/include/llvm-c/Disassembler.h @@ -0,0 +1,149 @@ +/*===-- llvm-c/Disassembler.h - Disassembler Public C Interface ---*- 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 public interface to a disassembler library. *| +|* LLVM provides an implementation of this interface. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_DISASSEMBLER_H +#define LLVM_C_DISASSEMBLER_H 1 + +#include <stddef.h> +#include "llvm/Support/DataTypes.h" + +/** + * An opaque reference to a disassembler context. + */ +typedef void *LLVMDisasmContextRef; + +/** + * The type for the operand information call back function. This is called to + * get the symbolic information for an operand of an instruction. Typically + * this is from the relocation information, symbol table, etc. That block of + * information is saved when the disassembler context is created and passed to + * the call back in the DisInfo parameter. The instruction containing operand + * is at the PC parameter. For some instruction sets, there can be more than + * one operand with symbolic information. To determine the symbolic operand + * information for each operand, the bytes for the specific operand in the + * instruction are specified by the Offset parameter and its byte widith is the + * size parameter. For instructions sets with fixed widths and one symbolic + * operand per instruction, the Offset parameter will be zero and Size parameter + * will be the instruction width. The information is returned in TagBuf and is + * Triple specific with its specific information defined by the value of + * TagType for that Triple. If symbolic information is returned the function + * returns 1 else it returns 0. + */ +typedef int (*LLVMOpInfoCallback)(void *DisInfo, + uint64_t PC, + uint64_t Offset, + uint64_t Size, + int TagType, + void *TagBuf); + +/** + * The initial support in LLVM MC for the most general form of a relocatable + * expression is "AddSymbol - SubtractSymbol + Offset". For some Darwin targets + * this full form is encoded in the relocation information so that AddSymbol and + * SubtractSymbol can be link edited independent of each other. Many other + * platforms only allow a relocatable expression of the form AddSymbol + Offset + * to be encoded. + * + * The LLVMOpInfoCallback() for the TagType value of 1 uses the struct + * LLVMOpInfo1. The value of the relocatable expression for the operand, + * including any PC adjustment, is passed in to the call back in the Value + * field. The symbolic information about the operand is returned using all + * the fields of the structure with the Offset of the relocatable expression + * returned in the Value field. It is possible that some symbols in the + * relocatable expression were assembly temporary symbols, for example + * "Ldata - LpicBase + constant", and only the Values of the symbols without + * symbol names are present in the relocation information. The VariantKind + * type is one of the Target specific #defines below and is used to print + * operands like "_foo@GOT", ":lower16:_foo", etc. + */ +struct LLVMOpInfoSymbol1 { + uint64_t Present; /* 1 if this symbol is present */ + char *Name; /* symbol name if not NULL */ + uint64_t Value; /* symbol value if name is NULL */ +}; +struct LLVMOpInfo1 { + struct LLVMOpInfoSymbol1 AddSymbol; + struct LLVMOpInfoSymbol1 SubtractSymbol; + uint64_t Value; + uint64_t VariantKind; +}; + +/** + * The operand VariantKinds for symbolic disassembly. + */ +#define LLVMDisassembler_VariantKind_None 0 /* all targets */ + +/** + * The ARM target VariantKinds. + */ +#define LLVMDisassembler_VariantKind_ARM_HI16 1 /* :upper16: */ +#define LLVMDisassembler_VariantKind_ARM_LO16 2 /* :lower16: */ + +/** + * The type for the symbol lookup function. This may be called by the + * disassembler for such things like adding a comment for a PC plus a constant + * offset load instruction to use a symbol name instead of a load address value. + * It is passed the block information is saved when the disassembler context is + * created and a value of a symbol to look up. If no symbol is found NULL is + * to be returned. + */ +typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo, + uint64_t SymbolValue); + +#ifdef __cplusplus +extern "C" { +#endif /* !defined(__cplusplus) */ + +/** + * Create a disassembler for the TripleName. Symbolic disassembly is supported + * by passing a block of information in the DisInfo parameter and specifing the + * TagType and call back functions as described above. These can all be passed + * as NULL. If successful this returns a disassembler context if not it + * returns NULL. + */ +extern LLVMDisasmContextRef +LLVMCreateDisasm(const char *TripleName, + void *DisInfo, + int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp); + +/** + * Dispose of a disassembler context. + */ +extern void +LLVMDisasmDispose(LLVMDisasmContextRef DC); + +/** + * Disassmble a single instruction using the disassembler context specified in + * the parameter DC. The bytes of the instruction are specified in the parameter + * Bytes, and contains at least BytesSize number of bytes. The instruction is + * at the address specified by the PC parameter. If a valid instruction can be + * disassembled its string is returned indirectly in OutString which whos size + * is specified in the parameter OutStringSize. This function returns the + * number of bytes in the instruction or zero if there was no valid instruction. + */ +extern size_t +LLVMDisasmInstruction(LLVMDisasmContextRef DC, + uint8_t *Bytes, + uint64_t BytesSize, + uint64_t PC, + char *OutString, + size_t OutStringSize); + +#ifdef __cplusplus +} +#endif /* !defined(__cplusplus) */ + +#endif /* !defined(LLVM_C_DISASSEMBLER_H) */ diff --git a/include/llvm-c/EnhancedDisassembly.h b/include/llvm-c/EnhancedDisassembly.h index 28ac0ed..0c173c2 100644 --- a/include/llvm-c/EnhancedDisassembly.h +++ b/include/llvm-c/EnhancedDisassembly.h @@ -44,7 +44,7 @@ typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg); @param arg An anonymous argument for client use. @result 0 if the register could be read; -1 otherwise. */ -typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID, +typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID, void* arg); /*! @@ -83,7 +83,7 @@ typedef void *EDTokenRef; Encapsulates an operand of an instruction. */ typedef void *EDOperandRef; - + /*! @functiongroup Getting a disassembler */ @@ -91,7 +91,7 @@ typedef void *EDOperandRef; /*! @function EDGetDisassembler Gets the disassembler for a given target. - @param disassembler A pointer whose target will be filled in with the + @param disassembler A pointer whose target will be filled in with the disassembler. @param triple Identifies the target. Example: "x86_64-apple-darwin10" @param syntax The assembly syntax to use when decoding instructions. @@ -104,12 +104,12 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler, /*! @functiongroup Generic architectural queries */ - + /*! @function EDGetRegisterName Gets the human-readable name for a given register. @param regName A pointer whose target will be pointed at the name of the - register. The name does not need to be deallocated and will be + register. The name does not need to be deallocated and will be @param disassembler The disassembler to query for the name. @param regID The register identifier, as returned by EDRegisterTokenValue. @result 0 on success; -1 otherwise. @@ -117,7 +117,7 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler, int EDGetRegisterName(const char** regName, EDDisassemblerRef disassembler, unsigned regID); - + /*! @function EDRegisterIsStackPointer Determines if a register is one of the platform's stack-pointer registers. @@ -137,16 +137,16 @@ int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, */ int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, unsigned regID); - + /*! @functiongroup Creating and querying instructions */ - + /*! @function EDCreateInst Gets a set of contiguous instructions from a disassembler. @param insts A pointer to an array that will be filled in with the - instructions. Must have at least count entries. Entries not filled in will + instructions. Must have at least count entries. Entries not filled in will be set to NULL. @param count The maximum number of instructions to fill in. @param disassembler The disassembler to use when decoding the instructions. @@ -197,7 +197,7 @@ int EDGetInstString(const char **buf, @result 0 on success; -1 otherwise. */ int EDInstID(unsigned *instID, EDInstRef inst); - + /*! @function EDInstIsBranch @param inst The instruction to be queried. @@ -217,7 +217,7 @@ int EDInstIsMove(EDInstRef inst); /*! @function EDBranchTargetID @param inst The instruction to be queried. - @result The ID of the branch target operand, suitable for use with + @result The ID of the branch target operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDBranchTargetID(EDInstRef inst); @@ -225,7 +225,7 @@ int EDBranchTargetID(EDInstRef inst); /*! @function EDMoveSourceID @param inst The instruction to be queried. - @result The ID of the move source operand, suitable for use with + @result The ID of the move source operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDMoveSourceID(EDInstRef inst); @@ -233,7 +233,7 @@ int EDMoveSourceID(EDInstRef inst); /*! @function EDMoveTargetID @param inst The instruction to be queried. - @result The ID of the move source operand, suitable for use with + @result The ID of the move source operand, suitable for use with EDCopyOperand. -1 if no such operand exists. */ int EDMoveTargetID(EDInstRef inst); @@ -241,7 +241,7 @@ int EDMoveTargetID(EDInstRef inst); /*! @functiongroup Creating and querying tokens */ - + /*! @function EDNumTokens @param inst The instruction to be queried. @@ -261,7 +261,7 @@ int EDNumTokens(EDInstRef inst); int EDGetToken(EDTokenRef *token, EDInstRef inst, int index); - + /*! @function EDGetTokenString Gets the disassembled text for a token. @@ -287,7 +287,7 @@ int EDOperandIndexForToken(EDTokenRef token); @result 1 if the token is whitespace; 0 if not; -1 on error. */ int EDTokenIsWhitespace(EDTokenRef token); - + /*! @function EDTokenIsPunctuation @param token The token to be queried. @@ -335,18 +335,18 @@ int EDLiteralTokenAbsoluteValue(uint64_t *value, /*! @function EDRegisterTokenValue - @param registerID A pointer whose target will be filled in with the LLVM + @param registerID A pointer whose target will be filled in with the LLVM register identifier for the token. @param token The token to be queried. @result 0 on success; -1 otherwise. */ int EDRegisterTokenValue(unsigned *registerID, EDTokenRef token); - + /*! @functiongroup Creating and querying operands */ - + /*! @function EDNumOperands @param inst The instruction to be queried. @@ -366,7 +366,7 @@ int EDNumOperands(EDInstRef inst); int EDGetOperand(EDOperandRef *operand, EDInstRef inst, int index); - + /*! @function EDOperandIsRegister @param operand The operand to be queried. @@ -391,13 +391,13 @@ int EDOperandIsMemory(EDOperandRef operand); /*! @function EDRegisterOperandValue @param value A pointer whose target will be filled in with the LLVM register ID - of the register named by the operand. + of the register named by the operand. @param operand The operand to be queried. @result 0 on success; -1 otherwise. */ int EDRegisterOperandValue(unsigned *value, EDOperandRef operand); - + /*! @function EDImmediateOperandValue @param value A pointer whose target will be filled in with the value of the @@ -427,7 +427,7 @@ int EDEvaluateOperand(uint64_t *result, EDOperandRef operand, EDRegisterReaderCallback regReader, void *arg); - + #ifdef __BLOCKS__ /*! @@ -458,13 +458,13 @@ typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID); typedef int (^EDTokenVisitor_t)(EDTokenRef token); /*! @functiongroup Block-based interfaces */ - + /*! @function EDBlockCreateInsts Gets a set of contiguous instructions from a disassembler, using a block to read memory. @param insts A pointer to an array that will be filled in with the - instructions. Must have at least count entries. Entries not filled in will + instructions. Must have at least count entries. Entries not filled in will be set to NULL. @param count The maximum number of instructions to fill in. @param disassembler The disassembler to use when decoding the instructions. @@ -505,7 +505,7 @@ int EDBlockVisitTokens(EDInstRef inst, EDTokenVisitor_t visitor); #endif - + #ifdef __cplusplus } #endif diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h new file mode 100644 index 0000000..6e72b59 --- /dev/null +++ b/include/llvm-c/Object.h @@ -0,0 +1,77 @@ +/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/ +/* */ +/* The LLVM Compiler Infrastructure */ +/* */ +/* This file is distributed under the University of Illinois Open Source */ +/* License. See LICENSE.TXT for details. */ +/* */ +/*===----------------------------------------------------------------------===*/ +/* */ +/* This header declares the C interface to libLLVMObject.a, which */ +/* implements object file reading and writing. */ +/* */ +/* Many exotic languages can interoperate with C code but have a harder time */ +/* with C++ due to name mangling. So in addition to C, this interface enables */ +/* tools written in such languages. */ +/* */ +/*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_OBJECT_H +#define LLVM_C_OBJECT_H + +#include "llvm-c/Core.h" +#include "llvm/Config/llvm-config.h" + +#ifdef __cplusplus +#include "llvm/Object/ObjectFile.h" + +extern "C" { +#endif + + +typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef; + +typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef; + +LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf); +void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile); + +LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile); +void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI); +LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, + LLVMSectionIteratorRef SI); +void LLVMMoveToNextSection(LLVMSectionIteratorRef SI); +const char *LLVMGetSectionName(LLVMSectionIteratorRef SI); +uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI); +const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI); + + +#ifdef __cplusplus +} + +namespace llvm { + namespace object { + inline ObjectFile *unwrap(LLVMObjectFileRef OF) { + return reinterpret_cast<ObjectFile*>(OF); + } + + inline LLVMObjectFileRef wrap(const ObjectFile *OF) { + return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF)); + } + + inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) { + return reinterpret_cast<ObjectFile::section_iterator*>(SI); + } + + inline LLVMSectionIteratorRef + wrap(const ObjectFile::section_iterator *SI) { + return reinterpret_cast<LLVMSectionIteratorRef> + (const_cast<ObjectFile::section_iterator*>(SI)); + } + } +} + +#endif /* defined(__cplusplus) */ + +#endif + diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h index 2ddfb38..cf8d71f 100644 --- a/include/llvm-c/Transforms/Scalar.h +++ b/include/llvm-c/Transforms/Scalar.h @@ -52,6 +52,9 @@ void LLVMAddLICMPass(LLVMPassManagerRef PM); /** See llvm::createLoopDeletionPass function. */ void LLVMAddLoopDeletionPass(LLVMPassManagerRef PM); +/** See llvm::createLoopIdiomPass function */ +void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM); + /** See llvm::createLoopRotatePass function. */ void LLVMAddLoopRotatePass(LLVMPassManagerRef PM); @@ -77,6 +80,9 @@ void LLVMAddSCCPPass(LLVMPassManagerRef PM); void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM); /** See llvm::createScalarReplAggregatesPass function. */ +void LLVMAddScalarReplAggregatesPassSSA(LLVMPassManagerRef PM); + +/** See llvm::createScalarReplAggregatesPass function. */ void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef PM, int Threshold); @@ -95,6 +101,19 @@ void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef PM); /** See llvm::createVerifierPass function. */ void LLVMAddVerifierPass(LLVMPassManagerRef PM); +/** See llvm::createCorrelatedValuePropagationPass function */ +void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM); + +/** See llvm::createEarlyCSEPass function */ +void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM); + +/** See llvm::createTypeBasedAliasAnalysisPass function */ +void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM); + +/** See llvm::createBasicAliasAnalysisPass function */ +void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM); + + #ifdef __cplusplus } #endif /* defined(__cplusplus) */ diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 1c42ce0..7ea7ad0 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -72,7 +72,7 @@ lto_get_version(void); /** - * Returns the last error string or NULL if last operation was sucessful. + * Returns the last error string or NULL if last operation was successful. */ extern const char* lto_get_error_message(void); @@ -127,7 +127,15 @@ lto_module_create_from_memory(const void* mem, size_t length); * Returns NULL on error (check lto_get_error_message() for details). */ extern lto_module_t -lto_module_create_from_fd(int fd, const char *path, off_t size); +lto_module_create_from_fd(int fd, const char *path, size_t file_size); + +/** + * Loads an object file from disk. The seek point of fd is not preserved. + * Returns NULL on error (check lto_get_error_message() for details). + */ +extern lto_module_t +lto_module_create_from_fd_at_offset(int fd, const char *path, size_t file_size, + size_t map_size, off_t offset); /** @@ -255,7 +263,7 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path); /** * Generates code for all added modules into one native object file. - * On sucess returns a pointer to a generated mach-o/ELF buffer and + * On success returns a pointer to a generated mach-o/ELF buffer and * length set to the buffer size. The buffer is owned by the * lto_code_gen_t and will be freed when lto_codegen_dispose() * is called, or lto_codegen_compile() is called again. @@ -264,6 +272,13 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path); extern const void* lto_codegen_compile(lto_code_gen_t cg, size_t* length); +/** + * Generates code for all added modules into one native object file. + * The name of the file is written to name. Returns true on error. + */ +extern bool +lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); + /** * Sets options to help debug codegen bugs. diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index ca4138b..21b8c86 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -353,6 +353,10 @@ namespace llvm { unsigned FormatPrecision = 0, unsigned FormatMaxPadding = 3) const; + /// getExactInverse - If this value has an exact multiplicative inverse, + /// store it in inv and return true. + bool getExactInverse(APFloat *inv) const; + private: /* Trivial queries. */ diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index d1fd3e5..2feef07 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -818,6 +818,7 @@ public: APInt usub_ov(const APInt &RHS, bool &Overflow) const; APInt sdiv_ov(const APInt &RHS, bool &Overflow) const; APInt smul_ov(const APInt &RHS, bool &Overflow) const; + APInt umul_ov(const APInt &RHS, bool &Overflow) const; APInt sshl_ov(unsigned Amt, bool &Overflow) const; /// @returns the bit value at bitPosition @@ -1372,7 +1373,7 @@ public: /// Calculate the magic number for unsigned division by a constant. struct mu; - mu magicu() const; + mu magicu(unsigned LeadingZeros = 0) const; /// @} /// @name Building-block Operations for APInt and APFloat diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index d3ea9c0..97e42cb 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -22,8 +22,8 @@ namespace llvm { /// /// This class does not own the underlying data, it is expected to be used in /// situations where the data resides in some other buffer, whose lifetime - /// extends past that of the StringRef. For this reason, it is not in general - /// safe to store a ArrayRef. + /// extends past that of the ArrayRef. For this reason, it is not in general + /// safe to store an ArrayRef. /// /// This is intended to be trivially copyable, so it should be passed by /// value. @@ -79,6 +79,8 @@ namespace llvm { /// empty - Check if the array is empty. bool empty() const { return Length == 0; } + const T *data() const { return Data; } + /// size - Get the array size. size_t size() const { return Length; } @@ -94,10 +96,22 @@ namespace llvm { return Data[Length-1]; } + /// slice(n) - Chop off the first N elements of the array. + ArrayRef<T> slice(unsigned N) { + assert(N <= size() && "Invalid specifier"); + return ArrayRef<T>(data()+N, size()-N); + } + + /// slice(n, m) - Chop off the first N elements of the array, and keep M + /// elements in the array. + ArrayRef<T> slice(unsigned N, unsigned M) { + assert(N+M <= size() && "Invalid specifier"); + return ArrayRef<T>(data()+N, M); + } + /// @} /// @name Operator Overloads /// @{ - const T &operator[](size_t Index) const { assert(Index < Length && "Invalid index!"); return Data[Index]; @@ -106,7 +120,6 @@ namespace llvm { /// @} /// @name Expensive Operations /// @{ - std::vector<T> vec() const { return std::vector<T>(Data, Data+Length); } diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 61d6ae7..0f1cfeb 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -53,13 +53,13 @@ public: CopyFrom(other); } - explicit DenseMap(unsigned NumInitBuckets = 64) { + explicit DenseMap(unsigned NumInitBuckets = 0) { init(NumInitBuckets); } template<typename InputIt> DenseMap(const InputIt &I, const InputIt &E) { - init(64); + init(NextPowerOf2(std::distance(I, E))); insert(I, E); } @@ -72,7 +72,8 @@ public: P->first.~KeyT(); } #ifndef NDEBUG - memset(Buckets, 0x5a, sizeof(BucketT)*NumBuckets); + if (NumBuckets) + memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets); #endif operator delete(Buckets); } @@ -98,7 +99,10 @@ public: unsigned size() const { return NumEntries; } /// Grow the densemap so that it has at least Size buckets. Does not shrink - void resize(size_t Size) { grow(Size); } + void resize(size_t Size) { + if (Size > NumBuckets) + grow(Size); + } void clear() { if (NumEntries == 0 && NumTombstones == 0) return; @@ -248,23 +252,29 @@ private: if (NumBuckets) { #ifndef NDEBUG - memset(Buckets, 0x5a, sizeof(BucketT)*NumBuckets); + memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets); #endif operator delete(Buckets); } - Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * - other.NumBuckets)); + + NumBuckets = other.NumBuckets; + + if (NumBuckets == 0) { + Buckets = 0; + return; + } + + Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets)); if (isPodLike<KeyInfoT>::value && isPodLike<ValueInfoT>::value) - memcpy(Buckets, other.Buckets, other.NumBuckets * sizeof(BucketT)); + memcpy(Buckets, other.Buckets, NumBuckets * sizeof(BucketT)); else - for (size_t i = 0; i < other.NumBuckets; ++i) { + for (size_t i = 0; i < NumBuckets; ++i) { new (&Buckets[i].first) KeyT(other.Buckets[i].first); if (!KeyInfoT::isEqual(Buckets[i].first, getEmptyKey()) && !KeyInfoT::isEqual(Buckets[i].first, getTombstoneKey())) new (&Buckets[i].second) ValueT(other.Buckets[i].second); } - NumBuckets = other.NumBuckets; } BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value, @@ -279,11 +289,14 @@ private: // table completely filled with tombstones, no lookup would ever succeed, // causing infinite loops in lookup. ++NumEntries; - if (NumEntries*4 >= NumBuckets*3 || - NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { + if (NumEntries*4 >= NumBuckets*3) { this->grow(NumBuckets * 2); LookupBucketFor(Key, TheBucket); } + if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) { + this->grow(NumBuckets); + LookupBucketFor(Key, TheBucket); + } // If we are writing over a tombstone, remember this. if (!KeyInfoT::isEqual(TheBucket->first, getEmptyKey())) @@ -313,6 +326,11 @@ private: unsigned ProbeAmt = 1; BucketT *BucketsPtr = Buckets; + if (NumBuckets == 0) { + FoundBucket = 0; + return false; + } + // FoundTombstone - Keep track of whether we find a tombstone while probing. BucketT *FoundTombstone = 0; const KeyT EmptyKey = getEmptyKey(); @@ -354,6 +372,12 @@ private: NumEntries = 0; NumTombstones = 0; NumBuckets = InitBuckets; + + if (InitBuckets == 0) { + Buckets = 0; + return; + } + assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 && "# initial buckets must be a power of two!"); Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets)); @@ -367,6 +391,9 @@ private: unsigned OldNumBuckets = NumBuckets; BucketT *OldBuckets = Buckets; + if (NumBuckets < 64) + NumBuckets = 64; + // Double the number of buckets. while (NumBuckets < AtLeast) NumBuckets <<= 1; @@ -398,7 +425,8 @@ private: } #ifndef NDEBUG - memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); + if (OldNumBuckets) + memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); #endif // Free the old table. operator delete(OldBuckets); @@ -431,13 +459,22 @@ private: } #ifndef NDEBUG - memset(OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); + memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets); #endif // Free the old table. operator delete(OldBuckets); NumEntries = 0; } + +public: + /// Return the approximate size (in bytes) of the actual map. + /// This is just the raw memory used by DenseMap. + /// If entries are pointers to objects, the size of the referenced objects + /// are not included. + size_t getMemorySize() const { + return NumBuckets * sizeof(BucketT); + } }; template<typename KeyT, typename ValueT, diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 25e341b..744b6f4 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -157,7 +157,10 @@ struct DenseMapInfo<std::pair<T, U> > { key ^= (key >> 31); return (unsigned)key; } - static bool isEqual(const Pair& LHS, const Pair& RHS) { return LHS == RHS; } + static bool isEqual(const Pair &LHS, const Pair &RHS) { + return FirstInfo::isEqual(LHS.first, RHS.first) && + SecondInfo::isEqual(LHS.second, RHS.second); + } }; } // end namespace llvm diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index b9e5cbd..dd13a2c 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -143,8 +143,7 @@ public: static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); } inline bool operator==(const _Self& x) const { - return VisitStack.size() == x.VisitStack.size() && - VisitStack == x.VisitStack; + return VisitStack == x.VisitStack; } inline bool operator!=(const _Self& x) const { return !operator==(x); } diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index 879dbd0..52e0434 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -209,10 +209,10 @@ template<typename T> struct FoldingSetTrait; /// for FoldingSetTrait implementations. /// template<typename T> struct DefaultFoldingSetTrait { - static void Profile(const T& X, FoldingSetNodeID& ID) { + static void Profile(const T &X, FoldingSetNodeID &ID) { X.Profile(ID); } - static void Profile(T& X, FoldingSetNodeID& ID) { + static void Profile(T &X, FoldingSetNodeID &ID) { X.Profile(ID); } @@ -267,7 +267,7 @@ template<typename T, typename Ctx> struct ContextualFoldingSetTrait /// is often much larger than necessary, and the possibility of heap /// allocation means it requires a non-trivial destructor call. class FoldingSetNodeIDRef { - const unsigned* Data; + const unsigned *Data; size_t Size; public: FoldingSetNodeIDRef() : Data(0), Size(0) {} @@ -310,9 +310,10 @@ public: void AddInteger(unsigned long long I); void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); } void AddString(StringRef String); + void AddNodeID(const FoldingSetNodeID &ID); template <typename T> - inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); } + inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); } /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID /// object to be used to compute a new profile. @@ -548,7 +549,7 @@ public: return static_cast<T*>(NodePtr); } - inline FoldingSetIterator& operator++() { // Preincrement + inline FoldingSetIterator &operator++() { // Preincrement advance(); return *this; } @@ -596,10 +597,10 @@ public: FoldingSetBucketIterator(void **Bucket, bool) : FoldingSetBucketIteratorImpl(Bucket, true) {} - T& operator*() const { return *static_cast<T*>(Ptr); } - T* operator->() const { return static_cast<T*>(Ptr); } + T &operator*() const { return *static_cast<T*>(Ptr); } + T *operator->() const { return static_cast<T*>(Ptr); } - inline FoldingSetBucketIterator& operator++() { // Preincrement + inline FoldingSetBucketIterator &operator++() { // Preincrement advance(); return *this; } @@ -615,36 +616,36 @@ template <typename T> class FoldingSetNodeWrapper : public FoldingSetNode { T data; public: - explicit FoldingSetNodeWrapper(const T& x) : data(x) {} + explicit FoldingSetNodeWrapper(const T &x) : data(x) {} virtual ~FoldingSetNodeWrapper() {} template<typename A1> - explicit FoldingSetNodeWrapper(const A1& a1) + explicit FoldingSetNodeWrapper(const A1 &a1) : data(a1) {} template <typename A1, typename A2> - explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2) + explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2) : data(a1,a2) {} template <typename A1, typename A2, typename A3> - explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3) + explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3) : data(a1,a2,a3) {} template <typename A1, typename A2, typename A3, typename A4> - explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, - const A4& a4) + explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3, + const A4 &a4) : data(a1,a2,a3,a4) {} template <typename A1, typename A2, typename A3, typename A4, typename A5> - explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3, - const A4& a4, const A5& a5) + explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3, + const A4 &a4, const A5 &a5) : data(a1,a2,a3,a4,a5) {} - void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); } + void Profile(FoldingSetNodeID &ID) { FoldingSetTrait<T>::Profile(data, ID); } - T& getValue() { return data; } - const T& getValue() const { return data; } + T &getValue() { return data; } + const T &getValue() const { return data; } operator T&() { return data; } operator const T&() const { return data; } @@ -661,20 +662,22 @@ class FastFoldingSetNode : public FoldingSetNode { protected: explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {} public: - void Profile(FoldingSetNodeID& ID) const { ID = FastID; } + void Profile(FoldingSetNodeID &ID) const { + ID.AddNodeID(FastID); + } }; //===----------------------------------------------------------------------===// // Partial specializations of FoldingSetTrait. template<typename T> struct FoldingSetTrait<T*> { - static inline void Profile(const T* X, FoldingSetNodeID& ID) { + static inline void Profile(const T *X, FoldingSetNodeID &ID) { ID.AddPointer(X); } }; template<typename T> struct FoldingSetTrait<const T*> { - static inline void Profile(const T* X, FoldingSetNodeID& ID) { + static inline void Profile(const T *X, FoldingSetNodeID &ID) { ID.AddPointer(X); } }; diff --git a/include/llvm/ADT/ImmutableIntervalMap.h b/include/llvm/ADT/ImmutableIntervalMap.h index 0d8fcf3..fa7ccb9 100644 --- a/include/llvm/ADT/ImmutableIntervalMap.h +++ b/include/llvm/ADT/ImmutableIntervalMap.h @@ -10,6 +10,10 @@ // This file defines the ImmutableIntervalMap class. // //===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H +#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H + #include "llvm/ADT/ImmutableMap.h" namespace llvm { @@ -240,3 +244,5 @@ private: }; } // end namespace llvm + +#endif diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 79f24d3..f28ebf3 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -1328,6 +1328,10 @@ public: /// const_iterator - Create an iterator that isn't pointing anywhere. const_iterator() : map(0) {} + /// setMap - Change the map iterated over. This call must be followed by a + /// call to goToBegin(), goToEnd(), or find() + void setMap(const IntervalMap &m) { map = const_cast<IntervalMap*>(&m); } + /// valid - Return true if the current position is valid, false for end(). bool valid() const { return path.valid(); } diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 37d4ac9..2f6fd2b 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -42,18 +42,16 @@ namespace llvm { //===----------------------------------------------------------------------===// template <class Derived> class RefCountedBase { - unsigned ref_cnt; + mutable unsigned ref_cnt; - protected: + public: RefCountedBase() : ref_cnt(0) {} - void Retain() { ++ref_cnt; } - void Release() { + void Retain() const { ++ref_cnt; } + void Release() const { assert (ref_cnt > 0 && "Reference count is already zero."); - if (--ref_cnt == 0) delete static_cast<Derived*>(this); + if (--ref_cnt == 0) delete static_cast<const Derived*>(this); } - - friend class IntrusiveRefCntPtr<Derived>; }; //===----------------------------------------------------------------------===// @@ -64,21 +62,21 @@ namespace llvm { /// inherit from RefCountedBaseVPTR can't be allocated on stack - /// attempting to do this will produce a compile error. //===----------------------------------------------------------------------===// - template <class Derived> class RefCountedBaseVPTR { - unsigned ref_cnt; + mutable unsigned ref_cnt; protected: RefCountedBaseVPTR() : ref_cnt(0) {} virtual ~RefCountedBaseVPTR() {} - void Retain() { ++ref_cnt; } - void Release() { + void Retain() const { ++ref_cnt; } + void Release() const { assert (ref_cnt > 0 && "Reference count is already zero."); if (--ref_cnt == 0) delete this; } - friend class IntrusiveRefCntPtr<Derived>; + template <typename T> + friend class IntrusiveRefCntPtr; }; //===----------------------------------------------------------------------===// @@ -155,6 +153,10 @@ namespace llvm { other.Obj = Obj; Obj = tmp; } + + void resetWithoutRelease() { + Obj = 0; + } private: void retain() { if (Obj) Obj->Retain(); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 61de042..13b98ce 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -19,16 +19,33 @@ namespace llvm { - /// getPointerUnionTypeNum - If the argument has type PT1* or PT2* return - /// false or true respectively. - template <typename PT1, typename PT2> - static inline int getPointerUnionTypeNum(PT1 *P) { return 0; } - template <typename PT1, typename PT2> - static inline int getPointerUnionTypeNum(PT2 *P) { return 1; } - template <typename PT1, typename PT2> - static inline int getPointerUnionTypeNum(...) { return -1; } - - + template <typename T> + struct PointerUnionTypeSelectorReturn { + typedef T Return; + }; + + /// \brief Get a type based on whether two types are the same or not. For: + /// @code + /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret; + /// @endcode + /// Ret will be EQ type if T1 is same as T2 or NE type otherwise. + template <typename T1, typename T2, typename RET_EQ, typename RET_NE> + struct PointerUnionTypeSelector { + typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return; + }; + + template <typename T, typename RET_EQ, typename RET_NE> + struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> { + typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return; + }; + + template <typename T1, typename T2, typename RET_EQ, typename RET_NE> + struct PointerUnionTypeSelectorReturn< + PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > { + typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return + Return; + }; + /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion /// for the two template arguments. template <typename PT1, typename PT2> @@ -65,6 +82,16 @@ namespace llvm { PointerUnionUIntTraits<PT1,PT2> > ValTy; private: ValTy Val; + + struct IsPT1 { + static const int Num = 0; + }; + struct IsPT2 { + static const int Num = 1; + }; + template <typename T> + struct UNION_DOESNT_CONTAIN_TYPE { }; + public: PointerUnion() {} @@ -87,8 +114,11 @@ namespace llvm { /// is<T>() return true if the Union currently holds the type matching T. template<typename T> int is() const { - int TyNo = ::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0); - assert(TyNo != -1 && "Type query could never succeed on PointerUnion!"); + typedef typename + ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1, + ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2, + UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty; + int TyNo = Ty::Num; return static_cast<int>(Val.getInt()) == TyNo; } @@ -175,6 +205,34 @@ namespace llvm { typedef PointerUnion<InnerUnion, PT3> ValTy; private: ValTy Val; + + struct IsInnerUnion { + ValTy Val; + IsInnerUnion(ValTy val) : Val(val) { } + template<typename T> + int is() const { + return Val.template is<InnerUnion>() && + Val.template get<InnerUnion>().template is<T>(); + } + template<typename T> + T get() const { + return Val.template get<InnerUnion>().template get<T>(); + } + }; + + struct IsPT3 { + ValTy Val; + IsPT3(ValTy val) : Val(val) { } + template<typename T> + int is() const { + return Val.template is<T>(); + } + template<typename T> + T get() const { + return Val.template get<T>(); + } + }; + public: PointerUnion3() {} @@ -196,11 +254,12 @@ namespace llvm { /// is<T>() return true if the Union currently holds the type matching T. template<typename T> int is() const { - // Is it PT1/PT2? - if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) - return Val.template is<InnerUnion>() && - Val.template get<InnerUnion>().template is<T>(); - return Val.template is<T>(); + // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. + typedef typename + ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion, + ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 > + >::Return Ty; + return Ty(Val).is<T>(); } /// get<T>() - Return the value of the specified pointer type. If the @@ -208,11 +267,12 @@ namespace llvm { template<typename T> T get() const { assert(is<T>() && "Invalid accessor called"); - // Is it PT1/PT2? - if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) - return Val.template get<InnerUnion>().template get<T>(); - - return Val.template get<T>(); + // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. + typedef typename + ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion, + ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 > + >::Return Ty; + return Ty(Val).get<T>(); } /// dyn_cast<T>() - If the current value is of the specified pointer type, @@ -302,12 +362,13 @@ namespace llvm { /// is<T>() return true if the Union currently holds the type matching T. template<typename T> int is() const { - // Is it PT1/PT2? - if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) - return Val.template is<InnerUnion1>() && - Val.template get<InnerUnion1>().template is<T>(); - return Val.template is<InnerUnion2>() && - Val.template get<InnerUnion2>().template is<T>(); + // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. + typedef typename + ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1, + ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 > + >::Return Ty; + return Val.template is<Ty>() && + Val.template get<Ty>().template is<T>(); } /// get<T>() - Return the value of the specified pointer type. If the @@ -315,11 +376,12 @@ namespace llvm { template<typename T> T get() const { assert(is<T>() && "Invalid accessor called"); - // Is it PT1/PT2? - if (::llvm::getPointerUnionTypeNum<PT1, PT2>((T*)0) != -1) - return Val.template get<InnerUnion1>().template get<T>(); - - return Val.template get<InnerUnion2>().template get<T>(); + // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. + typedef typename + ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1, + ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 > + >::Return Ty; + return Val.template get<Ty>().template get<T>(); } /// dyn_cast<T>() - If the current value is of the specified pointer type, diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index af3c482..a6803ee 100644 --- a/include/llvm/ADT/ScopedHashTable.h +++ b/include/llvm/ADT/ScopedHashTable.h @@ -96,6 +96,9 @@ public: ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT); ~ScopedHashTableScope(); + ScopedHashTableScope *getParentScope() { return PrevScope; } + const ScopedHashTableScope *getParentScope() const { return PrevScope; } + private: friend class ScopedHashTable<K, V, KInfo, AllocatorTy>; ScopedHashTableVal<K, V> *getLastValInScope() { @@ -141,9 +144,14 @@ public: template <typename K, typename V, typename KInfo, typename AllocatorTy> class ScopedHashTable { +public: + /// ScopeTy - This is a helpful typedef that allows clients to get easy access + /// to the name of the scope for this hash table. + typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy; +private: typedef ScopedHashTableVal<K, V> ValTy; DenseMap<K, ValTy*, KInfo> TopLevelMap; - ScopedHashTableScope<K, V, KInfo, AllocatorTy> *CurScope; + ScopeTy *CurScope; AllocatorTy Allocator; @@ -157,9 +165,6 @@ public: assert(CurScope == 0 && TopLevelMap.empty() && "Scope imbalance!"); } - /// ScopeTy - This is a helpful typedef that allows clients to get easy access - /// to the name of the scope for this hash table. - typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy; /// Access to the allocator. typedef typename ReferenceAdder<AllocatorTy>::result AllocatorRefTy; @@ -180,13 +185,7 @@ public: } void insert(const K &Key, const V &Val) { - assert(CurScope && "No scope active!"); - - ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key]; - - KeyEntry = ValTy::Create(CurScope->getLastValInScope(), KeyEntry, Key, Val, - Allocator); - CurScope->setLastValInScope(KeyEntry); + insertIntoScope(CurScope, Key, Val); } typedef ScopedHashTableIterator<K, V, KInfo> iterator; @@ -199,6 +198,21 @@ public: if (I == TopLevelMap.end()) return end(); return iterator(I->second); } + + ScopeTy *getCurScope() { return CurScope; } + const ScopeTy *getCurScope() const { return CurScope; } + + /// insertIntoScope - This inserts the specified key/value at the specified + /// (possibly not the current) scope. While it is ok to insert into a scope + /// that isn't the current one, it isn't ok to insert *underneath* an existing + /// value of the specified key. + void insertIntoScope(ScopeTy *S, const K &Key, const V &Val) { + assert(S && "No scope active!"); + ScopedHashTableVal<K, V> *&KeyEntry = TopLevelMap[Key]; + KeyEntry = ValTy::Create(S->getLastValInScope(), KeyEntry, Key, Val, + Allocator); + S->setLastValInScope(KeyEntry); + } }; /// ScopedHashTableScope ctor - Install this as the current scope for the hash diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index ff32ba8..9992858 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -133,7 +133,7 @@ private: void shrink_and_clear(); /// Grow - Allocate a larger backing store for the buckets and move it over. - void Grow(); + void Grow(unsigned NewSize); void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT. protected: diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index f137ea2..fda99c6 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -121,6 +121,9 @@ protected: /// \brief Enable the collection and printing of statistics. void EnableStatistics(); +/// \brief Check if statistics are enabled. +bool AreStatisticsEnabled(); + /// \brief Print statistics to the file returned by CreateInfoOutputFile(). void PrintStatistics(); diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index acbed66..5f5c041 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -20,7 +20,6 @@ #include <cctype> #include <cstdio> #include <string> -#include <vector> namespace llvm { template<typename T> class SmallVectorImpl; @@ -153,7 +152,7 @@ void SplitString(StringRef Source, SmallVectorImpl<StringRef> &OutFragments, StringRef Delimiters = " \t\n\v\f\r"); -/// HashString - Hash funtion for strings. +/// HashString - Hash function for strings. /// /// This is the Bernstein hash function. // diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index bad0e6f..934cacc 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -17,7 +17,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include <cstring> -#include <string> namespace llvm { template<typename ValueT> @@ -81,16 +80,6 @@ protected: StringMapImpl(unsigned InitSize, unsigned ItemSize); void RehashTable(); - /// ShouldRehash - Return true if the table should be rehashed after a new - /// element was recently inserted. - bool ShouldRehash() const { - // If the hash table is now more than 3/4 full, or if fewer than 1/8 of - // the buckets are empty (meaning that many are filled with tombstones), - // grow the table. - return NumItems*4 > NumBuckets*3 || - NumBuckets-(NumItems+NumTombstones) < NumBuckets/8; - } - /// LookupBucketFor - Look up the bucket that the specified string should end /// up in. If it already exists as a key in the map, the Item pointer for the /// specified bucket will be non-null. Otherwise, it will be null. In either @@ -339,9 +328,9 @@ public: --NumTombstones; Bucket.Item = KeyValue; ++NumItems; + assert(NumItems + NumTombstones <= NumBuckets); - if (ShouldRehash()) - RehashTable(); + RehashTable(); return true; } @@ -359,6 +348,7 @@ public: } NumItems = 0; + NumTombstones = 0; } /// GetOrCreateValue - Look up the specified key in the table. If a value @@ -378,13 +368,13 @@ public: if (Bucket.Item == getTombstoneVal()) --NumTombstones; ++NumItems; + assert(NumItems + NumTombstones <= NumBuckets); // Fill in the bucket for the hash table. The FullHashValue was already // filled in by LookupBucketFor. Bucket.Item = NewItem; - if (ShouldRehash()) - RehashTable(); + RehashTable(); return *NewItem; } diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index e6dcc23..2659bce 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -64,7 +64,8 @@ public: x86_64, // X86-64: amd64, x86_64 xcore, // XCore: xcore mblaze, // MBlaze: mblaze - ptx, // PTX: ptx + ptx32, // PTX: ptx (32-bit) + ptx64, // PTX: ptx (64-bit) InvalidArch }; @@ -72,7 +73,8 @@ public: UnknownVendor, Apple, - PC + PC, + SCEI }; enum OSType { UnknownOS, @@ -82,8 +84,10 @@ public: Darwin, DragonFly, FreeBSD, + IOS, Linux, Lv2, // PS3 + MacOSX, MinGW32, // i*86-pc-mingw32, *-w64-mingw32 NetBSD, OpenBSD, @@ -221,21 +225,81 @@ public: /// if the environment component is present). StringRef getOSAndEnvironmentName() const; + /// getOSNumber - Parse the version number from the OS name component of the + /// triple, if present. + /// + /// For example, "fooos1.2.3" would return (1, 2, 3). + /// + /// If an entry is not defined, it will be returned as 0. + void getOSVersion(unsigned &Major, unsigned &Minor, unsigned &Micro) const; - /// getDarwinNumber - Parse the 'darwin number' out of the specific target - /// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is - /// not defined, return 0's. This requires that the triple have an OSType of - /// darwin before it is called. - void getDarwinNumber(unsigned &Maj, unsigned &Min, unsigned &Revision) const; - - /// getDarwinMajorNumber - Return just the major version number, this is + /// getOSMajorVersion - Return just the major version number, this is /// specialized because it is a common query. - unsigned getDarwinMajorNumber() const { - unsigned Maj, Min, Rev; - getDarwinNumber(Maj, Min, Rev); + unsigned getOSMajorVersion() const { + unsigned Maj, Min, Micro; + getDarwinNumber(Maj, Min, Micro); return Maj; } + void getDarwinNumber(unsigned &Major, unsigned &Minor, + unsigned &Micro) const { + return getOSVersion(Major, Minor, Micro); + } + + unsigned getDarwinMajorNumber() const { + return getOSMajorVersion(); + } + + /// isOSVersionLT - Helper function for doing comparisons against version + /// numbers included in the target triple. + bool isOSVersionLT(unsigned Major, unsigned Minor = 0, + unsigned Micro = 0) const { + unsigned LHS[3]; + getOSVersion(LHS[0], LHS[1], LHS[2]); + + if (LHS[0] != Major) + return LHS[0] < Major; + if (LHS[1] != Minor) + return LHS[1] < Minor; + if (LHS[2] != Micro) + return LHS[1] < Micro; + + return false; + } + + /// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both + /// "darwin" and "osx" as OS X triples. + bool isMacOSX() const { + return getOS() == Triple::Darwin || getOS() == Triple::MacOSX; + } + + /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS). + bool isOSDarwin() const { + return isMacOSX() ||getOS() == Triple::IOS; + } + + /// isOSWindows - Is this a "Windows" OS. + bool isOSWindows() const { + return getOS() == Triple::Win32 || getOS() == Triple::Cygwin || + getOS() == Triple::MinGW32; + } + + /// isMacOSXVersionLT - Comparison function for checking OS X version + /// compatibility, which handles supporting skewed version numbering schemes + /// used by the "darwin" triples. + unsigned isMacOSXVersionLT(unsigned Major, unsigned Minor = 0, + unsigned Micro = 0) const { + assert(isMacOSX() && "Not an OS X triple!"); + + // If this is OS X, expect a sane version number. + if (getOS() == Triple::MacOSX) + return isOSVersionLT(Major, Minor, Micro); + + // Otherwise, compare to the "Darwin" number. + assert(Major == 10 && "Unexpected major version"); + return isOSVersionLT(Minor + 4, Micro, 0); + } + /// @} /// @name Mutators /// @{ diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 865fcb3..bcacfd9 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -289,7 +289,7 @@ template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { //===----------------------------------------------------------------------===// // /// iplist - The subset of list functionality that can safely be used on nodes -/// of polymorphic types, i.e. a heterogenous list with a common base class that +/// of polymorphic types, i.e. a heterogeneous list with a common base class that /// holds the next/prev pointers. The only state of the list itself is a single /// pointer to the head of the list. /// diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 71a5982..8f9708b 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -38,7 +38,6 @@ #define LLVM_ANALYSIS_ALIAS_ANALYSIS_H #include "llvm/Support/CallSite.h" -#include <vector> namespace llvm { diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index e844d10..03149c6 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -259,6 +259,7 @@ private: if (CallSites[i] == CS.getInstruction()) { CallSites[i] = CallSites.back(); CallSites.pop_back(); + --i; --e; // Revisit the moved entry. } } void setVolatile() { Volatile = true; } @@ -283,6 +284,7 @@ class AliasSetTracker { class ASTCallbackVH : public CallbackVH { AliasSetTracker *AST; virtual void deleted(); + virtual void allUsesReplacedWith(Value *); public: ASTCallbackVH(Value *V, AliasSetTracker *AST = 0); ASTCallbackVH &operator=(Value *V); diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h index ac8f596..61614e3 100644 --- a/include/llvm/Analysis/CFGPrinter.h +++ b/include/llvm/Analysis/CFGPrinter.h @@ -15,6 +15,7 @@ #ifndef LLVM_ANALYSIS_CFGPRINTER_H #define LLVM_ANALYSIS_CFGPRINTER_H +#include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Instructions.h" #include "llvm/Assembly/Writer.h" diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index 417dbc4..5846dbf 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -16,6 +16,7 @@ #define LLVM_ANALYSIS_DIBUILDER_H #include "llvm/Support/DataTypes.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" namespace llvm { @@ -146,6 +147,30 @@ namespace llvm { uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty); + /// createObjCIVar - Create debugging information entry for Objective-C + /// instance variable. + /// @param Name Member name. + /// @param File File where this member is defined. + /// @param LineNo Line number. + /// @param SizeInBits Member size. + /// @param AlignInBits Member alignment. + /// @param OffsetInBits Member offset. + /// @param Flags Flags to encode member attribute, e.g. private + /// @param Ty Parent type. + /// @param PropertyName Name of the Objective C property assoicated with + /// this ivar. + /// @param GetterName Name of the Objective C property getter selector. + /// @param SetterName Name of the Objective C property setter selector. + /// @param PropertyAttributes Objective C property attributes. + DIType createObjCIVar(StringRef Name, DIFile File, + unsigned LineNo, uint64_t SizeInBits, + uint64_t AlignInBits, uint64_t OffsetInBits, + unsigned Flags, DIType Ty, + StringRef PropertyName = StringRef(), + StringRef PropertyGetterName = StringRef(), + StringRef PropertySetterName = StringRef(), + unsigned PropertyAttributes = 0); + /// createClassType - Create debugging information entry for a class. /// @param Scope Scope in which this class is defined. /// @param Name class name. @@ -278,7 +303,7 @@ namespace llvm { DIDescriptor createUnspecifiedParameter(); /// getOrCreateArray - Get a DIArray, create one if required. - DIArray getOrCreateArray(Value *const *Elements, unsigned NumElements); + DIArray getOrCreateArray(ArrayRef<Value *> Elements); /// getOrCreateSubrange - Create a descriptor for a value range. This /// implicitly uniques the values returned. @@ -326,11 +351,14 @@ namespace llvm { /// @param AlwaysPreserve Boolean. Set to true if debug info for this /// variable should be preserved in optimized build. /// @param Flags Flags, e.g. artificial variable. + /// @param ArgNo If this variable is an arugment then this argument's + /// number. 1 indicates 1st argument. DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo, DIType Ty, bool AlwaysPreserve = false, - unsigned Flags = 0); + unsigned Flags = 0, + unsigned ArgNo = 0); /// createComplexVariable - Create a new descriptor for the specified @@ -342,12 +370,13 @@ namespace llvm { /// @param File File where this variable is defined. /// @param LineNo Line number. /// @param Ty Variable Type - /// @param Addr A pointer to a vector of complex address operations. - /// @param NumAddr Num of address operations in the vector. + /// @param Addr An array of complex address operations. + /// @param ArgNo If this variable is an arugment then this argument's + /// number. 1 indicates 1st argument. DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile F, unsigned LineNo, - DIType Ty, Value *const *Addr, - unsigned NumAddr); + DIType Ty, ArrayRef<Value *> Addr, + unsigned ArgNo = 0); /// createFunction - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. @@ -363,6 +392,7 @@ namespace llvm { /// This flags are used to emit dwarf attributes. /// @param isOptimized True if optimization is ON. /// @param Fn llvm::Function pointer. + /// @param TParam Function template parameters. DISubprogram createFunction(DIDescriptor Scope, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, @@ -370,7 +400,9 @@ namespace llvm { bool isDefinition, unsigned Flags = 0, bool isOptimized = false, - Function *Fn = 0); + Function *Fn = 0, + MDNode *TParam = 0, + MDNode *Decl = 0); /// createMethod - Create a new descriptor for the specified C++ method. /// See comments in DISubprogram for descriptions of these fields. @@ -382,7 +414,7 @@ namespace llvm { /// @param Ty Function type. /// @param isLocalToUnit True if this function is not externally visible.. /// @param isDefinition True if this is a function definition. - /// @param Virtuality Attributes describing virutallness. e.g. pure + /// @param Virtuality Attributes describing virtualness. e.g. pure /// virtual function. /// @param VTableIndex Index no of this method in virtual table. /// @param VTableHolder Type that holds vtable. @@ -390,6 +422,7 @@ namespace llvm { /// This flags are used to emit dwarf attributes. /// @param isOptimized True if optimization is ON. /// @param Fn llvm::Function pointer. + /// @param TParam Function template parameters. DISubprogram createMethod(DIDescriptor Scope, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, @@ -399,7 +432,8 @@ namespace llvm { MDNode *VTableHolder = 0, unsigned Flags = 0, bool isOptimized = false, - Function *Fn = 0); + Function *Fn = 0, + MDNode *TParam = 0); /// createNameSpace - This creates new descriptor for a namespace /// with the specified parent scope. diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index aa69088..c6cc8f7 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -332,6 +332,32 @@ namespace llvm { /// return base type size. uint64_t getOriginalTypeSize() const; + StringRef getObjCPropertyName() const { return getStringField(10); } + StringRef getObjCPropertyGetterName() const { + return getStringField(11); + } + StringRef getObjCPropertySetterName() const { + return getStringField(12); + } + bool isReadOnlyObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readonly) != 0; + } + bool isReadWriteObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0; + } + bool isAssignObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_assign) != 0; + } + bool isRetainObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_retain) != 0; + } + bool isCopyObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_copy) != 0; + } + bool isNonAtomicObjCProperty() { + return (getUnsignedField(13) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0; + } + /// Verify - Verify that a derived type descriptor is well formed. bool Verify() const; @@ -511,6 +537,10 @@ namespace llvm { bool describes(const Function *F); Function *getFunction() const { return getFunctionField(16); } + DIArray getTemplateParams() const { return getFieldAs<DIArray>(17); } + DISubprogram getFunctionDeclaration() const { + return getFieldAs<DISubprogram>(18); + } }; /// DIGlobalVariable - This is a wrapper for a global variable. @@ -564,7 +594,13 @@ namespace llvm { DIFile F = getFieldAs<DIFile>(3); return F.getCompileUnit(); } - unsigned getLineNumber() const { return getUnsignedField(4); } + unsigned getLineNumber() const { + return (getUnsignedField(4) << 8) >> 8; + } + unsigned getArgNumber() const { + unsigned L = getUnsignedField(4); + return L >> 24; + } DIType getType() const { return getFieldAs<DIType>(5); } /// isArtificial - Return true if this variable is marked as "artificial". @@ -586,7 +622,9 @@ namespace llvm { unsigned getNumAddrElements() const; uint64_t getAddrElement(unsigned Idx) const { - return getUInt64Field(Idx+6); + if (getVersion() <= llvm::LLVMDebugVersion8) + return getUInt64Field(Idx+6); + return getUInt64Field(Idx+7); } /// isBlockByrefVariable - Return true if the variable was declared as @@ -660,214 +698,6 @@ namespace llvm { bool Verify() const; }; - /// DIFactory - This object assists with the construction of the various - /// descriptors. - class DIFactory { - Module &M; - LLVMContext& VMContext; - - Function *DeclareFn; // llvm.dbg.declare - Function *ValueFn; // llvm.dbg.value - - DIFactory(const DIFactory &); // DO NOT IMPLEMENT - void operator=(const DIFactory&); // DO NOT IMPLEMENT - public: - enum ComplexAddrKind { OpPlus=1, OpDeref }; - - explicit DIFactory(Module &m); - - /// GetOrCreateArray - Create an descriptor for an array of descriptors. - /// This implicitly uniques the arrays created. - DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys); - - /// GetOrCreateSubrange - Create a descriptor for a value range. This - /// implicitly uniques the values returned. - DISubrange GetOrCreateSubrange(int64_t Lo, int64_t Hi); - - /// CreateUnspecifiedParameter - Create unspeicified type descriptor - /// for a subroutine type. - DIDescriptor CreateUnspecifiedParameter(); - - /// CreateCompileUnit - Create a new descriptor for the specified compile - /// unit. - DICompileUnit CreateCompileUnit(unsigned LangID, - StringRef Filename, - StringRef Directory, - StringRef Producer, - bool isMain = false, - bool isOptimized = false, - StringRef Flags = "", - unsigned RunTimeVer = 0); - - /// CreateFile - Create a new descriptor for the specified file. - DIFile CreateFile(StringRef Filename, StringRef Directory, - DICompileUnit CU); - - /// CreateEnumerator - Create a single enumerator value. - DIEnumerator CreateEnumerator(StringRef Name, uint64_t Val); - - /// CreateBasicType - Create a basic type like int, float, etc. - DIBasicType CreateBasicType(DIDescriptor Context, StringRef Name, - DIFile F, unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - unsigned Encoding); - - /// CreateBasicType - Create a basic type like int, float, etc. - DIBasicType CreateBasicTypeEx(DIDescriptor Context, StringRef Name, - DIFile F, unsigned LineNumber, - Constant *SizeInBits, Constant *AlignInBits, - Constant *OffsetInBits, unsigned Flags, - unsigned Encoding); - - /// CreateDerivedType - Create a derived type like const qualified type, - /// pointer, typedef, etc. - DIDerivedType CreateDerivedType(unsigned Tag, DIDescriptor Context, - StringRef Name, - DIFile F, - unsigned LineNumber, - uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType DerivedFrom); - - /// CreateDerivedType - Create a derived type like const qualified type, - /// pointer, typedef, etc. - DIDerivedType CreateDerivedTypeEx(unsigned Tag, DIDescriptor Context, - StringRef Name, - DIFile F, - unsigned LineNumber, - Constant *SizeInBits, - Constant *AlignInBits, - Constant *OffsetInBits, unsigned Flags, - DIType DerivedFrom); - - /// CreateCompositeType - Create a composite type like array, struct, etc. - DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context, - StringRef Name, - DIFile F, - unsigned LineNumber, - uint64_t SizeInBits, - uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, - DIType DerivedFrom, - DIArray Elements, - unsigned RunTimeLang = 0, - MDNode *ContainingType = 0); - - /// CreateTemporaryType - Create a temporary forward-declared type. - DIType CreateTemporaryType(); - DIType CreateTemporaryType(DIFile F); - - /// CreateArtificialType - Create a new DIType with "artificial" flag set. - DIType CreateArtificialType(DIType Ty); - - /// CreateCompositeType - Create a composite type like array, struct, etc. - DICompositeType CreateCompositeTypeEx(unsigned Tag, DIDescriptor Context, - StringRef Name, - DIFile F, - unsigned LineNumber, - Constant *SizeInBits, - Constant *AlignInBits, - Constant *OffsetInBits, - unsigned Flags, - DIType DerivedFrom, - DIArray Elements, - unsigned RunTimeLang = 0, - MDNode *ContainingType = 0); - - /// CreateSubprogram - Create a new descriptor for the specified subprogram. - /// See comments in DISubprogram for descriptions of these fields. - DISubprogram CreateSubprogram(DIDescriptor Context, StringRef Name, - StringRef DisplayName, - StringRef LinkageName, - DIFile F, unsigned LineNo, - DIType Ty, bool isLocalToUnit, - bool isDefinition, - unsigned VK = 0, - unsigned VIndex = 0, - DIType ContainingType = DIType(), - unsigned Flags = 0, - bool isOptimized = false, - Function *Fn = 0); - - /// CreateSubprogramDefinition - Create new subprogram descriptor for the - /// given declaration. - DISubprogram CreateSubprogramDefinition(DISubprogram &SPDeclaration); - - /// CreateGlobalVariable - Create a new descriptor for the specified global. - DIGlobalVariable - CreateGlobalVariable(DIDescriptor Context, StringRef Name, - StringRef DisplayName, - StringRef LinkageName, - DIFile F, - unsigned LineNo, DIType Ty, bool isLocalToUnit, - bool isDefinition, llvm::GlobalVariable *GV); - - /// CreateGlobalVariable - Create a new descriptor for the specified constant. - DIGlobalVariable - CreateGlobalVariable(DIDescriptor Context, StringRef Name, - StringRef DisplayName, - StringRef LinkageName, - DIFile F, - unsigned LineNo, DIType Ty, bool isLocalToUnit, - bool isDefinition, llvm::Constant *C); - - /// CreateVariable - Create a new descriptor for the specified variable. - DIVariable CreateVariable(unsigned Tag, DIDescriptor Context, - StringRef Name, - DIFile F, unsigned LineNo, - DIType Ty, bool AlwaysPreserve = false, - unsigned Flags = 0); - - /// CreateComplexVariable - Create a new descriptor for the specified - /// variable which has a complex address expression for its address. - DIVariable CreateComplexVariable(unsigned Tag, DIDescriptor Context, - StringRef Name, DIFile F, unsigned LineNo, - DIType Ty, Value *const *Addr, - unsigned NumAddr); - - /// CreateLexicalBlock - This creates a descriptor for a lexical block - /// with the specified parent context. - DILexicalBlock CreateLexicalBlock(DIDescriptor Context, DIFile F, - unsigned Line = 0, unsigned Col = 0); - - /// CreateNameSpace - This creates new descriptor for a namespace - /// with the specified parent context. - DINameSpace CreateNameSpace(DIDescriptor Context, StringRef Name, - DIFile F, unsigned LineNo); - - /// CreateLocation - Creates a debug info location. - DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo, - DIScope S, DILocation OrigLoc); - - /// CreateLocation - Creates a debug info location. - DILocation CreateLocation(unsigned LineNo, unsigned ColumnNo, - DIScope S, MDNode *OrigLoc = 0); - - /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. - Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, - BasicBlock *InsertAtEnd); - - /// InsertDeclare - Insert a new llvm.dbg.declare intrinsic call. - Instruction *InsertDeclare(llvm::Value *Storage, DIVariable D, - Instruction *InsertBefore); - - /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset, - DIVariable D, BasicBlock *InsertAtEnd); - - /// InsertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. - Instruction *InsertDbgValueIntrinsic(llvm::Value *V, uint64_t Offset, - DIVariable D, Instruction *InsertBefore); - - // RecordType - Record DIType in a module such that it is not lost even if - // it is not referenced through debug info anchors. - void RecordType(DIType T); - - private: - Constant *GetTagConstant(unsigned TAG); - }; - /// getDISubprogram - Find subprogram that is enclosing this scope. DISubprogram getDISubprogram(const MDNode *Scope); diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index 578e6ab..e56d24d 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -28,6 +28,7 @@ class IVUsers; class ScalarEvolution; class SCEV; class IVUsers; +class TargetData; /// IVStrideUse - Keep track of one use of a strided induction variable. /// The Expr member keeps track of the expression, User is the actual user @@ -122,6 +123,7 @@ class IVUsers : public LoopPass { LoopInfo *LI; DominatorTree *DT; ScalarEvolution *SE; + TargetData *TD; SmallPtrSet<Instruction*,16> Processed; /// IVUses - A list of all tracked IV uses of induction variable expressions diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index b08bf57..a0cce51 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -43,7 +43,7 @@ namespace llvm { /// InlineCost - Represent the cost of inlining a function. This /// supports special values for functions which should "always" or /// "never" be inlined. Otherwise, the cost represents a unitless - /// amount; smaller values increase the likelyhood of the function + /// amount; smaller values increase the likelihood of the function /// being inlined. class InlineCost { enum Kind { diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index dff1ba2..bc6e55f 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -55,6 +55,21 @@ namespace llvm { Value *SimplifyFDivInst(Value *LHS, Value *RHS, const TargetData *TD = 0, const DominatorTree *DT = 0); + /// SimplifySRemInst - Given operands for an SRem, see if we can + /// fold the result. If not, this returns null. + Value *SimplifySRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); + + /// SimplifyURemInst - Given operands for a URem, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyURemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); + + /// SimplifyFRemInst - Given operands for an FRem, see if we can + /// fold the result. If not, this returns null. + Value *SimplifyFRemInst(Value *LHS, Value *RHS, const TargetData *TD = 0, + const DominatorTree *DT = 0); + /// SimplifyShlInst - Given operands for a Shl, see if we can /// fold the result. If not, this returns null. Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, diff --git a/include/llvm/Analysis/Lint.h b/include/llvm/Analysis/Lint.h index eb65d22..7c88b13 100644 --- a/include/llvm/Analysis/Lint.h +++ b/include/llvm/Analysis/Lint.h @@ -20,8 +20,6 @@ #ifndef LLVM_ANALYSIS_LINT_H #define LLVM_ANALYSIS_LINT_H -#include <string> - namespace llvm { class FunctionPass; diff --git a/include/llvm/Analysis/LiveValues.h b/include/llvm/Analysis/LiveValues.h deleted file mode 100644 index b92cb78..0000000 --- a/include/llvm/Analysis/LiveValues.h +++ /dev/null @@ -1,99 +0,0 @@ -//===- LiveValues.h - Liveness information for LLVM IR Values. ------------===// -// -// 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 interface for the LLVM IR Value liveness -// analysis pass. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_LIVEVALUES_H -#define LLVM_ANALYSIS_LIVEVALUES_H - -#include "llvm/Pass.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" - -namespace llvm { - -class DominatorTree; -class LoopInfo; -class Value; - -/// LiveValues - Analysis that provides liveness information for -/// LLVM IR Values. -/// -class LiveValues : public FunctionPass { - DominatorTree *DT; - LoopInfo *LI; - - /// Memo - A bunch of state to be associated with a value. - /// - struct Memo { - /// Used - The set of blocks which contain a use of the value. - /// - SmallPtrSet<const BasicBlock *, 4> Used; - - /// LiveThrough - A conservative approximation of the set of blocks in - /// which the value is live-through, meaning blocks properly dominated - /// by the definition, and from which blocks containing uses of the - /// value are reachable. - /// - SmallPtrSet<const BasicBlock *, 4> LiveThrough; - - /// Killed - A conservative approximation of the set of blocks in which - /// the value is used and not live-out. - /// - SmallPtrSet<const BasicBlock *, 4> Killed; - }; - - /// Memos - Remembers the Memo for each Value. This is populated on - /// demand. - /// - DenseMap<const Value *, Memo> Memos; - - /// getMemo - Retrieve an existing Memo for the given value if one - /// is available, otherwise compute a new one. - /// - Memo &getMemo(const Value *V); - - /// compute - Compute a new Memo for the given value. - /// - Memo &compute(const Value *V); - -public: - static char ID; - LiveValues(); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - virtual bool runOnFunction(Function &F); - virtual void releaseMemory(); - - /// isUsedInBlock - Test if the given value is used in the given block. - /// - bool isUsedInBlock(const Value *V, const BasicBlock *BB); - - /// isLiveThroughBlock - Test if the given value is known to be - /// live-through the given block, meaning that the block is properly - /// dominated by the value's definition, and there exists a block - /// reachable from it that contains a use. This uses a conservative - /// approximation that errs on the side of returning false. - /// - bool isLiveThroughBlock(const Value *V, const BasicBlock *BB); - - /// isKilledInBlock - Test if the given value is known to be killed in - /// the given block, meaning that the block contains a use of the value, - /// and no blocks reachable from the block contain a use. This uses a - /// conservative approximation that errs on the side of returning false. - /// - bool isKilledInBlock(const Value *V, const BasicBlock *BB); -}; - -} // end namespace llvm - -#endif diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 4d5dd19..b56fe08 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -48,6 +48,11 @@ namespace llvm { /// this occurs when we see a may-aliased store to the memory location we /// care about. /// + /// There are several cases that may be interesting here: + /// 1. Loads are clobbered by may-alias stores. + /// 2. Loads are considered clobbered by partially-aliased loads. The + /// client may choose to analyze deeper into these cases. + /// /// A dependence query on the first instruction of the entry block will /// return a clobber(self) result. Clobber, @@ -350,6 +355,20 @@ namespace llvm { BasicBlock::iterator ScanIt, BasicBlock *BB); + + /// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that + /// looks at a memory location for a load (specified by MemLocBase, Offs, + /// and Size) and compares it against a load. If the specified load could + /// be safely widened to a larger integer load that is 1) still efficient, + /// 2) safe for the target, and 3) would provide the specified memory + /// location value, then this function returns the size in bytes of the + /// load width to use. If not, this returns zero. + static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase, + int64_t MemLocOffs, + unsigned MemLocSize, + const LoadInst *LI, + const TargetData &TD); + private: MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall, BasicBlock::iterator ScanIt, diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index 5b0c5b1..0eff75f 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -159,12 +159,6 @@ namespace llvm { //===--------------------------------------------------------------------===// // - // createLiveValuesPass - This creates an instance of the LiveValues pass. - // - FunctionPass *createLiveValuesPass(); - - //===--------------------------------------------------------------------===// - // /// createLazyValueInfoPass - This creates an instance of the LazyValueInfo /// pass. FunctionPass *createLazyValueInfoPass(); diff --git a/include/llvm/Analysis/PathProfileInfo.h b/include/llvm/Analysis/PathProfileInfo.h index 263763f..cef6d2d 100644 --- a/include/llvm/Analysis/PathProfileInfo.h +++ b/include/llvm/Analysis/PathProfileInfo.h @@ -16,7 +16,6 @@ #include "llvm/BasicBlock.h" #include "llvm/Analysis/PathNumbering.h" -#include <stack> namespace llvm { diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 2cd6ae3..0eddb91 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -14,7 +14,7 @@ #ifndef LLVM_ANALYSIS_POST_DOMINATORS_H #define LLVM_ANALYSIS_POST_DOMINATORS_H -#include "llvm/Analysis/DominanceFrontier.h" +#include "llvm/Analysis/Dominators.h" namespace llvm { @@ -101,37 +101,6 @@ template <> struct GraphTraits<PostDominatorTree*> } }; -/// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is -/// used to compute the a post-dominance frontier. -/// -struct PostDominanceFrontier : public DominanceFrontierBase { - static char ID; - PostDominanceFrontier() - : DominanceFrontierBase(ID, true) { - initializePostDominanceFrontierPass(*PassRegistry::getPassRegistry()); - } - - virtual bool runOnFunction(Function &) { - Frontiers.clear(); - PostDominatorTree &DT = getAnalysis<PostDominatorTree>(); - Roots = DT.getRoots(); - if (const DomTreeNode *Root = DT.getRootNode()) - calculate(DT, Root); - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<PostDominatorTree>(); - } - -private: - const DomSetType &calculate(const PostDominatorTree &DT, - const DomTreeNode *Node); -}; - -FunctionPass* createPostDomFrontier(); - } // End llvm namespace #endif diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h index a36ca11..9d89545 100644 --- a/include/llvm/Analysis/RegionInfo.h +++ b/include/llvm/Analysis/RegionInfo.h @@ -28,9 +28,10 @@ #define LLVM_ANALYSIS_REGION_INFO_H #include "llvm/ADT/PointerIntPair.h" -#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominanceFrontier.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Support/Allocator.h" +#include <map> namespace llvm { @@ -145,7 +146,7 @@ inline Region* RegionNode::getNodeAs<Region>() const { /// two connections to the remaining graph. It can be used to analyze or /// optimize parts of the control flow graph. /// -/// A <em> simple Region </em> is connected to the remaing graph by just two +/// A <em> simple Region </em> is connected to the remaining graph by just two /// edges. One edge entering the Region and another one leaving the Region. /// /// An <em> extended Region </em> (or just Region) is a subgraph that can be @@ -335,12 +336,16 @@ public: return RI; } + /// PrintStyle - Print region in difference ways. + enum PrintStyle { PrintNone, PrintBB, PrintRN }; + /// @brief Print the region. /// /// @param OS The output stream the Region is printed to. /// @param printTree Print also the tree of subregions. /// @param level The indentation level used for printing. - void print(raw_ostream& OS, bool printTree = true, unsigned level = 0) const; + void print(raw_ostream& OS, bool printTree = true, unsigned level = 0, + enum PrintStyle Style = PrintNone) const; /// @brief Print the region to stderr. void dump() const; @@ -438,7 +443,7 @@ public: /// @brief Move all direct child nodes of this Region to another Region. /// - /// @param To The Region the child nodes will be transfered to. + /// @param To The Region the child nodes will be transferred to. void transferChildrenTo(Region *To); /// @brief Verify if the region is a correct region. diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h index ced5b52..7adc71c 100644 --- a/include/llvm/Analysis/RegionIterator.h +++ b/include/llvm/Analysis/RegionIterator.h @@ -20,7 +20,7 @@ namespace llvm { //===----------------------------------------------------------------------===// -/// @brief Hierachical RegionNode successor iterator. +/// @brief Hierarchical RegionNode successor iterator. /// /// This iterator iterates over all successors of a RegionNode. /// diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index aedc06a..5403e09 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -54,7 +54,7 @@ public: /// @brief Get a pass to print the LLVM IR in the region. /// /// @param O The ouput stream to print the Region. - /// @param Banner The banner to seperate different printed passes. + /// @param Banner The banner to separate different printed passes. /// /// @return The pass to print the LLVM IR in the region. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index d193806..a62f6a8 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -24,6 +24,7 @@ #include "llvm/Pass.h" #include "llvm/Instructions.h" #include "llvm/Function.h" +#include "llvm/Operator.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/Allocator.h" @@ -72,6 +73,29 @@ namespace llvm { void operator=(const SCEV &); // DO NOT IMPLEMENT public: + /// NoWrapFlags are bitfield indices into SubclassData. + /// + /// Add and Mul expressions may have no-unsigned-wrap <NUW> or + /// no-signed-wrap <NSW> properties, which are derived from the IR + /// operator. NSW is a misnomer that we use to mean no signed overflow or + /// underflow. + /// + /// AddRec expression may have a no-self-wraparound <NW> property if the + /// result can never reach the start value. This property is independent of + /// the actual start value and step direction. Self-wraparound is defined + /// purely in terms of the recurrence's loop, step size, and + /// bitwidth. Formally, a recurrence with no self-wraparound satisfies: + /// abs(step) * max-iteration(loop) <= unsigned-max(bitwidth). + /// + /// Note that NUW and NSW are also valid properties of a recurrence, and + /// either implies NW. For convenience, NW will be set for a recurrence + /// whenever either NUW or NSW are set. + enum NoWrapFlags { FlagAnyWrap = 0, // No guarantee. + FlagNW = (1 << 0), // No self-wrap. + FlagNUW = (1 << 1), // No unsigned wrap. + FlagNSW = (1 << 2), // No signed wrap. + NoWrapMask = (1 << 3) -1 }; + explicit SCEV(const FoldingSetNodeIDRef ID, unsigned SCEVTy) : FastID(ID), SCEVType(SCEVTy), SubclassData(0) {} @@ -159,6 +183,20 @@ namespace llvm { ProperlyDominatesBlock ///< The SCEV properly dominates the block. }; + /// Convenient NoWrapFlags manipulation that hides enum casts and is + /// visible in the ScalarEvolution name space. + static SCEV::NoWrapFlags maskFlags(SCEV::NoWrapFlags Flags, int Mask) { + return (SCEV::NoWrapFlags)(Flags & Mask); + } + static SCEV::NoWrapFlags setFlags(SCEV::NoWrapFlags Flags, + SCEV::NoWrapFlags OnFlags) { + return (SCEV::NoWrapFlags)(Flags | OnFlags); + } + static SCEV::NoWrapFlags clearFlags(SCEV::NoWrapFlags Flags, + SCEV::NoWrapFlags OffFlags) { + return (SCEV::NoWrapFlags)(Flags & ~OffFlags); + } + private: /// SCEVCallbackVH - A CallbackVH to arrange for ScalarEvolution to be /// notified whenever a Value is deleted. @@ -465,44 +503,41 @@ namespace llvm { const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty); const SCEV *getAddExpr(SmallVectorImpl<const SCEV *> &Ops, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false) { + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SmallVector<const SCEV *, 2> Ops; Ops.push_back(LHS); Ops.push_back(RHS); - return getAddExpr(Ops, HasNUW, HasNSW); + return getAddExpr(Ops, Flags); } - const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, - const SCEV *Op2, - bool HasNUW = false, bool HasNSW = false) { + const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SmallVector<const SCEV *, 3> Ops; Ops.push_back(Op0); Ops.push_back(Op1); Ops.push_back(Op2); - return getAddExpr(Ops, HasNUW, HasNSW); + return getAddExpr(Ops, Flags); } const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false) { + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) + { SmallVector<const SCEV *, 2> Ops; Ops.push_back(LHS); Ops.push_back(RHS); - return getMulExpr(Ops, HasNUW, HasNSW); + return getMulExpr(Ops, Flags); } const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, - const Loop *L, - bool HasNUW = false, bool HasNSW = false); + const Loop *L, SCEV::NoWrapFlags Flags); const SCEV *getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, - const Loop *L, - bool HasNUW = false, bool HasNSW = false); + const Loop *L, SCEV::NoWrapFlags Flags); const SCEV *getAddRecExpr(const SmallVectorImpl<const SCEV *> &Operands, - const Loop *L, - bool HasNUW = false, bool HasNSW = false) { + const Loop *L, SCEV::NoWrapFlags Flags) { SmallVector<const SCEV *, 4> NewOp(Operands.begin(), Operands.end()); - return getAddRecExpr(NewOp, L, HasNUW, HasNSW); + return getAddRecExpr(NewOp, L, Flags); } const SCEV *getSMaxExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getSMaxExpr(SmallVectorImpl<const SCEV *> &Operands); @@ -537,11 +572,9 @@ namespace llvm { /// const SCEV *getNotSCEV(const SCEV *V); - /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1, - /// and thus the HasNUW and HasNSW bits apply to the resultant add, not - /// whether the sub would have overflowed. + /// getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1. const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, - bool HasNUW = false, bool HasNSW = false); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion /// of the input value to the specified type. If the type must be @@ -586,6 +619,12 @@ namespace llvm { const SCEV *getUMinFromMismatchedTypes(const SCEV *LHS, const SCEV *RHS); + /// getPointerBase - Transitively follow the chain of pointer-type operands + /// until reaching a SCEV that does not have a single pointer operand. This + /// returns a SCEVUnknown pointer for well-formed pointer-type expressions, + /// but corner cases do exist. + const SCEV *getPointerBase(const SCEV *V); + /// getSCEVAtScope - Return a SCEV expression for the specified value /// at the specified scope in the program. The L value specifies a loop /// nest to evaluate the expression at, where null is the top-level or a diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index db432c8..856d92c 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -160,13 +160,8 @@ namespace llvm { const Type *getType() const { return getOperand(0)->getType(); } - bool hasNoUnsignedWrap() const { return SubclassData & (1 << 0); } - void setHasNoUnsignedWrap(bool B) { - SubclassData = (SubclassData & ~(1 << 0)) | (B << 0); - } - bool hasNoSignedWrap() const { return SubclassData & (1 << 1); } - void setHasNoSignedWrap(bool B) { - SubclassData = (SubclassData & ~(1 << 1)) | (B << 1); + NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const { + return (NoWrapFlags)(SubclassData & Mask); } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -199,6 +194,11 @@ namespace llvm { S->getSCEVType() == scSMaxExpr || S->getSCEVType() == scUMaxExpr; } + + /// Set flags for a non-recurrence without clearing previously set flags. + void setNoWrapFlags(NoWrapFlags Flags) { + SubclassData |= Flags; + } }; @@ -305,11 +305,12 @@ namespace llvm { /// getStepRecurrence - This method constructs and returns the recurrence /// indicating how much this expression steps by. If this is a polynomial /// of degree N, it returns a chrec of degree N-1. + /// We cannot determine whether the step recurrence has self-wraparound. const SCEV *getStepRecurrence(ScalarEvolution &SE) const { if (isAffine()) return getOperand(1); return SE.getAddRecExpr(SmallVector<const SCEV *, 3>(op_begin()+1, op_end()), - getLoop()); + getLoop(), FlagAnyWrap); } /// isAffine - Return true if this is an affine AddRec (i.e., it represents @@ -327,6 +328,15 @@ namespace llvm { return getNumOperands() == 3; } + /// Set flags for a recurrence without clearing any previously set flags. + /// For AddRec, either NUW or NSW implies NW. Keep track of this fact here + /// to make it easier to propagate flags. + void setNoWrapFlags(NoWrapFlags Flags) { + if (Flags & (FlagNUW | FlagNSW)) + Flags = ScalarEvolution::setFlags(Flags, FlagNW); + SubclassData |= Flags; + } + /// evaluateAtIteration - Return the value of this chain of recurrences at /// the specified iteration number. const SCEV *evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const; @@ -364,8 +374,7 @@ namespace llvm { const SCEV *const *O, size_t N) : SCEVCommutativeExpr(ID, scSMaxExpr, O, N) { // Max never overflows. - setHasNoUnsignedWrap(true); - setHasNoSignedWrap(true); + setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW)); } public: @@ -387,8 +396,7 @@ namespace llvm { const SCEV *const *O, size_t N) : SCEVCommutativeExpr(ID, scUMaxExpr, O, N) { // Max never overflows. - setHasNoUnsignedWrap(true); - setHasNoSignedWrap(true); + setNoWrapFlags((NoWrapFlags)(FlagNUW | FlagNSW)); } public: diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h index c3c07d8..f89a86c 100644 --- a/include/llvm/Bitcode/Archive.h +++ b/include/llvm/Bitcode/Archive.h @@ -25,7 +25,6 @@ namespace llvm { class MemoryBuffer; - class raw_ostream; // Forward declare classes class Module; // From VMCore @@ -436,7 +435,7 @@ class Archive { /// to determine just enough information to create an ArchiveMember object /// which is then inserted into the Archive object's ilist at the location /// given by \p where. - /// @returns true if an error occured, false otherwise + /// @returns true if an error occurred, false otherwise /// @brief Add a file to the archive. bool addFileBefore( const sys::Path& filename, ///< The file to be added @@ -483,7 +482,7 @@ class Archive { bool loadSymbolTable(std::string* ErrMessage); /// @brief Write the symbol table to an ofstream. - void writeSymbolTable(raw_ostream& ARFile); + void writeSymbolTable(std::ofstream& ARFile); /// Writes one ArchiveMember to an ofstream. If an error occurs, returns /// false, otherwise true. If an error occurs and error is non-null then @@ -492,7 +491,7 @@ class Archive { /// @returns true Writing member failed, \p error set to error message bool writeMember( const ArchiveMember& member, ///< The member to be written - raw_ostream& ARFile, ///< The file to write member onto + std::ofstream& ARFile, ///< The file to write member onto bool CreateSymbolTable, ///< Should symbol table be created? bool TruncateNames, ///< Should names be truncated to 11 chars? bool ShouldCompress, ///< Should the member be compressed? diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index a071feb..58395ba 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -183,6 +183,10 @@ namespace llvm { /// function. void EmitFunctionBody(); + void emitPrologLabel(const MachineInstr &MI); + + bool needsCFIMoves(); + /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by @@ -377,10 +381,17 @@ namespace llvm { /// operands. virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; + /// getDwarfRegOpSize - get size required to emit given machine location + /// using dwarf encoding. + virtual unsigned getDwarfRegOpSize(const MachineLocation &MLoc) const; + /// getISAEncoding - Get the value for DW_AT_APPLE_isa. Zero if no isa /// encoding specified. virtual unsigned getISAEncoding() { return 0; } + /// EmitDwarfRegOp - Emit dwarf register operation. + virtual void EmitDwarfRegOp(const MachineLocation &MLoc) const; + //===------------------------------------------------------------------===// // Dwarf Lowering Routines //===------------------------------------------------------------------===// @@ -389,6 +400,7 @@ namespace llvm { /// frame. void EmitFrameMoves(const std::vector<MachineMove> &Moves, MCSymbol *BaseLabel, bool isEH) const; + void EmitCFIFrameMove(const MachineMove &Move) const; void EmitCFIFrameMoves(const std::vector<MachineMove> &Moves) const; //===------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 853ebf9..60edcc5 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -11,7 +11,7 @@ #ifndef LLVM_CODEGEN_CALCSPILLWEIGHTS_H #define LLVM_CODEGEN_CALCSPILLWEIGHTS_H -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/ADT/DenseMap.h" namespace llvm { @@ -29,28 +29,25 @@ namespace llvm { /// @param Size Size of live interval as returnexd by getSize() /// static inline float normalizeSpillWeight(float UseDefFreq, unsigned Size) { - // The magic constant 200 corresponds to approx. 25 instructions since - // SlotIndexes allocate 8 slots per instruction. - // - // The constant is added to avoid depending too much on accidental SlotIndex - // gaps for small intervals. The effect is that small intervals have a spill - // weight that is mostly proportional to the number of uses, while large - // intervals get a spill weight that is closer to a use density. - // - return UseDefFreq / (Size + 200); + // The constant 25 instructions is added to avoid depending too much on + // accidental SlotIndex gaps for small intervals. The effect is that small + // intervals have a spill weight that is mostly proportional to the number + // of uses, while large intervals get a spill weight that is closer to a use + // density. + return UseDefFreq / (Size + 25*SlotIndex::InstrDist); } /// VirtRegAuxInfo - Calculate auxiliary information for a virtual /// register such as its spill weight and allocation hint. class VirtRegAuxInfo { - MachineFunction &mf_; - LiveIntervals &lis_; - const MachineLoopInfo &loops_; - DenseMap<unsigned, float> hint_; + MachineFunction &MF; + LiveIntervals &LIS; + const MachineLoopInfo &Loops; + DenseMap<unsigned, float> Hint; public: VirtRegAuxInfo(MachineFunction &mf, LiveIntervals &lis, const MachineLoopInfo &loops) : - mf_(mf), lis_(lis), loops_(loops) {} + MF(mf), LIS(lis), Loops(loops) {} /// CalculateRegClass - recompute the register class for reg from its uses. /// Since the register class can affect the allocation hint, this function diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h index 2a9bbdf..9018ea3 100644 --- a/include/llvm/CodeGen/CallingConvLower.h +++ b/include/llvm/CodeGen/CallingConvLower.h @@ -141,6 +141,8 @@ typedef bool CCCustomFn(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); +typedef enum { Invalid, Prologue, Call } ParmContext; + /// CCState - This class holds information needed while lowering arguments and /// return values. It captures which registers are already assigned and which /// stack slots are used. It provides accessors to allocate these values. @@ -154,6 +156,9 @@ class CCState { unsigned StackOffset; SmallVector<uint32_t, 16> UsedRegs; + unsigned FirstByValReg; + bool FirstByValRegValid; + ParmContext CallOrPrologue; public: CCState(CallingConv::ID CC, bool isVarArg, const TargetMachine &TM, SmallVector<CCValAssign, 16> &locs, LLVMContext &C); @@ -288,6 +293,16 @@ public: MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags); + // First GPR that carries part of a byval aggregate that's split + // between registers and memory. + unsigned getFirstByValReg() { return FirstByValRegValid ? FirstByValReg : 0; } + void setFirstByValReg(unsigned r) { FirstByValReg = r; FirstByValRegValid = true; } + void clearFirstByValReg() { FirstByValReg = 0; FirstByValRegValid = false; } + bool isFirstByValRegValid() { return FirstByValRegValid; } + + ParmContext getCallOrPrologue() { return CallOrPrologue; } + void setCallOrPrologue(ParmContext pc) { CallOrPrologue = pc; } + private: /// MarkAllocated - Mark a register and all of its aliases as allocated. void MarkAllocated(unsigned Reg); diff --git a/include/llvm/CodeGen/EdgeBundles.h b/include/llvm/CodeGen/EdgeBundles.h index 2c5215a..8aab3c6 100644 --- a/include/llvm/CodeGen/EdgeBundles.h +++ b/include/llvm/CodeGen/EdgeBundles.h @@ -16,6 +16,7 @@ #ifndef LLVM_CODEGEN_EDGEBUNDLES_H #define LLVM_CODEGEN_EDGEBUNDLES_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntEqClasses.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -29,6 +30,9 @@ class EdgeBundles : public MachineFunctionPass { /// 2*BB->getNumber()+1 -> Outgoing bundle. IntEqClasses EC; + /// Blocks - Map each bundle to a list of basic block numbers. + SmallVector<SmallVector<unsigned, 8>, 4> Blocks; + public: static char ID; EdgeBundles() : MachineFunctionPass(ID) {} @@ -40,6 +44,9 @@ public: /// getNumBundles - Return the total number of bundles in the CFG. unsigned getNumBundles() const { return EC.getNumClasses(); } + /// getBlocks - Return an array of blocks that are connected to Bundle. + ArrayRef<unsigned> getBlocks(unsigned Bundle) { return Blocks[Bundle]; } + /// getMachineFunction - Return the last machine function computed. const MachineFunction *getMachineFunction() const { return MF; } diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index fbb1200..10c4c33d 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// // // This file defines the FastISel class. -// +// //===----------------------------------------------------------------------===// - + #ifndef LLVM_CODEGEN_FASTISEL_H #define LLVM_CODEGEN_FASTISEL_H @@ -108,7 +108,7 @@ public: const LoadInst * /*LI*/) { return false; } - + /// recomputeInsertPt - Reset InsertPt to prepare for inserting instructions /// into the current block. void recomputeInsertPt(); @@ -203,16 +203,7 @@ protected: unsigned Opcode, unsigned Op0, bool Op0IsKill, uint64_t Imm, MVT ImmType); - - /// FastEmit_rf_ - This method is a wrapper of FastEmit_rf. It first tries - /// to emit an instruction with an immediate operand using FastEmit_rf. - /// If that fails, it materializes the immediate into a register and try - /// FastEmit_rr instead. - unsigned FastEmit_rf_(MVT VT, - unsigned Opcode, - unsigned Op0, bool Op0IsKill, - const ConstantFP *FPImm, MVT ImmType); - + /// FastEmit_i - This method is called by target-independent code /// to request that an instruction with the given type, opcode, and /// immediate operand be emitted. @@ -250,14 +241,22 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill); - /// FastEmitInst_ri - Emit a MachineInstr with two register operands - /// and a result register in the given register class. + /// FastEmitInst_ri - Emit a MachineInstr with a register operand, + /// an immediate, and a result register in the given register class. /// unsigned FastEmitInst_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, unsigned Op0, bool Op0IsKill, uint64_t Imm); + /// FastEmitInst_rii - Emit a MachineInstr with one register operand + /// and two immediate operands. + /// + unsigned FastEmitInst_rii(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_rf - Emit a MachineInstr with two register operands /// and a result register in the given register class. /// @@ -274,13 +273,18 @@ protected: unsigned Op0, bool Op0IsKill, unsigned Op1, bool Op1IsKill, uint64_t Imm); - + /// FastEmitInst_i - Emit a MachineInstr with a single immediate /// operand, and a result register in the given register class. unsigned FastEmitInst_i(unsigned MachineInstrOpcode, const TargetRegisterClass *RC, uint64_t Imm); + /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands. + unsigned FastEmitInst_ii(unsigned MachineInstrOpcode, + const TargetRegisterClass *RC, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg /// from a specified index of a superregister to a specified type. unsigned FastEmitInst_extractsubreg(MVT RetVT, @@ -300,8 +304,8 @@ protected: unsigned UpdateValueMap(const Value* I, unsigned Reg); unsigned createResultReg(const TargetRegisterClass *RC); - - /// TargetMaterializeConstant - Emit a constant in a register using + + /// TargetMaterializeConstant - Emit a constant in a register using /// target-specific logic, such as constant pool loads. virtual unsigned TargetMaterializeConstant(const Constant* C) { return 0; @@ -313,6 +317,10 @@ protected: return 0; } + virtual unsigned TargetMaterializeFloatZero(const ConstantFP* CF) { + return 0; + } + private: bool SelectBinaryOp(const User *I, unsigned ISDOpcode); @@ -323,7 +331,7 @@ private: bool SelectCall(const User *I); bool SelectBitCast(const User *I); - + bool SelectCast(const User *I, unsigned Opcode); /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index b41f30d..4421cc0 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -187,7 +187,12 @@ public: /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be /// called when a block is visited before all of its predecessors. void InvalidatePHILiveOutRegInfo(const PHINode *PN) { - unsigned Reg = ValueMap[PN]; + // PHIs with no uses have no ValueMap entry. + DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN); + if (It == ValueMap.end()) + return; + + unsigned Reg = It->second; LiveOutRegInfo.grow(Reg); LiveOutRegInfo[Reg].IsValid = false; } @@ -209,8 +214,9 @@ private: void AddCatchInfo(const CallInst &I, MachineModuleInfo *MMI, MachineBasicBlock *MBB); -/// CopyCatchInfo - Copy catch information from DestBB to SrcBB. -void CopyCatchInfo(const BasicBlock *SrcBB, const BasicBlock *DestBB, +/// CopyCatchInfo - Copy catch information from SuccBB (or one of its +/// successors) to LPad. +void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad, MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); } // end namespace llvm diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 3da11c4..f0de936 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -219,7 +219,7 @@ namespace ISD { // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. // These nodes take two operands: the normal LHS and RHS to the add. They // produce two results: the normal result of the add, and a boolean that - // indicates if an overflow occured (*not* a flag, because it may be stored + // indicates if an overflow occurred (*not* a flag, because it may be stored // to memory, etc.). If the type of the boolean is not i1 then the high // bits conform to getBooleanContents. // These nodes are generated from the llvm.[su]add.with.overflow intrinsics. diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h index fea8523..88e22d6 100644 --- a/include/llvm/CodeGen/JITCodeEmitter.h +++ b/include/llvm/CodeGen/JITCodeEmitter.h @@ -23,8 +23,6 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/ADT/DenseMap.h" -using namespace std; - namespace llvm { class MachineBasicBlock; @@ -38,7 +36,7 @@ class GlobalValue; class Function; /// JITCodeEmitter - This class defines two sorts of methods: those for -/// emitting the actual bytes of machine code, and those for emitting auxillary +/// emitting the actual bytes of machine code, and those for emitting auxiliary /// structures, such as jump tables, relocations, etc. /// /// Emission of machine code is complicated by the fact that we don't (in diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 88131fb..c5285ce 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -286,6 +286,11 @@ namespace llvm { return valnos[ValNo]; } + /// containsValue - Returns true if VNI belongs to this interval. + bool containsValue(const VNInfo *VNI) const { + return VNI && VNI->id < getNumValNums() && VNI == getValNumInfo(VNI->id); + } + /// getNextValue - Create a new value number and return it. MIIdx specifies /// the instruction that defines the value number. VNInfo *getNextValue(SlotIndex def, MachineInstr *CopyMI, @@ -447,6 +452,11 @@ namespace llvm { addRangeFrom(LR, ranges.begin()); } + /// extendInBlock - If this interval is live before UseIdx in the basic + /// block that starts at StartIdx, extend it to be live at UseIdx and return + /// the value. If there is no live range before UseIdx, return NULL. + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx); + /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If /// the intervals are not joinable, this aborts. @@ -543,8 +553,8 @@ namespace llvm { /// } class ConnectedVNInfoEqClasses { - LiveIntervals &lis_; - IntEqClasses eqClass_; + LiveIntervals &LIS; + IntEqClasses EqClass; // Note that values a and b are connected. void Connect(unsigned a, unsigned b); @@ -552,7 +562,7 @@ namespace llvm { unsigned Renumber(); public: - explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {} + explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} /// Classify - Classify the values in LI into connected components. /// Return the number of connected components. @@ -560,12 +570,13 @@ namespace llvm { /// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// the equivalence class assigned the VNI. - unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; } + unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } /// Distribute - Distribute values in LIV[0] into a separate LiveInterval /// for each connected component. LIV must have a LiveInterval for each /// connected component. The LiveIntervals in Liv[1..] must be empty. - void Distribute(LiveInterval *LIV[]); + /// Instructions using LIV[0] are rewritten. + void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); }; diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index b09f8d1..8ca58b8 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -159,7 +159,11 @@ namespace llvm { /// range to just the remaining uses. This method does not compute reaching /// defs for new uses, and it doesn't remove dead defs. /// Dead PHIDef values are marked as unused. - void shrinkToUses(LiveInterval *li); + /// New dead machine instructions are added to the dead vector. + /// Return true if the interval may have been separated into multiple + /// connected components. + bool shrinkToUses(LiveInterval *li, + SmallVectorImpl<MachineInstr*> *dead = 0); // Interval removal @@ -272,7 +276,7 @@ namespace llvm { /// (if any is created) by reference. This is temporary. std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, const MachineLoopInfo *loopInfo, VirtRegMap& vrm); /// spillPhysRegAroundRegDefsUses - Spill the specified physical register @@ -285,7 +289,7 @@ namespace llvm { /// val# of the specified interval is re-materializable. Also returns true /// by reference if all of the defs are load instructions. bool isReMaterializable(const LiveInterval &li, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, bool &isLoad); /// isReMaterializable - Returns true if the definition MI of the specified @@ -372,7 +376,7 @@ namespace llvm { /// by reference if the def is a load. bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo, MachineInstr *MI, - const SmallVectorImpl<LiveInterval*> &SpillIs, + const SmallVectorImpl<LiveInterval*> *SpillIs, bool &isLoad); /// tryFoldMemoryOperand - Attempts to fold either a spill / restore from diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 1785451..ad12157 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/ADT/GraphTraits.h" +#include <functional> namespace llvm { @@ -304,10 +305,18 @@ public: /// it returns end() iterator getFirstTerminator(); + const_iterator getFirstTerminator() const { + return const_cast<MachineBasicBlock*>(this)->getFirstTerminator(); + } + /// getLastNonDebugInstr - returns an iterator to the last non-debug /// instruction in the basic block, or end() iterator getLastNonDebugInstr(); + const_iterator getLastNonDebugInstr() const { + return const_cast<MachineBasicBlock*>(this)->getLastNonDebugInstr(); + } + /// SplitCriticalEdge - Split the critical edge from this block to the /// given successor block, and return the newly created block, or null /// if splitting is not possible. @@ -411,6 +420,14 @@ raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB); void WriteAsOperand(raw_ostream &, const MachineBasicBlock*, bool t); +// This is useful when building IndexedMaps keyed on basic block pointers. +struct MBB2NumberFunctor : + public std::unary_function<const MachineBasicBlock*, unsigned> { + unsigned operator()(const MachineBasicBlock *MBB) const { + return MBB->getNumber(); + } +}; + //===--------------------------------------------------------------------===// // GraphTraits specializations for machine basic block graphs (machine-CFGs) //===--------------------------------------------------------------------===// diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 8fc80ad..428aada 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -34,7 +34,7 @@ class Function; class MCSymbol; /// MachineCodeEmitter - This class defines two sorts of methods: those for -/// emitting the actual bytes of machine code, and those for emitting auxillary +/// emitting the actual bytes of machine code, and those for emitting auxiliary /// structures, such as jump tables, relocations, etc. /// /// Emission of machine code is complicated by the fact that we don't (in @@ -54,7 +54,7 @@ protected: /// allocated for this code buffer. uint8_t *BufferBegin, *BufferEnd; /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting - /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If + /// code. This is guaranteed to be in the range [BufferBegin,BufferEnd]. If /// this pointer is at BufferEnd, it will never move due to code emission, and /// all code emission requests will be ignored (this is the buffer overflow /// condition). diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index 5727321..beb16a2 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -80,7 +80,7 @@ public: } Val; /// The required alignment for this entry. The top bit is set when Val is - /// a MachineConstantPoolValue. + /// a target specific MachineConstantPoolValue. unsigned Alignment; MachineConstantPoolEntry(const Constant *V, unsigned A) @@ -93,6 +93,9 @@ public: Alignment |= 1U << (sizeof(unsigned)*CHAR_BIT-1); } + /// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry + /// is indeed a target specific constantpool entry, not a wrapper over a + /// Constant. bool isMachineConstantPoolEntry() const { return (int)Alignment < 0; } diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 22a82a9..4ea6aa3 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -15,7 +15,6 @@ #define LLVM_CODEGEN_MACHINEFRAMEINFO_H #include "llvm/ADT/SmallVector.h" -//#include "llvm/ADT/IndexedMap.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <vector> diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 82c5332..2724689 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -50,13 +50,22 @@ public: enum CommentFlag { ReloadReuse = 0x1 }; - + + enum MIFlag { + NoFlags = 0, + FrameSetup = 1 << 0 // Instruction is used as a part of + // function frame setup code. + }; private: const TargetInstrDesc *TID; // Instruction descriptor. - unsigned short NumImplicitOps; // Number of implicit operands (which + uint16_t NumImplicitOps; // Number of implicit operands (which // are determined at construction time). - unsigned short AsmPrinterFlags; // Various bits of information used by + uint8_t Flags; // Various bits of additional + // information about machine + // instruction. + + uint8_t AsmPrinterFlags; // Various bits of information used by // the AsmPrinter to emit helpful // comments. This is *not* semantic // information. Do not use this for @@ -105,13 +114,13 @@ private: /// MachineInstr ctor - This constructor create a MachineInstr and add the /// implicit operands. It reserves space for number of operands specified by /// TargetInstrDesc. An explicit DebugLoc is supplied. - explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, + explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, bool NoImp = false); /// MachineInstr ctor - Work exactly the same as the ctor above, except that /// the MachineInstr is created and added to the end of the specified basic /// block. - MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, + MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const TargetInstrDesc &TID); ~MachineInstr(); @@ -125,12 +134,12 @@ public: /// getAsmPrinterFlags - Return the asm printer flags bitvector. /// - unsigned short getAsmPrinterFlags() const { return AsmPrinterFlags; } + uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; } /// clearAsmPrinterFlags - clear the AsmPrinter bitvector /// void clearAsmPrinterFlags() { AsmPrinterFlags = 0; } - + /// getAsmPrinterFlag - Return whether an AsmPrinter flag is set. /// bool getAsmPrinterFlag(CommentFlag Flag) const { @@ -140,9 +149,28 @@ public: /// setAsmPrinterFlag - Set a flag for the AsmPrinter. /// void setAsmPrinterFlag(CommentFlag Flag) { - AsmPrinterFlags |= (unsigned short)Flag; + AsmPrinterFlags |= (uint8_t)Flag; + } + + /// getFlags - Return the MI flags bitvector. + uint8_t getFlags() const { + return Flags; + } + + /// getFlag - Return whether an MI flag is set. + bool getFlag(MIFlag Flag) const { + return Flags & Flag; + } + + /// setFlag - Set a MI flag. + void setFlag(MIFlag Flag) { + Flags |= (uint8_t)Flag; + } + + void setFlags(unsigned flags) { + Flags = flags; } - + /// clearAsmPrinterFlag - clear specific AsmPrinter flags /// void clearAsmPrinterFlag(CommentFlag Flag) { @@ -152,7 +180,7 @@ public: /// getDebugLoc - Returns the debug location id of this MachineInstr. /// DebugLoc getDebugLoc() const { return debugLoc; } - + /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. const TargetInstrDesc &getDesc() const { return *TID; } @@ -213,7 +241,7 @@ public: /// removeFromParent - This method unlinks 'this' from the containing basic /// block, and returns it, but does not delete it. MachineInstr *removeFromParent(); - + /// eraseFromParent - This method unlinks 'this' from the containing basic /// block and deletes it. void eraseFromParent(); @@ -225,14 +253,14 @@ public: getOpcode() == TargetOpcode::EH_LABEL || getOpcode() == TargetOpcode::GC_LABEL; } - + bool isPrologLabel() const { return getOpcode() == TargetOpcode::PROLOG_LABEL; } bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; } bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; } bool isDebugValue() const { return getOpcode() == TargetOpcode::DBG_VALUE; } - + bool isPHI() const { return getOpcode() == TargetOpcode::PHI; } bool isKill() const { return getOpcode() == TargetOpcode::KILL; } bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; } @@ -329,7 +357,7 @@ public: int Idx = findRegisterUseOperandIdx(Reg, isKill, TRI); return (Idx == -1) ? NULL : &getOperand(Idx); } - + /// findRegisterDefOperandIdx() - Returns the operand index that is a def of /// the specified register or -1 if it is not found. If isDead is true, defs /// that are not dead are skipped. If Overlap is true, then it also looks for @@ -351,7 +379,7 @@ public: /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int findFirstPredOperandIdx() const; - + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the @@ -399,8 +427,8 @@ public: void addRegisterDefined(unsigned IncomingReg, const TargetRegisterInfo *RegInfo = 0); - /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as dead - /// except those in the UsedRegs list. + /// setPhysRegsDeadExcept - Mark every physreg used by this instruction as + /// dead except those in the UsedRegs list. void setPhysRegsDeadExcept(const SmallVectorImpl<unsigned> &UsedRegs, const TargetRegisterInfo &TRI); @@ -462,9 +490,9 @@ public: /// addOperand - Add the specified operand to the instruction. If it is an /// implicit operand, it is added to the end of the operand list. If it is /// an explicit operand it is added at the end of the explicit operand list - /// (before the first implicit operand). + /// (before the first implicit operand). void addOperand(const MachineOperand &Op); - + /// setDesc - Replace the instruction descriptor (thus opcode) of /// the current instruction with a new one. /// @@ -501,12 +529,12 @@ private: /// addImplicitDefUseOperands - Add all implicit def and use operands to /// this instruction. void addImplicitDefUseOperands(); - + /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands already be on their use lists. void RemoveRegOperandsFromUseLists(); - + /// AddRegOperandsToUseLists - Add all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands not be on their use lists yet. diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 1eb9735..967e019 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -48,6 +48,7 @@ public: /// Allow automatic conversion to the machine instruction we are working on. /// operator MachineInstr*() const { return MI; } + MachineInstr *operator->() const { return MI; } operator MachineBasicBlock::iterator() const { return MI; } /// addReg - Add a new virtual register operand... @@ -145,6 +146,16 @@ public: return *this; } + const MachineInstrBuilder &setMIFlags(unsigned Flags) const { + MI->setFlags(Flags); + return *this; + } + + const MachineInstrBuilder &setMIFlag(MachineInstr::MIFlag Flag) const { + MI->setFlag(Flag); + return *this; + } + // Add a displacement from an existing MachineOperand with an added offset. const MachineInstrBuilder &addDisp(const MachineOperand &Disp, int64_t off) const { diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h index b2224cb..5240729 100644 --- a/include/llvm/CodeGen/PBQP/Graph.h +++ b/include/llvm/CodeGen/PBQP/Graph.h @@ -18,7 +18,6 @@ #include "Math.h" #include <list> -#include <vector> #include <map> namespace PBQP { diff --git a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h index 47a287c..e96c4cb 100644 --- a/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h +++ b/include/llvm/CodeGen/PBQP/Heuristics/Briggs.h @@ -21,7 +21,6 @@ #include "../HeuristicSolver.h" #include "../HeuristicBase.h" -#include <set> #include <limits> namespace PBQP { diff --git a/include/llvm/CodeGen/ProcessImplicitDefs.h b/include/llvm/CodeGen/ProcessImplicitDefs.h index e2ab899..6ab57f0 100644 --- a/include/llvm/CodeGen/ProcessImplicitDefs.h +++ b/include/llvm/CodeGen/ProcessImplicitDefs.h @@ -18,14 +18,20 @@ namespace llvm { class MachineInstr; class TargetInstrInfo; + class TargetRegisterInfo; + class MachineRegisterInfo; + class LiveVariables; /// Process IMPLICIT_DEF instructions and make sure there is one implicit_def /// for each use. Add isUndef marker to implicit_def defs and their uses. class ProcessImplicitDefs : public MachineFunctionPass { - private: + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineRegisterInfo *MRI; + LiveVariables *LV; bool CanTurnIntoImplicitDef(MachineInstr *MI, unsigned Reg, - unsigned OpIdx, const TargetInstrInfo *tii_, + unsigned OpIdx, SmallSet<unsigned, 8> &ImpDefRegs); public: diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h index 246831c..26b6773 100644 --- a/include/llvm/CodeGen/RegisterScavenging.h +++ b/include/llvm/CodeGen/RegisterScavenging.h @@ -100,7 +100,7 @@ public: /// getRegsAvailable - Return all available registers in the register class /// in Mask. - void getRegsAvailable(const TargetRegisterClass *RC, BitVector &Mask); + BitVector getRegsAvailable(const TargetRegisterClass *RC); /// FindUnusedReg - Find a unused register of the specified register class. /// Return 0 if none is found. diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index a51e82a..576be82 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -66,6 +66,16 @@ namespace RTLIB { UREM_I32, UREM_I64, UREM_I128, + SDIVREM_I8, + SDIVREM_I16, + SDIVREM_I32, + SDIVREM_I64, + SDIVREM_I128, + UDIVREM_I8, + UDIVREM_I16, + UDIVREM_I32, + UDIVREM_I64, + UDIVREM_I128, NEG_I32, NEG_I64, diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h index 3864ffd..2eb3db3 100644 --- a/include/llvm/CodeGen/ScheduleDAG.h +++ b/include/llvm/CodeGen/ScheduleDAG.h @@ -250,7 +250,9 @@ namespace llvm { unsigned NumSuccsLeft; // # of succs not scheduled. unsigned short NumRegDefsLeft; // # of reg defs with no scheduled use. unsigned short Latency; // Node latency. + bool isVRegCycle : 1; // May use and def the same vreg. bool isCall : 1; // Is a function call. + bool isCallOp : 1; // Is a function call operand. bool isTwoAddress : 1; // Is a two-address instruction. bool isCommutable : 1; // Is a commutable instruction. bool hasPhysRegDefs : 1; // Has physreg defs that are being used. @@ -259,6 +261,7 @@ namespace llvm { bool isAvailable : 1; // True once available. bool isScheduled : 1; // True once scheduled. bool isScheduleHigh : 1; // True if preferable to schedule high. + bool isScheduleLow : 1; // True if preferable to schedule low. bool isCloned : 1; // True if this node has been cloned. Sched::Preference SchedulingPref; // Scheduling preference. @@ -278,10 +281,10 @@ namespace llvm { : Node(node), Instr(0), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -292,10 +295,10 @@ namespace llvm { : Node(0), Instr(instr), OrigNode(0), NodeNum(nodenum), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -305,10 +308,10 @@ namespace llvm { : Node(0), Instr(0), OrigNode(0), NodeNum(~0u), NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0), NumRegDefsLeft(0), Latency(0), - isCall(false), isTwoAddress(false), isCommutable(false), - hasPhysRegDefs(false), hasPhysRegClobbers(false), + isVRegCycle(false), isCall(false), isCallOp(false), isTwoAddress(false), + isCommutable(false), hasPhysRegDefs(false), hasPhysRegClobbers(false), isPending(false), isAvailable(false), isScheduled(false), - isScheduleHigh(false), isCloned(false), + isScheduleHigh(false), isScheduleLow(false), isCloned(false), SchedulingPref(Sched::None), isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0), CopyDstRC(NULL), CopySrcRC(NULL) {} @@ -356,7 +359,7 @@ namespace llvm { void removePred(const SDep &D); /// getDepth - Return the depth of this node, which is the length of the - /// maximum path up to any node with has no predecessors. + /// maximum path up to any node which has no predecessors. unsigned getDepth() const { if (!isDepthCurrent) const_cast<SUnit *>(this)->ComputeDepth(); @@ -364,7 +367,7 @@ namespace llvm { } /// getHeight - Return the height of this node, which is the length of the - /// maximum path down to any node with has no successors. + /// maximum path down to any node which has no successors. unsigned getHeight() const { if (!isHeightCurrent) const_cast<SUnit *>(this)->ComputeHeight(); @@ -690,11 +693,11 @@ namespace llvm { /// will create a cycle. bool WillCreateCycle(SUnit *SU, SUnit *TargetSU); - /// AddPred - Updates the topological ordering to accomodate an edge + /// AddPred - Updates the topological ordering to accommodate an edge /// to be added from SUnit X to SUnit Y. void AddPred(SUnit *Y, SUnit *X); - /// RemovePred - Updates the topological ordering to accomodate an + /// RemovePred - Updates the topological ordering to accommodate an /// an edge to be removed from the specified node N from the predecessors /// of the current node M. void RemovePred(SUnit *M, SUnit *N); diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h index 8850006..118df28 100644 --- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h +++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h @@ -21,7 +21,6 @@ #include <cassert> #include <cstring> -#include <string> namespace llvm { diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index c9de95b..92fd0c9 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -438,12 +438,12 @@ public: SDValue getConvertRndSat(EVT VT, DebugLoc dl, SDValue Val, SDValue DTy, SDValue STy, SDValue Rnd, SDValue Sat, ISD::CvtCode Code); - + /// getVectorShuffle - Return an ISD::VECTOR_SHUFFLE node. The number of /// elements in VT, which must be a vector type, must match the number of /// mask elements NumElts. A integer mask element equal to -1 is treated as /// undefined. - SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, + SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, const int *MaskElts); /// getSExtOrTrunc - Convert Op, which must be of integer type, to the @@ -671,10 +671,10 @@ public: /// getMDNode - Return an MDNodeSDNode which holds an MDNode. SDValue getMDNode(const MDNode *MD); - + /// getShiftAmountOperand - Return the specified value casted to /// the target's desired shift amount type. - SDValue getShiftAmountOperand(SDValue Op); + SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op); /// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, @@ -829,7 +829,7 @@ public: /// These functions only replace all existing uses. It's possible that as /// these replacements are being performed, CSE may cause the From node /// to be given new uses. These new uses of From are left in place, and - /// not automatically transfered to To. + /// not automatically transferred to To. /// void ReplaceAllUsesWith(SDValue From, SDValue Op, DAGUpdateListener *UpdateListener = 0); @@ -901,7 +901,7 @@ public: SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) { return DbgInfo->getSDDbgValues(SD); } - + /// TransferDbgValues - Transfer SDDbgValues. void TransferDbgValues(SDValue From, SDValue To); @@ -911,11 +911,11 @@ public: SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); } SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); } - SDDbgInfo::DbgIterator ByvalParmDbgBegin() { - return DbgInfo->ByvalParmDbgBegin(); + SDDbgInfo::DbgIterator ByvalParmDbgBegin() { + return DbgInfo->ByvalParmDbgBegin(); } - SDDbgInfo::DbgIterator ByvalParmDbgEnd() { - return DbgInfo->ByvalParmDbgEnd(); + SDDbgInfo::DbgIterator ByvalParmDbgEnd() { + return DbgInfo->ByvalParmDbgEnd(); } void dump() const; @@ -972,7 +972,7 @@ public: /// semantics as an ADD. This handles the equivalence: /// X|Cst == X+Cst iff X&Cst = 0. bool isBaseWithConstantOffset(SDValue Op) const; - + /// isKnownNeverNan - Test whether the given SDValue is known to never be NaN. bool isKnownNeverNaN(SDValue Op) const; @@ -997,8 +997,8 @@ public: /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); - /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a - /// location that is 'Dist' units away from the location that the 'Base' load + /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a + /// location that is 'Dist' units away from the location that the 'Base' load /// is loading from. bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const; @@ -1032,7 +1032,7 @@ private: std::vector<SDNode*> ValueTypeNodes; std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes; StringMap<SDNode*> ExternalSymbols; - + std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols; }; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 62358e7..ecf3947 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -127,6 +127,7 @@ public: OPC_EmitInteger, OPC_EmitRegister, + OPC_EmitRegister2, OPC_EmitConvertToTarget, OPC_EmitMergeInputChains, OPC_EmitMergeInputChains1_0, @@ -257,7 +258,7 @@ public: } virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { - assert(0 && "Tblgen shoudl generate this!"); + assert(0 && "Tblgen should generate this!"); return SDValue(); } @@ -279,7 +280,8 @@ private: void PrepareEHLandingPad(); void SelectAllBasicBlocks(const Function &Fn); - bool TryToFoldFastISelLoad(const LoadInst *LI, FastISel *FastIS); + bool TryToFoldFastISelLoad(const LoadInst *LI, const Instruction *FoldInst, + FastISel *FastIS); void FinishBasicBlock(); void SelectBasicBlock(BasicBlock::const_iterator Begin, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 6454639..9d265f1 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -838,7 +838,7 @@ public: /// HandleSDNode - This class is used to form a handle around another node that -/// is persistant and is updated across invocations of replaceAllUsesWith on its +/// is persistent and is updated across invocations of replaceAllUsesWith on its /// operand. This node should be directly created by end-users and not added to /// the AllNodes list. class HandleSDNode : public SDNode { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 1da1e91be..33ce675 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -34,77 +34,35 @@ namespace llvm { /// SlotIndex & SlotIndexes classes for the public interface to this /// information. class IndexListEntry { - static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U, - TOMBSTONE_KEY_INDEX = ~0U & ~7U; - IndexListEntry *next, *prev; MachineInstr *mi; unsigned index; - protected: - - typedef enum { EMPTY_KEY, TOMBSTONE_KEY } ReservedEntryType; - - // This constructor is only to be used by getEmptyKeyEntry - // & getTombstoneKeyEntry. It sets index to the given - // value and mi to zero. - IndexListEntry(ReservedEntryType r) : mi(0) { - switch(r) { - case EMPTY_KEY: index = EMPTY_KEY_INDEX; break; - case TOMBSTONE_KEY: index = TOMBSTONE_KEY_INDEX; break; - default: assert(false && "Invalid value for constructor."); - } - next = this; - prev = this; - } - public: - IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to create invalid index. " - "Available indexes may have been exhausted?."); - } - - bool isValid() const { - return (index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX); - } + IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {} MachineInstr* getInstr() const { return mi; } void setInstr(MachineInstr *mi) { - assert(isValid() && "Attempt to modify reserved index."); this->mi = mi; } unsigned getIndex() const { return index; } void setIndex(unsigned index) { - assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX && - "Attempt to set index to invalid value."); - assert(isValid() && "Attempt to reset reserved index value."); this->index = index; } IndexListEntry* getNext() { return next; } const IndexListEntry* getNext() const { return next; } void setNext(IndexListEntry *next) { - assert(isValid() && "Attempt to modify reserved index."); this->next = next; } IndexListEntry* getPrev() { return prev; } const IndexListEntry* getPrev() const { return prev; } void setPrev(IndexListEntry *prev) { - assert(isValid() && "Attempt to modify reserved index."); this->prev = prev; } - - // This function returns the index list entry that is to be used for empty - // SlotIndex keys. - static IndexListEntry* getEmptyKeyEntry(); - - // This function returns the index list entry that is to be used for - // tombstone SlotIndex keys. - static IndexListEntry* getTombstoneKeyEntry(); }; // Specialize PointerLikeTypeTraits for IndexListEntry. @@ -130,11 +88,10 @@ namespace llvm { PointerIntPair<IndexListEntry*, 2, unsigned> lie; SlotIndex(IndexListEntry *entry, unsigned slot) - : lie(entry, slot) { - assert(entry != 0 && "Attempt to construct index with 0 pointer."); - } + : lie(entry, slot) {} IndexListEntry& entry() const { + assert(isValid() && "Attempt to compare reserved index."); return *lie.getPointer(); } @@ -148,22 +105,27 @@ namespace llvm { } static inline unsigned getHashValue(const SlotIndex &v) { - IndexListEntry *ptrVal = &v.entry(); - return (unsigned((intptr_t)ptrVal) >> 4) ^ - (unsigned((intptr_t)ptrVal) >> 9); + void *ptrVal = v.lie.getOpaqueValue(); + return (unsigned((intptr_t)ptrVal)) ^ (unsigned((intptr_t)ptrVal) >> 9); } public: + enum { + /// The default distance between instructions as returned by distance(). + /// This may vary as instructions are inserted and removed. + InstrDist = 4*NUM + }; + static inline SlotIndex getEmptyKey() { - return SlotIndex(IndexListEntry::getEmptyKeyEntry(), 0); + return SlotIndex(0, 1); } static inline SlotIndex getTombstoneKey() { - return SlotIndex(IndexListEntry::getTombstoneKeyEntry(), 0); + return SlotIndex(0, 2); } /// Construct an invalid index. - SlotIndex() : lie(IndexListEntry::getEmptyKeyEntry(), 0) {} + SlotIndex() : lie(0, 0) {} // Construct a new slot index from the given one, and set the slot. SlotIndex(const SlotIndex &li, Slot s) @@ -175,8 +137,7 @@ namespace llvm { /// Returns true if this is a valid index. Invalid indicies do /// not point into an index table, and cannot be compared. bool isValid() const { - IndexListEntry *entry = lie.getPointer(); - return ((entry!= 0) && (entry->isValid())); + return lie.getPointer(); } /// Print this index to the given raw_ostream. @@ -187,11 +148,11 @@ namespace llvm { /// Compare two SlotIndex objects for equality. bool operator==(SlotIndex other) const { - return getIndex() == other.getIndex(); + return lie == other.lie; } /// Compare two SlotIndex objects for inequality. bool operator!=(SlotIndex other) const { - return getIndex() != other.getIndex(); + return lie != other.lie; } /// Compare two SlotIndex objects. Return true if the first index @@ -217,6 +178,11 @@ namespace llvm { return getIndex() >= other.getIndex(); } + /// isSameInstr - Return true if A and B refer to the same instruction. + static bool isSameInstr(SlotIndex A, SlotIndex B) { + return A.lie.getPointer() == B.lie.getPointer(); + } + /// Return the distance from this index to the given one. int distance(SlotIndex other) const { return other.getIndex() - getIndex(); @@ -376,15 +342,12 @@ namespace llvm { typedef DenseMap<const MachineInstr*, SlotIndex> Mi2IndexMap; Mi2IndexMap mi2iMap; - /// MBB2IdxMap - The indexes of the first and last instructions in the - /// specified basic block. - typedef DenseMap<const MachineBasicBlock*, - std::pair<SlotIndex, SlotIndex> > MBB2IdxMap; - MBB2IdxMap mbb2IdxMap; + /// MBBRanges - Map MBB number to (start, stop) indexes. + SmallVector<std::pair<SlotIndex, SlotIndex>, 8> MBBRanges; /// Idx2MBBMap - Sorted list of pairs of index of first instruction /// and MBB id. - std::vector<IdxMBBPair> idx2MBBMap; + SmallVector<IdxMBBPair, 8> idx2MBBMap; // IndexListEntry allocator. BumpPtrAllocator ileAllocator; @@ -466,6 +429,9 @@ namespace llvm { insert(getTail(), val); } + /// Renumber locally after inserting newEntry. + void renumberIndexes(IndexListEntry *newEntry); + public: static char ID; @@ -530,7 +496,7 @@ namespace llvm { /// Returns the instruction for the given index, or null if the given /// index has no instruction associated with it. MachineInstr* getInstructionFromIndex(SlotIndex index) const { - return index.entry().getInstr(); + return index.isValid() ? index.entry().getInstr() : 0; } /// Returns the next non-null index. @@ -545,12 +511,55 @@ namespace llvm { return nextNonNull; } + /// getIndexBefore - Returns the index of the last indexed instruction + /// before MI, or the the start index of its basic block. + /// MI is not required to have an index. + SlotIndex getIndexBefore(const MachineInstr *MI) const { + const MachineBasicBlock *MBB = MI->getParent(); + assert(MBB && "MI must be inserted inna basic block"); + MachineBasicBlock::const_iterator I = MI, B = MBB->begin(); + for (;;) { + if (I == B) + return getMBBStartIdx(MBB); + --I; + Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I); + if (MapItr != mi2iMap.end()) + return MapItr->second; + } + } + + /// getIndexAfter - Returns the index of the first indexed instruction + /// after MI, or the end index of its basic block. + /// MI is not required to have an index. + SlotIndex getIndexAfter(const MachineInstr *MI) const { + const MachineBasicBlock *MBB = MI->getParent(); + assert(MBB && "MI must be inserted inna basic block"); + MachineBasicBlock::const_iterator I = MI, E = MBB->end(); + for (;;) { + ++I; + if (I == E) + return getMBBEndIdx(MBB); + Mi2IndexMap::const_iterator MapItr = mi2iMap.find(I); + if (MapItr != mi2iMap.end()) + return MapItr->second; + } + } + + /// Return the (start,end) range of the given basic block number. + const std::pair<SlotIndex, SlotIndex> & + getMBBRange(unsigned Num) const { + return MBBRanges[Num]; + } + /// Return the (start,end) range of the given basic block. const std::pair<SlotIndex, SlotIndex> & - getMBBRange(const MachineBasicBlock *mbb) const { - MBB2IdxMap::const_iterator itr = mbb2IdxMap.find(mbb); - assert(itr != mbb2IdxMap.end() && "MBB not found in maps."); - return itr->second; + getMBBRange(const MachineBasicBlock *MBB) const { + return getMBBRange(MBB->getNumber()); + } + + /// Returns the first index in the given basic block number. + SlotIndex getMBBStartIdx(unsigned Num) const { + return getMBBRange(Num).first; } /// Returns the first index in the given basic block. @@ -558,6 +567,11 @@ namespace llvm { return getMBBRange(mbb).first; } + /// Returns the last index in the given basic block number. + SlotIndex getMBBEndIdx(unsigned Num) const { + return getMBBRange(Num).second; + } + /// Returns the last index in the given basic block. SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const { return getMBBRange(mbb).second; @@ -565,10 +579,12 @@ namespace llvm { /// Returns the basic block which the given index falls in. MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { - std::vector<IdxMBBPair>::const_iterator I = + if (MachineInstr *MI = getInstructionFromIndex(index)) + return MI->getParent(); + SmallVectorImpl<IdxMBBPair>::const_iterator I = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), index); // Take the pair containing the index - std::vector<IdxMBBPair>::const_iterator J = + SmallVectorImpl<IdxMBBPair>::const_iterator J = ((I != idx2MBBMap.end() && I->first > index) || (I == idx2MBBMap.end() && idx2MBBMap.size()>0)) ? (I-1): I; @@ -580,7 +596,7 @@ namespace llvm { bool findLiveInMBBs(SlotIndex start, SlotIndex end, SmallVectorImpl<MachineBasicBlock*> &mbbs) const { - std::vector<IdxMBBPair>::const_iterator itr = + SmallVectorImpl<IdxMBBPair>::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); bool resVal = false; @@ -600,7 +616,7 @@ namespace llvm { assert(start < end && "Backwards ranges not allowed."); - std::vector<IdxMBBPair>::const_iterator itr = + SmallVectorImpl<IdxMBBPair>::const_iterator itr = std::lower_bound(idx2MBBMap.begin(), idx2MBBMap.end(), start); if (itr == idx2MBBMap.end()) { @@ -622,95 +638,47 @@ namespace llvm { /// Insert the given machine instruction into the mapping. Returns the /// assigned index. - SlotIndex insertMachineInstrInMaps(MachineInstr *mi, - bool *deferredRenumber = 0) { + /// If Late is set and there are null indexes between mi's neighboring + /// instructions, create the new index after the null indexes instead of + /// before them. + SlotIndex insertMachineInstrInMaps(MachineInstr *mi, bool Late = false) { assert(mi2iMap.find(mi) == mi2iMap.end() && "Instr already indexed."); // Numbering DBG_VALUE instructions could cause code generation to be // affected by debug information. assert(!mi->isDebugValue() && "Cannot number DBG_VALUE instructions."); - MachineBasicBlock *mbb = mi->getParent(); - - assert(mbb != 0 && "Instr must be added to function."); + assert(mi->getParent() != 0 && "Instr must be added to function."); - MBB2IdxMap::iterator mbbRangeItr = mbb2IdxMap.find(mbb); - - assert(mbbRangeItr != mbb2IdxMap.end() && - "Instruction's parent MBB has not been added to SlotIndexes."); - - MachineBasicBlock::iterator miItr(mi); - bool needRenumber = false; - IndexListEntry *newEntry; - // Get previous index, considering that not all instructions are indexed. - IndexListEntry *prevEntry; - for (;;) { - // If mi is at the mbb beginning, get the prev index from the mbb. - if (miItr == mbb->begin()) { - prevEntry = &mbbRangeItr->second.first.entry(); - break; - } - // Otherwise rewind until we find a mapped instruction. - Mi2IndexMap::const_iterator itr = mi2iMap.find(--miItr); - if (itr != mi2iMap.end()) { - prevEntry = &itr->second.entry(); - break; - } + // Get the entries where mi should be inserted. + IndexListEntry *prevEntry, *nextEntry; + if (Late) { + // Insert mi's index immediately before the following instruction. + nextEntry = &getIndexAfter(mi).entry(); + prevEntry = nextEntry->getPrev(); + } else { + // Insert mi's index immediately after the preceeding instruction. + prevEntry = &getIndexBefore(mi).entry(); + nextEntry = prevEntry->getNext(); } - // Get next entry from previous entry. - IndexListEntry *nextEntry = prevEntry->getNext(); - // Get a number for the new instr, or 0 if there's no room currently. // In the latter case we'll force a renumber later. - unsigned dist = nextEntry->getIndex() - prevEntry->getIndex(); - unsigned newNumber = dist > SlotIndex::NUM ? - prevEntry->getIndex() + ((dist >> 1) & ~3U) : 0; - - if (newNumber == 0) { - needRenumber = true; - } + unsigned dist = ((nextEntry->getIndex() - prevEntry->getIndex())/2) & ~3u; + unsigned newNumber = prevEntry->getIndex() + dist; // Insert a new list entry for mi. - newEntry = createEntry(mi, newNumber); + IndexListEntry *newEntry = createEntry(mi, newNumber); insert(nextEntry, newEntry); - - SlotIndex newIndex(newEntry, SlotIndex::LOAD); - mi2iMap.insert(std::make_pair(mi, newIndex)); - - if (miItr == mbb->end()) { - // If this is the last instr in the MBB then we need to fix up the bb - // range: - mbbRangeItr->second.second = SlotIndex(newEntry, SlotIndex::STORE); - } - // Renumber if we need to. - if (needRenumber) { - if (deferredRenumber == 0) - renumberIndexes(); - else - *deferredRenumber = true; - } + // Renumber locally if we need to. + if (dist == 0) + renumberIndexes(newEntry); + SlotIndex newIndex(newEntry, SlotIndex::LOAD); + mi2iMap.insert(std::make_pair(mi, newIndex)); return newIndex; } - /// Add all instructions in the vector to the index list. This method will - /// defer renumbering until all instrs have been added, and should be - /// preferred when adding multiple instrs. - void insertMachineInstrsInMaps(SmallVectorImpl<MachineInstr*> &mis) { - bool renumber = false; - - for (SmallVectorImpl<MachineInstr*>::iterator - miItr = mis.begin(), miEnd = mis.end(); - miItr != miEnd; ++miItr) { - insertMachineInstrInMaps(*miItr, &renumber); - } - - if (renumber) - renumberIndexes(); - } - - /// Remove the given machine instruction from the mapping. void removeMachineInstrFromMaps(MachineInstr *mi) { // remove index -> MachineInstr and @@ -760,21 +728,14 @@ namespace llvm { SlotIndex startIdx(startEntry, SlotIndex::LOAD); SlotIndex endIdx(nextEntry, SlotIndex::LOAD); - mbb2IdxMap.insert( - std::make_pair(mbb, std::make_pair(startIdx, endIdx))); + assert(unsigned(mbb->getNumber()) == MBBRanges.size() && + "Blocks must be added in order"); + MBBRanges.push_back(std::make_pair(startIdx, endIdx)); idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb)); - if (MachineFunction::iterator(mbb) != mbb->getParent()->begin()) { - // Have to update the end index of the previous block. - MachineBasicBlock *priorMBB = - llvm::prior(MachineFunction::iterator(mbb)); - mbb2IdxMap[priorMBB].second = startIdx; - } - renumberIndexes(); std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare()); - } }; diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index fba3e48..829f580 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -59,6 +59,10 @@ public: virtual const MCSection *getEHFrameSection() const; + virtual void emitPersonalityValue(MCStreamer &Streamer, + const TargetMachine &TM, + const MCSymbol *Sym) const; + const MCSection *getDataRelSection() const { return DataRelSection; } /// getSectionForConstant - Given a constant with the SectionKind, return a @@ -81,6 +85,11 @@ public: getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. + virtual MCSymbol * + getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI) const; }; @@ -94,7 +103,7 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { /// const MCSection *TLSBSSSection; // Defaults to ".tbss". - /// TLSTLVSection - Section for thread local structure infomation. + /// TLSTLVSection - Section for thread local structure information. /// Contains the source code name of the variable, visibility and a pointer /// to the initial value (.tdata or .tbss). const MCSection *TLSTLVSection; // Defaults to ".tlv". @@ -172,9 +181,14 @@ public: MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. + virtual MCSymbol * + getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI) const; + virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; }; diff --git a/include/llvm/CompilerDriver/CompilationGraph.h b/include/llvm/CompilerDriver/CompilationGraph.h index e1eea32..951aff6 100644 --- a/include/llvm/CompilerDriver/CompilationGraph.h +++ b/include/llvm/CompilerDriver/CompilationGraph.h @@ -40,7 +40,7 @@ namespace llvmc { }; /// Edge - Represents an edge of the compilation graph. - class Edge : public llvm::RefCountedBaseVPTR<Edge> { + class Edge : public llvm::RefCountedBaseVPTR { public: Edge(const std::string& T) : ToolName_(T) {} virtual ~Edge() {} diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h index d0926ba..18a2b76 100644 --- a/include/llvm/CompilerDriver/Tool.h +++ b/include/llvm/CompilerDriver/Tool.h @@ -33,7 +33,7 @@ namespace llvmc { typedef llvm::StringSet<> InputLanguagesSet; /// Tool - Represents a single tool. - class Tool : public llvm::RefCountedBaseVPTR<Tool> { + class Tool : public llvm::RefCountedBaseVPTR { public: virtual ~Tool() {} diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index bf69375..755daa6 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -196,6 +196,9 @@ /* Define to 1 if you have the `udis86' library (-ludis86). */ #undef HAVE_LIBUDIS86 +/* Type of 1st arg on ELM Callback */ +#cmakedefine WIN32_ELMCB_PCSTR ${WIN32_ELMCB_PCSTR} + /* Define to 1 if you have the <limits.h> header file. */ #cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H} @@ -453,7 +456,7 @@ #cmakedefine HAVE_WRITEV ${HAVE_WRITEV} /* Define if the xdot.py program is available */ -#undef HAVE_XDOT_PY +#cmakedefine HAVE_XDOT_PY ${HAVE_XDOT_PY} /* Have host's _alloca */ #cmakedefine HAVE__ALLOCA ${HAVE__ALLOCA} @@ -585,7 +588,7 @@ #cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}" /* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */ -#undef LLVM_PATH_XDOT_PY +#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT_PY}" /* Installation prefix directory */ #cmakedefine LLVM_PREFIX "${LLVM_PREFIX}" diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 14c44b4..10a8935 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -567,6 +567,9 @@ /* LLVM architecture name for the native architecture, if available */ #undef LLVM_NATIVE_ARCH +/* LLVM name for the native AsmParser init function, if available */ +#undef LLVM_NATIVE_ASMPARSER + /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER @@ -672,6 +675,9 @@ /* Define if use udis86 library */ #undef USE_UDIS86 +/* Type of 1st arg on ELM Callback */ +#undef WIN32_ELMCB_PCSTR + /* Define to empty if `const' does not conform to ANSI C. */ #undef const diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index a679b95..9a9cb3b 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -61,6 +61,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter +/* LLVM name for the native AsmPrinter init function, if available */ +#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser + /* Define if this is Unixish platform */ #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} @@ -91,6 +94,9 @@ /* Define to path to twopi program if found or 'echo twopi' otherwise */ #cmakedefine LLVM_PATH_TWOPI "${LLVM_PATH_TWOPI}" +/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */ +#cmakedefine LLVM_PATH_XDOT_PY "${LLVM_PATH_XDOT.PY}" + /* Installation prefix directory */ #cmakedefine LLVM_PREFIX "${LLVM_PREFIX}" diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in index e7a04ee..4766a7a 100644 --- a/include/llvm/Config/llvm-config.h.in +++ b/include/llvm/Config/llvm-config.h.in @@ -61,6 +61,9 @@ /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER +/* LLVM name for the native AsmPrinter init function, if available */ +#undef LLVM_NATIVE_ASMPARSER + /* Define if this is Unixish platform */ #undef LLVM_ON_UNIX diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 38045fc..5f32ce0 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -47,10 +47,6 @@ protected: : User(ty, vty, Ops, NumOps) {} void destroyConstantImpl(); - - void setOperand(unsigned i, Value *V) { - User::setOperand(i, V); - } public: /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. @@ -90,15 +86,6 @@ public: /// FIXME: This really should not be in VMCore. PossibleRelocationsTy getRelocationInfo() const; - // Specialize get/setOperand for Users as their operands are always - // constants or BasicBlocks as well. - User *getOperand(unsigned i) { - return static_cast<User*>(User::getOperand(i)); - } - const User *getOperand(unsigned i) const { - return static_cast<const User*>(User::getOperand(i)); - } - /// getVectorElements - This method, which is only valid on constant of vector /// type, returns the elements of the vector in the specified smallvector. /// This handles breaking down a vector undef into undef elements, etc. For diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index c4768f8..eabc3a5 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -57,6 +57,8 @@ protected: public: static ConstantInt *getTrue(LLVMContext &Context); static ConstantInt *getFalse(LLVMContext &Context); + static Constant *getTrue(const Type *Ty); + static Constant *getFalse(const Type *Ty); /// If Ty is a vector type, return a Constant with a splat of the given /// value. Otherwise return a ConstantInt for the given value. @@ -425,6 +427,8 @@ public: const std::vector<Constant*> &V, bool Packed); static Constant *get(LLVMContext &Context, Constant *const *Vals, unsigned NumVals, bool Packed); + static Constant *get(LLVMContext &Context, bool Packed, + Constant * Val, ...) END_WITH_NULL; /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); @@ -599,6 +603,7 @@ struct OperandTraits<BlockAddress> : DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value) + //===----------------------------------------------------------------------===// /// ConstantExpr - a constant value that is initialized with an expression using /// other constant values. @@ -836,7 +841,7 @@ public: static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS); static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS); - /// Getelementptr form. std::vector<Value*> is only accepted for convenience: + /// Getelementptr form. Value* is only accepted for convenience; /// all elements must be Constant's. /// static Constant *getGetElementPtr(Constant *C, @@ -880,7 +885,7 @@ public: /// getIndices - Assert that this is an insertvalue or exactvalue /// expression and return the list of indices. - const SmallVector<unsigned, 4> &getIndices() const; + ArrayRef<unsigned> getIndices() const; /// getOpcodeName - Return a string representation for an opcode. const char *getOpcodeName() const; @@ -892,10 +897,7 @@ public: /// getWithOperands - This returns the current constant expression with the /// operands replaced with the specified values. The specified operands must /// match count and type with the existing ones. - Constant *getWithOperands(const std::vector<Constant*> &Ops) const { - return getWithOperands(&Ops[0], (unsigned)Ops.size()); - } - Constant *getWithOperands(Constant *const *Ops, unsigned NumOps) const; + Constant *getWithOperands(ArrayRef<Constant*> Ops) const; virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); diff --git a/include/llvm/DebugInfoProbe.h b/include/llvm/DebugInfoProbe.h new file mode 100644 index 0000000..78d00df --- /dev/null +++ b/include/llvm/DebugInfoProbe.h @@ -0,0 +1,67 @@ +//===-- DebugInfoProbe.h - DebugInfo Probe ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a probe, DebugInfoProbe, that can be used by pass +// manager to analyze how optimizer is treating debugging information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H +#define LLVM_TRANSFORMS_UTILS_DEBUGINFOPROBE_H + +#include "llvm/ADT/StringMap.h" + +namespace llvm { + class Function; + class Pass; + class DebugInfoProbeImpl; + + /// DebugInfoProbe - This class provides a interface to monitor + /// how an optimization pass is preserving debugging information. + class DebugInfoProbe { + public: + DebugInfoProbe(); + ~DebugInfoProbe(); + + /// initialize - Collect information before running an optimization pass. + void initialize(StringRef PName, Function &F); + + /// finalize - Collect information after running an optimization pass. This + /// must be used after initialization. + void finalize(Function &F); + + /// report - Report findings. This should be invoked after finalize. + void report(); + + private: + DebugInfoProbeImpl *pImpl; + }; + + /// DebugInfoProbeInfo - This class provides an interface that a pass manager + /// can use to manage debug info probes. + class DebugInfoProbeInfo { + StringMap<DebugInfoProbe *> Probes; + public: + DebugInfoProbeInfo() {} + + /// ~DebugInfoProbeInfo - Report data collected by all probes before deleting + /// them. + ~DebugInfoProbeInfo(); + + /// initialize - Collect information before running an optimization pass. + void initialize(Pass *P, Function &F); + + /// finalize - Collect information after running an optimization pass. This + /// must be used after initialization. + void finalize(Pass *P, Function &F); + }; + +} // End llvm namespace + +#endif diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index 56d1e3e..f1cb330 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -19,6 +19,7 @@ #define LLVM_DERIVED_TYPES_H #include "llvm/Type.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -147,7 +148,7 @@ class FunctionType : public DerivedType { FunctionType(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement - FunctionType(const Type *Result, const std::vector<const Type*> &Params, + FunctionType(const Type *Result, ArrayRef<const Type*> Params, bool IsVarArgs); public: @@ -156,7 +157,7 @@ public: /// static FunctionType *get( const Type *Result, ///< The result type - const std::vector<const Type*> &Params, ///< The types of the parameters + ArrayRef<const Type*> Params, ///< The types of the parameters bool isVarArg ///< Whether this is a variable argument length function ); @@ -166,7 +167,7 @@ public: const Type *Result, ///< The result type bool isVarArg ///< Whether this is a variable argument length function ) { - return get(Result, std::vector<const Type *>(), isVarArg); + return get(Result, ArrayRef<const Type *>(), isVarArg); } /// isValidReturnType - Return true if the specified type is valid as a return @@ -237,20 +238,19 @@ class StructType : public CompositeType { friend class TypeMap<StructValType, StructType>; StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - StructType(LLVMContext &C, - const std::vector<const Type*> &Types, bool isPacked); + StructType(LLVMContext &C, ArrayRef<const Type*> Types, bool isPacked); public: /// StructType::get - This static method is the primary way to create a /// StructType. /// static StructType *get(LLVMContext &Context, - const std::vector<const Type*> &Params, + ArrayRef<const Type*> Params, bool isPacked=false); /// StructType::get - Create an empty structure type. /// static StructType *get(LLVMContext &Context, bool isPacked=false) { - return get(Context, std::vector<const Type*>(), isPacked); + return get(Context, llvm::ArrayRef<const Type*>(), isPacked); } /// StructType::get - This static method is a convenience method for diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 71698fa..a01ad3a 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -21,6 +21,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/Mutex.h" #include "llvm/Target/TargetMachine.h" @@ -117,11 +118,11 @@ protected: /// The list of Modules that we are JIT'ing from. We use a SmallVector to /// optimize for the case where there is only one module. SmallVector<Module*, 1> Modules; - + void setTargetData(const TargetData *td) { TD = td; } - + /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -155,13 +156,15 @@ protected: /// pointer is invoked to create it. If this returns null, the JIT will /// abort. void *(*LazyFunctionCreator)(const std::string &); - + /// ExceptionTableRegister - If Exception Handling is set, the JIT will /// register dwarf tables with this function. typedef void (*EERegisterFn)(void*); EERegisterFn ExceptionTableRegister; EERegisterFn ExceptionTableDeregister; - std::vector<void*> AllExceptionTables; + /// This maps functions to their exception tables frames. + DenseMap<const Function*, void*> AllExceptionTables; + public: /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and @@ -182,7 +185,7 @@ public: /// \param GVsWithCode - Allocating globals with code breaks /// freeMachineCodeForFunction and is probably unsafe and bad for performance. /// However, we have clients who depend on this behavior, so we must support - /// it. Eventually, when we're willing to break some backwards compatability, + /// it. Eventually, when we're willing to break some backwards compatibility, /// this flag should be flipped to false, so that by default /// freeMachineCodeForFunction works. static ExecutionEngine *create(Module *M, @@ -213,7 +216,7 @@ public: virtual void addModule(Module *M) { Modules.push_back(M); } - + //===--------------------------------------------------------------------===// const TargetData *getTargetData() const { return TD; } @@ -226,7 +229,7 @@ public: /// defines FnName. This is very slow operation and shouldn't be used for /// general code. Function *FindFunctionNamed(const char *FnName); - + /// runFunction - Execute the specified function with the specified arguments, /// and return the result. virtual GenericValue runFunction(Function *F, @@ -243,8 +246,8 @@ public: /// /// \param isDtors - Run the destructors instead of constructors. void runStaticConstructorsDestructors(Module *module, bool isDtors); - - + + /// runFunctionAsMain - This is a helper function which wraps runFunction to /// handle the common task of starting up main with the specified argc, argv, /// and envp parameters. @@ -259,21 +262,21 @@ public: /// existing data in memory. Mappings are automatically removed when their /// GlobalValue is destroyed. void addGlobalMapping(const GlobalValue *GV, void *Addr); - + /// clearAllGlobalMappings - Clear all global mappings and start over again, /// for use in dynamic compilation scenarios to move globals. void clearAllGlobalMappings(); - + /// clearGlobalMappingsFromModule - Clear all global mappings that came from a /// particular module, because it has been removed from the JIT. void clearGlobalMappingsFromModule(Module *M); - + /// updateGlobalMapping - Replace an existing mapping for GV with a new /// address. This updates both maps as required. If "Addr" is null, the /// entry for the global is removed from the mappings. This returns the old /// value of the pointer, or null if it was not in the map. void *updateGlobalMapping(const GlobalValue *GV, void *Addr); - + /// getPointerToGlobalIfAvailable - This returns the address of the specified /// global value if it is has already been codegen'd, otherwise it returns /// null. @@ -294,7 +297,7 @@ public: /// different ways. Return the representation for a blockaddress of the /// specified block. virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0; - + /// getPointerToFunctionOrStub - If the specified function has been /// code-gen'd, return a pointer to the function. If not, compile it, or use /// a stub to implement lazy compilation if available. See @@ -398,7 +401,7 @@ public: void InstallLazyFunctionCreator(void* (*P)(const std::string &)) { LazyFunctionCreator = P; } - + /// InstallExceptionTableRegister - The JIT will use the given function /// to register the exception tables it generates. void InstallExceptionTableRegister(EERegisterFn F) { @@ -407,13 +410,26 @@ public: void InstallExceptionTableDeregister(EERegisterFn F) { ExceptionTableDeregister = F; } - + /// RegisterTable - Registers the given pointer as an exception table. It /// uses the ExceptionTableRegister function. - void RegisterTable(void* res) { + void RegisterTable(const Function *fn, void* res) { if (ExceptionTableRegister) { ExceptionTableRegister(res); - AllExceptionTables.push_back(res); + AllExceptionTables[fn] = res; + } + } + + /// DeregisterTable - Deregisters the exception frame previously registered + /// for the given function. + void DeregisterTable(const Function *Fn) { + if (ExceptionTableDeregister) { + DenseMap<const Function*, void*>::iterator frame = + AllExceptionTables.find(Fn); + if(frame != AllExceptionTables.end()) { + ExceptionTableDeregister(frame->second); + AllExceptionTables.erase(frame); + } } } @@ -429,7 +445,7 @@ protected: void EmitGlobalVariable(const GlobalVariable *GV); GenericValue getConstantValue(const Constant *C); - void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, + void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, const Type *Ty); }; @@ -540,8 +556,9 @@ public: /// setUseMCJIT - Set whether the MC-JIT implementation should be used /// (experimental). - void setUseMCJIT(bool Value) { + EngineBuilder &setUseMCJIT(bool Value) { UseMCJIT = Value; + return *this; } /// setMAttrs - Set cpu-specific attributes. diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h index 3841418..a63f0da 100644 --- a/include/llvm/ExecutionEngine/JITMemoryManager.h +++ b/include/llvm/ExecutionEngine/JITMemoryManager.h @@ -29,11 +29,11 @@ protected: public: JITMemoryManager() : HasGOT(false) {} virtual ~JITMemoryManager(); - + /// CreateDefaultMemManager - This is used to create the default /// JIT Memory Manager if the client does not provide one to the JIT. static JITMemoryManager *CreateDefaultMemManager(); - + /// setMemoryWritable - When code generation is in progress, /// the code pages may need permissions changed. virtual void setMemoryWritable() = 0; @@ -55,16 +55,16 @@ public: /// method is invoked to allocate it. This method is required to set HasGOT /// to true. virtual void AllocateGOT() = 0; - + /// isManagingGOT - Return true if the AllocateGOT method is called. bool isManagingGOT() const { return HasGOT; } - + /// getGOTBase - If this is managing a Global Offset Table, this method should /// return a pointer to its base. virtual uint8_t *getGOTBase() const = 0; - + //===--------------------------------------------------------------------===// // Main Allocation Functions //===--------------------------------------------------------------------===// @@ -91,11 +91,11 @@ public: /// startFunctionBody. virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, unsigned Alignment) = 0; - + /// endFunctionBody - This method is called when the JIT is done codegen'ing /// the specified function. At this point we know the size of the JIT /// compiled function. This passes in FunctionStart (which was returned by - /// the startFunctionBody method) and FunctionEnd which is a pointer to the + /// the startFunctionBody method) and FunctionEnd which is a pointer to the /// actual end of the function. This method should mark the space allocated /// and remember where it is in case the client wants to deallocate it. virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart, @@ -113,12 +113,12 @@ public: /// been deallocated yet. This is never called when the JIT is currently /// emitting a function. virtual void deallocateFunctionBody(void *Body) = 0; - + /// startExceptionTable - When we finished JITing the function, if exception /// handling is set, we emit the exception table. virtual uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) = 0; - + /// endExceptionTable - This method is called when the JIT is done emitting /// the exception table. virtual void endExceptionTable(const Function *F, uint8_t *TableStart, diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h new file mode 100644 index 0000000..3dc65e3 --- /dev/null +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -0,0 +1,75 @@ +//===-- RuntimeDyld.h - Run-time dynamic linker for MC-JIT ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Interface for the runtime dynamic linker facilities of the MC-JIT. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_RUNTIME_DYLD_H +#define LLVM_RUNTIME_DYLD_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Memory.h" + +namespace llvm { + +class RuntimeDyldImpl; +class MemoryBuffer; + +// RuntimeDyld clients often want to handle the memory management of +// what gets placed where. For JIT clients, this is an abstraction layer +// over the JITMemoryManager, which references objects by their source +// representations in LLVM IR. +// FIXME: As the RuntimeDyld fills out, additional routines will be needed +// for the varying types of objects to be allocated. +class RTDyldMemoryManager { + RTDyldMemoryManager(const RTDyldMemoryManager&); // DO NOT IMPLEMENT + void operator=(const RTDyldMemoryManager&); // DO NOT IMPLEMENT +public: + RTDyldMemoryManager() {} + virtual ~RTDyldMemoryManager(); + + // Allocate ActualSize bytes, or more, for the named function. Return + // a pointer to the allocated memory and update Size to reflect how much + // memory was acutally allocated. + virtual uint8_t *startFunctionBody(const char *Name, uintptr_t &Size) = 0; + + // Mark the end of the function, including how much of the allocated + // memory was actually used. + virtual void endFunctionBody(const char *Name, uint8_t *FunctionStart, + uint8_t *FunctionEnd) = 0; +}; + +class RuntimeDyld { + RuntimeDyld(const RuntimeDyld &); // DO NOT IMPLEMENT + void operator=(const RuntimeDyld &); // DO NOT IMPLEMENT + + // RuntimeDyldImpl is the actual class. RuntimeDyld is just the public + // interface. + RuntimeDyldImpl *Dyld; +public: + RuntimeDyld(RTDyldMemoryManager*); + ~RuntimeDyld(); + + bool loadObject(MemoryBuffer *InputBuffer); + // Get the address of our local copy of the symbol. This may or may not + // be the address used for relocation (clients can copy the data around + // and resolve relocatons based on where they put it). + void *getSymbolAddress(StringRef Name); + // Resolve the relocations for all symbols we currently know about. + void resolveRelocations(); + // Change the address associated with a symbol when resolving relocations. + // Any relocations already associated with the symbol will be re-resolved. + void reassignSymbolAddress(StringRef Name, uint8_t *Addr); + StringRef getErrorString(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 1769c66..442e0c0 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -12,7 +12,7 @@ // // Global variables are constant pointers that refer to hunks of space that are // allocated by either the VM, or by the linker in a static compiler. A global -// variable may have an intial value, which is copied into the executables .data +// variable may have an initial value, which is copied into the executables .data // area. Global Constants are required to have initializers. // //===----------------------------------------------------------------------===// diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 02dbfbd..cca0194 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -94,12 +94,12 @@ void initializeDominatorTreePass(PassRegistry&); void initializeEdgeBundlesPass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&); void initializePathProfilerPass(PassRegistry&); +void initializeGCOVProfilerPass(PassRegistry&); void initializeEarlyCSEPass(PassRegistry&); void initializeExpandISelPseudosPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&); -void initializeGEPSplitterPass(PassRegistry&); void initializeGVNPass(PassRegistry&); void initializeGlobalDCEPass(PassRegistry&); void initializeGlobalOptPass(PassRegistry&); @@ -123,7 +123,6 @@ void initializeLintPass(PassRegistry&); void initializeLiveDebugVariablesPass(PassRegistry&); void initializeLiveIntervalsPass(PassRegistry&); void initializeLiveStacksPass(PassRegistry&); -void initializeLiveValuesPass(PassRegistry&); void initializeLiveVariablesPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&); void initializePathProfileLoaderPassPass(PassRegistry&); @@ -170,7 +169,6 @@ void initializePostDomOnlyPrinterPass(PassRegistry&); void initializePostDomOnlyViewerPass(PassRegistry&); void initializePostDomPrinterPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&); -void initializePostDominanceFrontierPass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&); void initializePreAllocSplittingPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&); @@ -196,14 +194,12 @@ void initializeRegionViewerPass(PassRegistry&); void initializeRegisterCoalescerAnalysisGroup(PassRegistry&); void initializeRenderMachineFunctionPass(PassRegistry&); void initializeSCCPPass(PassRegistry&); -void initializeSRETPromotionPass(PassRegistry&); void initializeSROA_DTPass(PassRegistry&); void initializeSROA_SSAUpPass(PassRegistry&); void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&); void initializeScalarEvolutionPass(PassRegistry&); void initializeSimpleInlinerPass(PassRegistry&); void initializeSimpleRegisterCoalescingPass(PassRegistry&); -void initializeSimplifyHalfPowrLibCallsPass(PassRegistry&); void initializeSimplifyLibCallsPass(PassRegistry&); void initializeSingleLoopExtractorPass(PassRegistry&); void initializeSinkingPass(PassRegistry&); diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index a166956..cc9ec3a 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -18,7 +18,6 @@ #include "llvm/Instruction.h" #include "llvm/OperandTraits.h" -#include "llvm/Operator.h" #include "llvm/DerivedTypes.h" #include "llvm/ADT/Twine.h" diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 17ff763..54dfe39 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -584,7 +584,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// @brief Represent an integer comparison operator. class ICmpInst: public CmpInst { protected: - /// @brief Clone an indentical ICmpInst + /// @brief Clone an identical ICmpInst virtual ICmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. @@ -735,7 +735,7 @@ public: /// @brief Represents a floating point comparison operator. class FCmpInst: public CmpInst { protected: - /// @brief Clone an indentical FCmpInst + /// @brief Clone an identical FCmpInst virtual FCmpInst *clone_impl() const; public: /// @brief Constructor with insert-before-instruction semantics. @@ -1811,39 +1811,37 @@ class PHINode : public Instruction { void *operator new(size_t s) { return User::operator new(s, 0); } - explicit PHINode(const Type *Ty, const Twine &NameStr = "", - Instruction *InsertBefore = 0) + explicit PHINode(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), - ReservedSpace(0) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); + OperandList = allocHungoffUses(ReservedSpace); } - PHINode(const Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd) + PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), - ReservedSpace(0) { + ReservedSpace(NumReservedValues * 2) { setName(NameStr); + OperandList = allocHungoffUses(ReservedSpace); } protected: virtual PHINode *clone_impl() const; public: - static PHINode *Create(const Type *Ty, const Twine &NameStr = "", + /// Constructors - NumReservedValues is a hint for the number of incoming + /// edges that this phi node will have (use 0 if you really have no idea). + static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr = "", Instruction *InsertBefore = 0) { - return new PHINode(Ty, NameStr, InsertBefore); + return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore); } - static PHINode *Create(const Type *Ty, const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new PHINode(Ty, NameStr, InsertAtEnd); + static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } ~PHINode(); - /// reserveOperandSpace - This method can be used to avoid repeated - /// reallocation of PHI operand lists by reserving space for the correct - /// number of operands before adding them. Unlike normal vector reserves, - /// this method can also be used to trim the operand space. - void reserveOperandSpace(unsigned NumValues) { - resizeOperands(NumValues*2); - } - /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -1912,7 +1910,7 @@ public: "All operands to PHI node must be the same type as the PHI node!"); unsigned OpNo = NumOperands; if (OpNo+2 > ReservedSpace) - resizeOperands(0); // Get more space! + growOperands(); // Get more space! // Initialize some new operands. NumOperands = OpNo+2; OperandList[OpNo] = V; @@ -1962,7 +1960,7 @@ public: return isa<Instruction>(V) && classof(cast<Instruction>(V)); } private: - void resizeOperands(unsigned NumOperands); + void growOperands(); }; template <> @@ -2154,7 +2152,7 @@ class SwitchInst : public TerminatorInst { // Operand[2n+1] = BasicBlock to go to on match SwitchInst(const SwitchInst &SI); void init(Value *Value, BasicBlock *Default, unsigned NumReserved); - void resizeOperands(unsigned No); + void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); @@ -2306,7 +2304,7 @@ class IndirectBrInst : public TerminatorInst { // Operand[2n+1] = BasicBlock to go to on match IndirectBrInst(const IndirectBrInst &IBI); void init(Value *Address, unsigned NumDests); - void resizeOperands(unsigned No); + void growOperands(); // allocate space for exactly zero operands void *operator new(size_t s) { return User::operator new(s, 0); diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 0c9be78..a63cd6a 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -30,7 +30,7 @@ class IntrinsicProperty; def IntrNoMem : IntrinsicProperty; // IntrReadArgMem - This intrinsic reads only from memory that one of its -// arguments points to, but may read an unspecified amount. +// pointer-typed arguments points to, but may read an unspecified amount. def IntrReadArgMem : IntrinsicProperty; // IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be @@ -307,7 +307,7 @@ let Properties = [IntrNoMem] in { def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_ptr_ty]>; +def int_eh_sjlj_dispatch_setup : Intrinsic<[], []>; def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; @@ -490,3 +490,4 @@ include "llvm/IntrinsicsARM.td" include "llvm/IntrinsicsCellSPU.td" include "llvm/IntrinsicsAlpha.td" include "llvm/IntrinsicsXCore.td" +include "llvm/IntrinsicsPTX.td" diff --git a/include/llvm/IntrinsicsARM.td b/include/llvm/IntrinsicsARM.td index 546538a..03e9261 100644 --- a/include/llvm/IntrinsicsARM.td +++ b/include/llvm/IntrinsicsARM.td @@ -1,10 +1,10 @@ //===- IntrinsicsARM.td - Defines ARM intrinsics -----------*- tablegen -*-===// -// +// // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. -// +// //===----------------------------------------------------------------------===// // // This file defines all of the ARM-specific intrinsics. @@ -129,8 +129,12 @@ let Properties = [IntrNoMem, Commutative] in { def int_arm_neon_vmulp : Neon_2Arg_Intrinsic; def int_arm_neon_vqdmulh : Neon_2Arg_Intrinsic; def int_arm_neon_vqrdmulh : Neon_2Arg_Intrinsic; + def int_arm_neon_vmulls : Neon_2Arg_Long_Intrinsic; + def int_arm_neon_vmullu : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vmullp : Neon_2Arg_Long_Intrinsic; def int_arm_neon_vqdmull : Neon_2Arg_Long_Intrinsic; + + // Vector Multiply and Accumulate/Subtract. def int_arm_neon_vqdmlal : Neon_3Arg_Long_Intrinsic; def int_arm_neon_vqdmlsl : Neon_3Arg_Long_Intrinsic; diff --git a/include/llvm/IntrinsicsPTX.td b/include/llvm/IntrinsicsPTX.td new file mode 100644 index 0000000..28379c9 --- /dev/null +++ b/include/llvm/IntrinsicsPTX.td @@ -0,0 +1,92 @@ +//===- IntrinsicsPTX.td - Defines PTX intrinsics -----------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines all of the PTX-specific intrinsics. +// +//===----------------------------------------------------------------------===// + +let TargetPrefix = "ptx" in { + multiclass PTXReadSpecialRegisterIntrinsic_v4i32<string prefix> { +// FIXME: Do we need the 128-bit integer type version? +// def _r64 : Intrinsic<[llvm_i128_ty], [], [IntrNoMem]>; + +// FIXME: Enable this once v4i32 support is enabled in back-end. +// def _v4i16 : Intrinsic<[llvm_v4i32_ty], [], [IntrNoMem]>; + + def _x : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<!strconcat(prefix, "_x")>; + def _y : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<!strconcat(prefix, "_y")>; + def _z : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<!strconcat(prefix, "_z")>; + def _w : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<!strconcat(prefix, "_w")>; + } + + class PTXReadSpecialRegisterIntrinsic_r32<string name> + : Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>, + GCCBuiltin<name>; + + class PTXReadSpecialRegisterIntrinsic_r64<string name> + : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>, + GCCBuiltin<name>; +} + +defm int_ptx_read_tid : PTXReadSpecialRegisterIntrinsic_v4i32 + <"__builtin_ptx_read_tid">; +defm int_ptx_read_ntid : PTXReadSpecialRegisterIntrinsic_v4i32 + <"__builtin_ptx_read_ntid">; + +def int_ptx_read_laneid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_laneid">; +def int_ptx_read_warpid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_warpid">; +def int_ptx_read_nwarpid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_nwarpid">; + +defm int_ptx_read_ctaid : PTXReadSpecialRegisterIntrinsic_v4i32 + <"__builtin_ptx_read_ctaid">; +defm int_ptx_read_nctaid : PTXReadSpecialRegisterIntrinsic_v4i32 + <"__builtin_ptx_read_nctaid">; + +def int_ptx_read_smid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_smid">; +def int_ptx_read_nsmid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_nsmid">; +def int_ptx_read_gridid : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_gridid">; + +def int_ptx_read_lanemask_eq : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_lanemask_eq">; +def int_ptx_read_lanemask_le : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_lanemask_le">; +def int_ptx_read_lanemask_lt : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_lanemask_lt">; +def int_ptx_read_lanemask_ge : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_lanemask_ge">; +def int_ptx_read_lanemask_gt : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_lanemask_gt">; + +def int_ptx_read_clock : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_clock">; +def int_ptx_read_clock64 : PTXReadSpecialRegisterIntrinsic_r64 + <"__builtin_ptx_read_clock64">; + +def int_ptx_read_pm0 : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_pm0">; +def int_ptx_read_pm1 : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_pm1">; +def int_ptx_read_pm2 : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_pm2">; +def int_ptx_read_pm3 : PTXReadSpecialRegisterIntrinsic_r32 + <"__builtin_ptx_read_pm3">; + +let TargetPrefix = "ptx" in + def int_ptx_bar_sync : Intrinsic<[], [llvm_i32_ty], []>, + GCCBuiltin<"__builtin_ptx_bar_sync">; diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td index 4946220..b44101a 100644 --- a/include/llvm/IntrinsicsX86.td +++ b/include/llvm/IntrinsicsX86.td @@ -18,6 +18,83 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". } //===----------------------------------------------------------------------===// +// 3DNow! + +let TargetPrefix = "x86" in { + def int_x86_3dnow_pavgusb : GCCBuiltin<"__builtin_ia32_pavgusb">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pf2id : GCCBuiltin<"__builtin_ia32_pf2id">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnow_pfacc : GCCBuiltin<"__builtin_ia32_pfacc">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfadd : GCCBuiltin<"__builtin_ia32_pfadd">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfcmpeq : GCCBuiltin<"__builtin_ia32_pfcmpeq">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfcmpge : GCCBuiltin<"__builtin_ia32_pfcmpge">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfcmpgt : GCCBuiltin<"__builtin_ia32_pfcmpgt">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfmax : GCCBuiltin<"__builtin_ia32_pfmax">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfmin : GCCBuiltin<"__builtin_ia32_pfmin">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfmul : GCCBuiltin<"__builtin_ia32_pfmul">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfrcp : GCCBuiltin<"__builtin_ia32_pfrcp">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnow_pfrcpit1 : GCCBuiltin<"__builtin_ia32_pfrcpit1">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfrcpit2 : GCCBuiltin<"__builtin_ia32_pfrcpit2">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfrsqrt : GCCBuiltin<"__builtin_ia32_pfrsqrt">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnow_pfrsqit1 : GCCBuiltin<"__builtin_ia32_pfrsqit1">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfsub : GCCBuiltin<"__builtin_ia32_pfsub">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pfsubr : GCCBuiltin<"__builtin_ia32_pfsubr">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnow_pi2fd : GCCBuiltin<"__builtin_ia32_pi2fd">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnow_pmulhrw : GCCBuiltin<"__builtin_ia32_pmulhrw">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; +} + +//===----------------------------------------------------------------------===// +// 3DNow! extensions + +let TargetPrefix = "x86" in { + def int_x86_3dnowa_pf2iw : GCCBuiltin<"__builtin_ia32_pf2iw">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnowa_pfnacc : GCCBuiltin<"__builtin_ia32_pfnacc">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnowa_pfpnacc : GCCBuiltin<"__builtin_ia32_pfpnacc">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty], + [IntrNoMem]>; + def int_x86_3dnowa_pi2fw : GCCBuiltin<"__builtin_ia32_pi2fw">, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; + def int_x86_3dnowa_pswapd : + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty], [IntrNoMem]>; +} + +//===----------------------------------------------------------------------===// // SSE1 // Arithmetic ops @@ -138,12 +215,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". llvm_x86mmx_ty], [IntrNoMem]>; } -// SIMD load ops -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse_loadu_ps : GCCBuiltin<"__builtin_ia32_loadups">, - Intrinsic<[llvm_v4f32_ty], [llvm_ptr_ty], [IntrReadMem]>; -} - // SIMD store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">, @@ -452,14 +523,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[llvm_v2f64_ty], [llvm_x86mmx_ty], [IntrNoMem]>; } -// SIMD load ops -let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". - def int_x86_sse2_loadu_pd : GCCBuiltin<"__builtin_ia32_loadupd">, - Intrinsic<[llvm_v2f64_ty], [llvm_ptr_ty], [IntrReadMem]>; - def int_x86_sse2_loadu_dq : GCCBuiltin<"__builtin_ia32_loaddqu">, - Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty], [IntrReadMem]>; -} - // SIMD store ops let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">, @@ -921,68 +984,68 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". // String/text processing ops. let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">, - Intrinsic<[llvm_v16i8_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">, - Intrinsic<[llvm_v16i8_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_v16i8_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">, - Intrinsic<[llvm_i32_ty], - [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, - llvm_i8_ty], - [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], + [llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty, + llvm_i8_ty], + [IntrNoMem]>; } //===----------------------------------------------------------------------===// @@ -1571,14 +1634,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.". Intrinsic<[], [llvm_ptrx86mmx_ty, llvm_x86mmx_ty], []>; def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">, - Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem]>; def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">, - Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty], + Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty], [IntrNoMem]>; def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">, - Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, + Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>; } diff --git a/include/llvm/IntrinsicsXCore.td b/include/llvm/IntrinsicsXCore.td index 944120f..e633af0 100644 --- a/include/llvm/IntrinsicsXCore.td +++ b/include/llvm/IntrinsicsXCore.td @@ -9,8 +9,13 @@ //===----------------------------------------------------------------------===// let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". + // Miscellaneous instructions. def int_xcore_bitrev : Intrinsic<[llvm_i32_ty],[llvm_i32_ty],[IntrNoMem]>; def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>; + def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>; + def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>; + def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>; + def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>; // Resource instructions. def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>; @@ -48,8 +53,37 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty], [NoCapture<0>]>; def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], + [NoCapture<0>, NoCapture<1>]>; + def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], + [NoCapture<0>, NoCapture<1>]>; + def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], + [NoCapture<0>]>; // Intrinsics for events. def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; + + // If any of the resources owned by the thread are ready this returns the + // vector of one of the ready resources. If no resources owned by the thread + // are ready then the operand passed to the intrinsic is returned. + def int_xcore_checkevent : Intrinsic<[llvm_ptr_ty],[llvm_ptr_ty]>; + def int_xcore_clre : Intrinsic<[],[],[]>; + + // Intrinsics for threads. + def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; + def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_ssync : Intrinsic <[],[]>; + def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>; + def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; + def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; } diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 69e1bd9..88ee65a 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -49,7 +49,6 @@ namespace { (void) llvm::createAliasAnalysisCounterPass(); (void) llvm::createAliasDebugger(); (void) llvm::createArgumentPromotionPass(); - (void) llvm::createStructRetPromotionPass(); (void) llvm::createBasicAliasAnalysisPass(); (void) llvm::createLibCallAliasAnalysisPass(0); (void) llvm::createScalarEvolutionAliasAnalysisPass(); @@ -71,6 +70,7 @@ namespace { (void) llvm::createEdgeProfilerPass(); (void) llvm::createOptimalEdgeProfilerPass(); (void) llvm::createPathProfilerPass(); + (void) llvm::createGCOVProfilerPass(true, true); (void) llvm::createFunctionInliningPass(); (void) llvm::createAlwaysInlinerPass(); (void) llvm::createGlobalDCEPass(); @@ -84,7 +84,6 @@ namespace { (void) llvm::createLCSSAPass(); (void) llvm::createLICMPass(); (void) llvm::createLazyValueInfoPass(); - (void) llvm::createLiveValuesPass(); (void) llvm::createLoopDependenceAnalysisPass(); (void) llvm::createLoopExtractorPass(); (void) llvm::createLoopSimplifyPass(); @@ -119,7 +118,6 @@ namespace { (void) llvm::createSCCPPass(); (void) llvm::createScalarReplAggregatesPass(); (void) llvm::createSimplifyLibCallsPass(); - (void) llvm::createSimplifyHalfPowrLibCallsPass(); (void) llvm::createSingleLoopExtractorPass(); (void) llvm::createStripSymbolsPass(); (void) llvm::createStripNonDebugSymbolsPass(); @@ -136,7 +134,6 @@ namespace { (void) llvm::createMemCpyOptPass(); (void) llvm::createLoopDeletionPass(); (void) llvm::createPostDomTree(); - (void) llvm::createPostDomFrontier(); (void) llvm::createInstructionNamerPass(); (void) llvm::createFunctionAttrsPass(); (void) llvm::createMergeFunctionsPass(); @@ -145,7 +142,6 @@ namespace { (void) llvm::createDbgInfoPrinterPass(); (void) llvm::createModuleDebugInfoPrinterPass(); (void) llvm::createPartialInliningPass(); - (void) llvm::createGEPSplitterPass(); (void) llvm::createLintPass(); (void) llvm::createSinkingPass(); (void) llvm::createLowerAtomicPass(); diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 0bf364a..8733161 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -20,13 +20,16 @@ #include <cassert> namespace llvm { + class MCExpr; class MCSection; + class MCStreamer; + class MCSymbol; class MCContext; /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. namespace ExceptionHandling { - enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj }; + enum ExceptionsType { None, DwarfTable, DwarfCFI, SjLj, ARM }; } class MCAsmInfo { @@ -66,10 +69,9 @@ namespace llvm { /// relative expressions. const char *PCSymbol; // Defaults to "$". - /// SeparatorChar - This character, if specified, is used to separate - /// instructions from each other when on the same line. This is used to - /// measure inline asm instructions. - char SeparatorChar; // Defaults to ';' + /// SeparatorString - This string, if specified, is used to separate + /// instructions from each other when on the same line. + const char *SeparatorString; // Defaults to ';' /// CommentColumn - This indicates the comment num (zero-based) at /// which asm comments should be printed. @@ -322,6 +324,16 @@ namespace llvm { return 0; } + virtual const MCExpr * + getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; + + const MCExpr * + getExprForFDESymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; + bool usesSunStyleELFSectionSwitchSyntax() const { return SunStyleELFSectionSwitchSyntax; } @@ -350,8 +362,8 @@ namespace llvm { const char *getPCSymbol() const { return PCSymbol; } - char getSeparatorChar() const { - return SeparatorChar; + const char *getSeparatorString() const { + return SeparatorString; } unsigned getCommentColumn() const { return CommentColumn; @@ -451,7 +463,8 @@ namespace llvm { bool isExceptionHandlingDwarf() const { return (ExceptionsType == ExceptionHandling::DwarfTable || - ExceptionsType == ExceptionHandling::DwarfCFI); + ExceptionsType == ExceptionHandling::DwarfCFI || + ExceptionsType == ExceptionHandling::ARM); } bool doesDwarfRequireFrameSection() const { diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h index 01cb000..a4585d1 100644 --- a/include/llvm/MC/MCAsmLayout.h +++ b/include/llvm/MC/MCAsmLayout.h @@ -36,8 +36,8 @@ private: /// List of sections in layout order. llvm::SmallVector<MCSectionData*, 16> SectionOrder; - /// The last fragment which was layed out, or 0 if nothing has been layed - /// out. Fragments are always layed out in order, so all fragments with a + /// The last fragment which was laid out, or 0 if nothing has been laid + /// out. Fragments are always laid out in order, so all fragments with a /// lower ordinal will be up to date. mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment; @@ -58,7 +58,7 @@ public: void Invalidate(MCFragment *F); /// \brief Perform layout for a single fragment, assuming that the previous - /// fragment has already been layed out correctly, and the parent section has + /// fragment has already been laid out correctly, and the parent section has /// been initialized. void LayoutFragment(MCFragment *Fragment); diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 30971c6..fc91966 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -706,7 +706,7 @@ private: /// \param DF The fragment the fixup is inside. /// \param Target [out] On return, the relocatable expression the fixup /// evaluates to. - /// \param Value [out] On return, the value of the fixup as currently layed + /// \param Value [out] On return, the value of the fixup as currently laid /// out. /// \return Whether the fixup value was fully resolved. This is true if the /// \arg Value result is fixed, otherwise the value may change due to @@ -745,7 +745,7 @@ private: MCFragment &F, const MCFixup &Fixup); public: - /// Compute the effective fragment size assuming it is layed out at the given + /// Compute the effective fragment size assuming it is laid out at the given /// \arg SectionAddress and \arg FragmentOffset. uint64_t ComputeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const; diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 7b26d54..070089e 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -45,12 +45,18 @@ namespace llvm { const TargetAsmInfo *TAI; + /// Allocator - Allocator object used for creating machine code objects. + /// + /// We use a bump pointer allocator to avoid the need to track all allocated + /// objects. + BumpPtrAllocator Allocator; + /// Symbols - Bindings of names to symbols. - StringMap<MCSymbol*> Symbols; + StringMap<MCSymbol*, BumpPtrAllocator&> Symbols; /// UsedNames - Keeps tracks of names that were used both for used declared /// and artificial symbols. - StringMap<bool> UsedNames; + StringMap<bool, BumpPtrAllocator&> UsedNames; /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary /// symbol. @@ -84,6 +90,11 @@ namespace llvm { MCDwarfLoc CurrentDwarfLoc; bool DwarfLocSeen; + /// Honor temporary labels, this is useful for debugging semantic + /// differences between temporary and non-temporary labels (primarily on + /// Darwin). + bool AllowTemporaryLabels; + /// The dwarf line information from the .loc directives for the sections /// with assembled machine instructions have after seeing .loc directives. DenseMap<const MCSection *, MCLineSection *> MCLineSections; @@ -91,12 +102,6 @@ namespace llvm { /// the elements were added. std::vector<const MCSection *> MCLineSectionOrder; - /// Allocator - Allocator object used for creating machine code objects. - /// - /// We use a bump pointer allocator to avoid the need to track all allocated - /// objects. - BumpPtrAllocator Allocator; - void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; MCSymbol *CreateSymbol(StringRef Name); @@ -109,6 +114,8 @@ namespace llvm { const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } + /// @name Symbol Management /// @{ diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index c9e42eb..ce8759a 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -10,12 +10,14 @@ #define MCDISASSEMBLER_H #include "llvm/Support/DataTypes.h" +#include "llvm-c/Disassembler.h" namespace llvm { class MCInst; class MemoryObject; class raw_ostream; +class MCContext; struct EDInstInfo; @@ -24,7 +26,7 @@ struct EDInstInfo; class MCDisassembler { public: /// Constructor - Performs initial setup for the disassembler. - MCDisassembler() {} + MCDisassembler() : GetOpInfo(0), DisInfo(0), Ctx(0) {} virtual ~MCDisassembler(); @@ -46,13 +48,37 @@ public: uint64_t address, raw_ostream &vStream) const = 0; - /// getEDInfo - Returns the enhanced insturction information corresponding to + /// getEDInfo - Returns the enhanced instruction information corresponding to /// the disassembler. /// /// @return - An array of instruction information, with one entry for /// each MCInst opcode this disassembler returns. /// NULL if there is no info for this target. virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; } + +private: + // + // Hooks for symbolic disassembly via the public 'C' interface. + // + // The function to get the symbolic information for operands. + LLVMOpInfoCallback GetOpInfo; + // The pointer to the block of symbolic information for above call back. + void *DisInfo; + // The assembly context for creating symbols and MCExprs in place of + // immediate operands when there is symbolic information. + MCContext *Ctx; + +public: + void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo, + void *disInfo, + MCContext *ctx) { + GetOpInfo = getOpInfo; + DisInfo = disInfo; + Ctx = ctx; + } + LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } + void *getDisInfoBlock() const { return DisInfo; } + MCContext *getMCContext() const { return Ctx; } }; } // namespace llvm diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 07a7bad..3bbcf3e 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -23,6 +23,7 @@ #include <vector> namespace llvm { + class TargetAsmInfo; class MachineMove; class MCContext; class MCExpr; @@ -230,7 +231,7 @@ namespace llvm { class MCCFIInstruction { public: - enum OpType { Remember, Restore, Move }; + enum OpType { SameValue, Remember, Restore, Move, RelMove }; private: OpType Operation; MCSymbol *Label; @@ -242,10 +243,19 @@ namespace llvm { : Operation(Op), Label(L) { assert(Op == Remember || Op == Restore); } + MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register) + : Operation(Op), Label(L), Destination(Register) { + assert(Op == SameValue); + } MCCFIInstruction(MCSymbol *L, const MachineLocation &D, const MachineLocation &S) : Operation(Move), Label(L), Destination(D), Source(S) { } + MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D, + const MachineLocation &S) + : Operation(Op), Label(L), Destination(D), Source(S) { + assert(Op == RelMove); + } OpType getOperation() const { return Operation; } MCSymbol *getLabel() const { return Label; } const MachineLocation &getDestination() const { return Destination; } @@ -254,12 +264,13 @@ namespace llvm { struct MCDwarfFrameInfo { MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), - Instructions(), PersonalityEncoding(0), + Function(0), Instructions(), PersonalityEncoding(), LsdaEncoding(0) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; const MCSymbol *Lsda; + const MCSymbol *Function; std::vector<MCCFIInstruction> Instructions; unsigned PersonalityEncoding; unsigned LsdaEncoding; @@ -270,9 +281,11 @@ namespace llvm { // // This emits the frame info section. // - static void Emit(MCStreamer &streamer); + static void Emit(MCStreamer &streamer, bool usingCFI); + static void EmitDarwin(MCStreamer &streamer, bool usingCFI); static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); - static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS); + static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS, + const TargetAsmInfo &AsmInfo); }; } // end namespace llvm diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index fea5249..521fde6 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -19,6 +19,7 @@ class MCAsmInfo; class MCAsmLayout; class MCAssembler; class MCContext; +class MCSection; class MCSectionData; class MCSymbol; class MCValue; @@ -92,6 +93,12 @@ public: /// @result - True on success. bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout &Layout) const; + /// FindAssociatedSection - Find the "associated section" for this expression, + /// which is currently defined as the absolute section for constants, or + /// otherwise the section associated with the first defined symbol in the + /// expression. + const MCSection *FindAssociatedSection() const; + /// @} static bool classof(const MCExpr *) { return true; } @@ -420,6 +427,7 @@ public: virtual bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const = 0; virtual void AddValueSymbols(MCAssembler *) const = 0; + virtual const MCSection *FindAssociatedSection() const = 0; static bool classof(const MCExpr *E) { return E->getKind() == MCExpr::Target; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 96716c7..0669558 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -25,9 +25,12 @@ protected: /// assembly emission is disable. raw_ostream *CommentStream; const MCAsmInfo &MAI; + + /// The current set of available features. + unsigned AvailableFeatures; public: MCInstPrinter(const MCAsmInfo &mai) - : CommentStream(0), MAI(mai) {} + : CommentStream(0), MAI(mai), AvailableFeatures(0) {} virtual ~MCInstPrinter(); @@ -41,6 +44,12 @@ public: /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. virtual StringRef getOpcodeName(unsigned Opcode) const; + + /// getRegName - Return the assembler register name. + virtual StringRef getRegName(unsigned RegNo) const; + + unsigned getAvailableFeatures() const { return AvailableFeatures; } + void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } }; } // namespace llvm diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 833341e..8b0d87a 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -38,6 +38,9 @@ class MCObjectStreamer : public MCStreamer { protected: MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); + MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, + raw_ostream &_OS, MCCodeEmitter *_Emitter, + MCAssembler *_Assembler); ~MCObjectStreamer(); MCSectionData *getCurrentSectionData() const { @@ -60,9 +63,9 @@ public: virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace); - virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); - virtual void EmitSLEB128Value(const MCExpr *Value, unsigned AddrSpace = 0); + unsigned AddrSpace); + virtual void EmitULEB128Value(const MCExpr *Value); + virtual void EmitSLEB128Value(const MCExpr *Value); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index 252696b..ab78799 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -49,6 +49,7 @@ public: virtual StringRef LexUntilEndOfStatement(); bool isAtStartOfComment(char Char); + bool isAtStatementSeparator(const char *Ptr); const MCAsmInfo &getMAI() const { return MAI; } diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 1c01b2f..5700817 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -14,7 +14,6 @@ #ifndef LLVM_MC_MCSECTION_H #define LLVM_MC_MCSECTION_H -#include <string> #include "llvm/ADT/StringRef.h" #include "llvm/MC/SectionKind.h" #include "llvm/Support/Casting.h" diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 7633515..bdb17e9 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -66,10 +66,10 @@ public: /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in /// the Reserved2 field. S_SYMBOL_STUBS = 0x08U, - /// S_SYMBOL_STUBS - Section with only function pointers for + /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for /// initialization. S_MOD_INIT_FUNC_POINTERS = 0x09U, - /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for + /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for /// termination. S_MOD_TERM_FUNC_POINTERS = 0x0AU, /// S_COALESCED - Section contains symbols that are to be coalesced. @@ -157,10 +157,12 @@ public: /// flavored .s file. If successful, this fills in the specified Out /// parameters and returns an empty string. When an invalid section /// specifier is present, this returns a string indicating the problem. + /// If no TAA was parsed, TAA is not altered, and TAAWasSet becomes false. static std::string ParseSectionSpecifier(StringRef Spec, // In. StringRef &Segment, // Out. StringRef &Section, // Out. unsigned &TAA, // Out. + bool &TAAParsed, // Out. unsigned &StubSize); // Out. virtual void PrintSwitchToSection(const MCAsmInfo &MAI, diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 4451199..b005c8b 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -50,13 +50,12 @@ namespace llvm { MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT - void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, - bool isPCRel, unsigned AddrSpace); - std::vector<MCDwarfFrameInfo> FrameInfos; MCDwarfFrameInfo *getCurrentFrameInfo(); void EnsureValidFrame(); + const MCSymbol* LastNonPrivate; + /// SectionStack - This is stack of current and previous section /// values saved by PushSection. SmallVector<std::pair<const MCSection *, @@ -65,6 +64,12 @@ namespace llvm { protected: MCStreamer(MCContext &Ctx); + const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, + const MCSymbol *B); + + const MCExpr *ForceExpAbs(MCStreamer *Streamer, MCContext &Context, + const MCExpr* Expr); + public: virtual ~MCStreamer(); @@ -180,7 +185,10 @@ namespace llvm { /// @param Symbol - The symbol to emit. A given symbol should only be /// emitted as a label once, and symbols emitted as a label should never be /// used in an assignment. - virtual void EmitLabel(MCSymbol *Symbol) = 0; + virtual void EmitLabel(MCSymbol *Symbol); + + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, + MCSymbol *EHSymbol); /// EmitAssemblerFlag - Note in the output the specified @p Flag virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0; @@ -300,13 +308,10 @@ namespace llvm { /// @param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - bool isPCRel, unsigned AddrSpace) = 0; + unsigned AddrSpace) = 0; void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); - void EmitPCRelValue(const MCExpr *Value, unsigned Size, - unsigned AddrSpace = 0); - /// EmitIntValue - Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. virtual void EmitIntValue(uint64_t Value, unsigned Size, @@ -319,11 +324,9 @@ namespace llvm { void EmitAbsValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0); - virtual void EmitULEB128Value(const MCExpr *Value, - unsigned AddrSpace = 0) = 0; + virtual void EmitULEB128Value(const MCExpr *Value) = 0; - virtual void EmitSLEB128Value(const MCExpr *Value, - unsigned AddrSpace = 0) = 0; + virtual void EmitSLEB128Value(const MCExpr *Value) = 0; /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. @@ -338,9 +341,6 @@ namespace llvm { void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace = 0); - void EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, - unsigned AddrSpace = 0); - /// EmitGPRel32Value - Emit the expression @p Value into the output as a /// gprel32 (32-bit GP relative) value. /// @@ -422,7 +422,8 @@ namespace llvm { virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, - unsigned Discriminator); + unsigned Discriminator, + StringRef FileName); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, @@ -435,17 +436,19 @@ namespace llvm { void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); - virtual bool EmitCFIStartProc(); - virtual bool EmitCFIEndProc(); - virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset); - virtual bool EmitCFIDefCfaOffset(int64_t Offset); - virtual bool EmitCFIDefCfaRegister(int64_t Register); - virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); - virtual bool EmitCFIPersonality(const MCSymbol *Sym, - unsigned Encoding); - virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); - virtual bool EmitCFIRememberState(); - virtual bool EmitCFIRestoreState(); + virtual void EmitCFIStartProc(); + virtual void EmitCFIEndProc(); + virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset); + virtual void EmitCFIDefCfaOffset(int64_t Offset); + virtual void EmitCFIDefCfaRegister(int64_t Register); + virtual void EmitCFIOffset(int64_t Register, int64_t Offset); + virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); + virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); + virtual void EmitCFIRememberState(); + virtual void EmitCFIRestoreState(); + virtual void EmitCFISameValue(int64_t Register); + virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset); + virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment); /// EmitInstruction - Emit the given @p Instruction into the current /// section. @@ -457,6 +460,19 @@ namespace llvm { virtual void EmitRawText(StringRef String); void EmitRawText(const Twine &String); + /// ARM-related methods. + /// FIXME: Eventually we should have some "target MC streamer" and move + /// these methods there. + virtual void EmitFnStart(); + virtual void EmitFnEnd(); + virtual void EmitCantUnwind(); + virtual void EmitPersonality(const MCSymbol *Personality); + virtual void EmitHandlerData(); + virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); + virtual void EmitPad(int64_t Offset); + virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, + bool isVector); + /// Finish - Finish emission of machine code. virtual void Finish() = 0; }; @@ -485,6 +501,7 @@ namespace llvm { MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, + bool useCFI, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, TargetAsmBackend *TAB = 0, diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 7da4d7c..0583ce5 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -56,6 +56,7 @@ namespace llvm { mutable unsigned IsUsed : 1; private: // MCContext creates and uniques these. + friend class MCExpr; friend class MCContext; MCSymbol(StringRef name, bool isTemporary) : Name(name), Section(0), Value(0), diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index a6c3f03..c323025 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -17,6 +17,7 @@ #define LLVM_METADATA_H #include "llvm/Value.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ilist_node.h" @@ -110,28 +111,25 @@ class MDNode : public Value, public FoldingSetNode { void replaceOperand(MDNodeOperand *Op, Value *NewVal); ~MDNode(); - MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, - bool isFunctionLocal); + MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal); - static MDNode *getMDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals, + static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals, FunctionLocalness FL, bool Insert = true); public: // Constructors and destructors. - static MDNode *get(LLVMContext &Context, Value *const *Vals, - unsigned NumVals); + static MDNode *get(LLVMContext &Context, ArrayRef<Value*> Vals); // getWhenValsUnresolved - Construct MDNode determining function-localness // from isFunctionLocal argument, not by analyzing Vals. - static MDNode *getWhenValsUnresolved(LLVMContext &Context, Value *const *Vals, - unsigned NumVals, bool isFunctionLocal); + static MDNode *getWhenValsUnresolved(LLVMContext &Context, + ArrayRef<Value*> Vals, + bool isFunctionLocal); - static MDNode *getIfExists(LLVMContext &Context, Value *const *Vals, - unsigned NumVals); + static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals); /// getTemporary - Return a temporary MDNode, for use in constructing /// cyclic MDNode structures. A temporary MDNode is not uniqued, /// may be RAUW'd, and must be manually deleted with deleteTemporary. - static MDNode *getTemporary(LLVMContext &Context, Value *const *Vals, - unsigned NumVals); + static MDNode *getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals); /// deleteTemporary - Deallocate a node created by getTemporary. The /// node must not have any users. diff --git a/include/llvm/Module.h b/include/llvm/Module.h index f95895e..aef8eb8 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -211,15 +211,20 @@ public: void setTargetTriple(StringRef T) { TargetTriple = T; } /// Set the module-scope inline assembly blocks. - void setModuleInlineAsm(StringRef Asm) { GlobalScopeAsm = Asm; } + void setModuleInlineAsm(StringRef Asm) { + GlobalScopeAsm = Asm; + if (!GlobalScopeAsm.empty() && + GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n') + GlobalScopeAsm += '\n'; + } /// Append to the module-scope inline assembly blocks, automatically inserting /// a separating newline if necessary. void appendModuleInlineAsm(StringRef Asm) { + GlobalScopeAsm += Asm; if (!GlobalScopeAsm.empty() && GlobalScopeAsm[GlobalScopeAsm.size()-1] != '\n') GlobalScopeAsm += '\n'; - GlobalScopeAsm += Asm; } /// @} @@ -303,7 +308,7 @@ public: /// 1. If it does not exist, add a declaration of the global and return it. /// 2. Else, the global exists but has the wrong type: return the function /// with a constantexpr cast to the right type. - /// 3. Finally, if the existing global is the correct delclaration, return + /// 3. Finally, if the existing global is the correct declaration, return /// the existing global. Constant *getOrInsertGlobal(StringRef Name, const Type *Ty); diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h index 03d9c14..19a399e 100644 --- a/include/llvm/Object/MachOObject.h +++ b/include/llvm/Object/MachOObject.h @@ -19,6 +19,7 @@ namespace llvm { class MemoryBuffer; +class raw_ostream; namespace object { @@ -172,7 +173,26 @@ public: InMemoryStruct<macho::Symbol64TableEntry> &Res) const; /// @} + + /// @name Object Dump Facilities + /// @{ + /// dump - Support for debugging, callable in GDB: V->dump() + // + void dump() const; + void dumpHeader() const; + + /// print - Implement operator<< on Value. + /// + void print(raw_ostream &O) const; + void printHeader(raw_ostream &O) const; + + /// @} }; + +inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) { + V.print(OS); + return OS; +} } // end namespace object } // end namespace llvm diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h index ed0fb39..04dd8b6 100644 --- a/include/llvm/Pass.h +++ b/include/llvm/Pass.h @@ -13,7 +13,7 @@ // Passes are designed this way so that it is possible to run passes in a cache // and organizationally optimal order without having to specify it at the front // end. This allows arbitrary passes to be strung together and have them -// executed as effeciently as possible. +// executed as efficiently as possible. // // Passes should extend one of the classes below, depending on the guarantees // that it can make about what will be modified as it is run. For example, most @@ -114,7 +114,7 @@ public: void dump() const; // dump - Print to stderr. /// createPrinterPass - Get a Pass appropriate to print the IR this - /// pass operates one (Module, Function or MachineFunction). + /// pass operates on (Module, Function or MachineFunction). virtual Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const = 0; @@ -320,7 +320,7 @@ class BasicBlockPass : public Pass { public: explicit BasicBlockPass(char &pid) : Pass(PT_BasicBlock, pid) {} - /// createPrinterPass - Get a function printer pass. + /// createPrinterPass - Get a basic block printer pass. Pass *createPrinterPass(raw_ostream &O, const std::string &Banner) const; /// doInitialization - Virtual method overridden by subclasses to do diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h index a3342d5..fede121 100644 --- a/include/llvm/PassAnalysisSupport.h +++ b/include/llvm/PassAnalysisSupport.h @@ -142,6 +142,8 @@ public: Pass *findImplPass(Pass *P, AnalysisID PI, Function &F); void addAnalysisImplsPair(AnalysisID PI, Pass *P) { + if (findImplPass(PI) == P) + return; std::pair<AnalysisID, Pass*> pir = std::make_pair(PI,P); AnalysisImpls.push_back(pir); } diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index c680709..a2ad24f 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -177,6 +177,9 @@ public: unsigned GetNumSlabs() const; void PrintStats() const; + + /// Compute the total physical memory allocated by this allocator. + size_t getTotalMemory() const; }; /// SpecificBumpPtrAllocator - Same as BumpPtrAllocator but allows only diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h index 9ba71fc..d2ea123 100644 --- a/include/llvm/Support/CFG.h +++ b/include/llvm/Support/CFG.h @@ -41,6 +41,7 @@ class PredIterator : public std::iterator<std::forward_iterator_tag, public: typedef typename super::pointer pointer; + PredIterator() {} explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) { advancePastNonTerminators(); } @@ -64,6 +65,12 @@ public: inline Self operator++(int) { // Postincrement Self tmp = *this; ++*this; return tmp; } + + /// getOperandNo - Return the operand number in the predecessor's + /// terminator of the successor. + unsigned getOperandNo() const { + return It.getOperandNo(); + } }; typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator; diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h index 6bb9806..abb5a9a 100644 --- a/include/llvm/Support/Casting.h +++ b/include/llvm/Support/Casting.h @@ -192,8 +192,8 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> { // cast<X> - Return the argument parameter cast to the specified type. This // casting operator asserts that the type is correct, so it does not return null -// on failure. But it will correctly return NULL when the input is NULL. -// Used Like this: +// on failure. It does not allow a null argument (use cast_or_null for that). +// It is typically used like this: // // cast<Instruction>(myVal)->getParent() // diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 9ae3d6a..d609871 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -60,6 +60,12 @@ void ParseEnvironmentOptions(const char *progName, const char *envvar, void SetVersionPrinter(void (*func)()); +// PrintOptionValues - Print option values. +// With -print-options print the difference between option values and defaults. +// With -print-all-options print all option values. +// (Currently not perfect, but best-effort.) +void PrintOptionValues(); + // MarkOptionsChanged - Internal helper function. void MarkOptionsChanged(); @@ -230,6 +236,8 @@ public: // virtual void printOptionInfo(size_t GlobalWidth) const = 0; + virtual void printOptionValue(size_t GlobalWidth, bool Force) const = 0; + virtual void getExtraOptionNames(SmallVectorImpl<const char*> &) {} // addOccurrence - Wrapper around handleOccurrence that enforces Flags. @@ -303,6 +311,120 @@ LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); } //===----------------------------------------------------------------------===// +// OptionValue class + +// Support value comparison outside the template. +struct GenericOptionValue { + virtual ~GenericOptionValue() {} + virtual bool compare(const GenericOptionValue &V) const = 0; +}; + +template<class DataType> struct OptionValue; + +// The default value safely does nothing. Option value printing is only +// best-effort. +template<class DataType, bool isClass> +struct OptionValueBase : public GenericOptionValue { + // Temporary storage for argument passing. + typedef OptionValue<DataType> WrapperType; + + bool hasValue() const { return false; } + + const DataType &getValue() const { assert(false && "no default value"); } + + // Some options may take their value from a different data type. + template<class DT> + void setValue(const DT& /*V*/) {} + + bool compare(const DataType &/*V*/) const { return false; } + + virtual bool compare(const GenericOptionValue& /*V*/) const { return false; } +}; + +// Simple copy of the option value. +template<class DataType> +class OptionValueCopy : public GenericOptionValue { + DataType Value; + bool Valid; +public: + OptionValueCopy() : Valid(false) {} + + bool hasValue() const { return Valid; } + + const DataType &getValue() const { + assert(Valid && "invalid option value"); + return Value; + } + + void setValue(const DataType &V) { Valid = true; Value = V; } + + bool compare(const DataType &V) const { + return Valid && (Value != V); + } + + virtual bool compare(const GenericOptionValue &V) const { + const OptionValueCopy<DataType> &VC = + static_cast< const OptionValueCopy<DataType>& >(V); + if (!VC.hasValue()) return false; + return compare(VC.getValue()); + } +}; + +// Non-class option values. +template<class DataType> +struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> { + typedef DataType WrapperType; +}; + +// Top-level option class. +template<class DataType> +struct OptionValue : OptionValueBase<DataType, is_class<DataType>::value> { + OptionValue() {} + + OptionValue(const DataType& V) { + this->setValue(V); + } + // Some options may take their value from a different data type. + template<class DT> + OptionValue<DataType> &operator=(const DT& V) { + this->setValue(V); + return *this; + } +}; + +// Other safe-to-copy-by-value common option types. +enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; +template<> +struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> { + typedef cl::boolOrDefault WrapperType; + + OptionValue() {} + + OptionValue(const cl::boolOrDefault& V) { + this->setValue(V); + } + OptionValue<cl::boolOrDefault> &operator=(const cl::boolOrDefault& V) { + setValue(V); + return *this; + } +}; + +template<> +struct OptionValue<std::string> : OptionValueCopy<std::string> { + typedef StringRef WrapperType; + + OptionValue() {} + + OptionValue(const std::string& V) { + this->setValue(V); + } + OptionValue<std::string> &operator=(const std::string& V) { + setValue(V); + return *this; + } +}; + +//===----------------------------------------------------------------------===// // Enum valued command line option // #define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC @@ -355,7 +477,6 @@ ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val, return Vals; } - //===----------------------------------------------------------------------===// // parser class - Parameterizable parser for different data types. By default, // known data types (string, int, bool) have specialized parsers, that do what @@ -368,7 +489,16 @@ ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val, // not need replicated for every instance of the generic parser. This also // allows us to put stuff into CommandLine.cpp // -struct generic_parser_base { +class generic_parser_base { +protected: + class GenericOptionInfo { + public: + GenericOptionInfo(const char *name, const char *helpStr) : + Name(name), HelpStr(helpStr) {} + const char *Name; + const char *HelpStr; + }; +public: virtual ~generic_parser_base() {} // Base class should have virtual-dtor // getNumOptions - Virtual function implemented by generic subclass to @@ -385,11 +515,28 @@ struct generic_parser_base { // Return the width of the option tag for printing... virtual size_t getOptionWidth(const Option &O) const; + virtual const GenericOptionValue &getOptionValue(unsigned N) const = 0; + // printOptionInfo - Print out information about this option. The // to-be-maintained width is specified. // virtual void printOptionInfo(const Option &O, size_t GlobalWidth) const; + void printGenericOptionDiff(const Option &O, const GenericOptionValue &V, + const GenericOptionValue &Default, + size_t GlobalWidth) const; + + // printOptionDiff - print the value of an option and it's default. + // + // Template definition ensures that the option and default have the same + // DataType (via the same AnyOptionValue). + template<class AnyOptionValue> + void printOptionDiff(const Option &O, const AnyOptionValue &V, + const AnyOptionValue &Default, + size_t GlobalWidth) const { + printGenericOptionDiff(O, V, Default, GlobalWidth); + } + void initialize(Option &O) { // All of the modifiers for the option have been processed by now, so the // argstr field should be stable, copy it down now. @@ -443,13 +590,11 @@ protected: template <class DataType> class parser : public generic_parser_base { protected: - class OptionInfo { + class OptionInfo : public GenericOptionInfo { public: OptionInfo(const char *name, DataType v, const char *helpStr) : - Name(name), V(v), HelpStr(helpStr) {} - const char *Name; - DataType V; - const char *HelpStr; + GenericOptionInfo(name, helpStr), V(v) {} + OptionValue<DataType> V; }; SmallVector<OptionInfo, 8> Values; public: @@ -462,6 +607,11 @@ public: return Values[N].HelpStr; } + // getOptionValue - Return the value of option name N. + virtual const GenericOptionValue &getOptionValue(unsigned N) const { + return Values[N].V; + } + // parse - Return true on error. bool parse(Option &O, StringRef ArgName, StringRef Arg, DataType &V) { StringRef ArgVal; @@ -473,7 +623,7 @@ public: for (unsigned i = 0, e = static_cast<unsigned>(Values.size()); i != e; ++i) if (Values[i].Name == ArgVal) { - V = Values[i].V; + V = Values[i].V.getValue(); return false; } @@ -522,11 +672,19 @@ public: // void printOptionInfo(const Option &O, size_t GlobalWidth) const; + // printOptionNoValue - Print a placeholder for options that don't yet support + // printOptionDiff(). + void printOptionNoValue(const Option &O, size_t GlobalWidth) const; + // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "value"; } // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); + +protected: + // A helper for basic_parser::printOptionDiff. + void printOptionName(const Option &O, size_t GlobalWidth) const; }; // basic_parser - The real basic parser is just a template wrapper that provides @@ -536,6 +694,7 @@ template<class DataType> class basic_parser : public basic_parser_impl { public: typedef DataType parser_data_type; + typedef OptionValue<DataType> OptVal; }; //-------------------------------------------------- @@ -561,6 +720,9 @@ public: // getValueName - Do not print =<value> at all. virtual const char *getValueName() const { return 0; } + void printOptionDiff(const Option &O, bool V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -569,7 +731,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>); //-------------------------------------------------- // parser<boolOrDefault> -enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE }; template<> class parser<boolOrDefault> : public basic_parser<boolOrDefault> { public: @@ -583,6 +744,9 @@ public: // getValueName - Do not print =<value> at all. virtual const char *getValueName() const { return 0; } + void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -601,6 +765,9 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "int"; } + void printOptionDiff(const Option &O, int V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -620,6 +787,9 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "uint"; } + void printOptionDiff(const Option &O, unsigned V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -638,6 +808,9 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "number"; } + void printOptionDiff(const Option &O, double V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -656,6 +829,9 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "number"; } + void printOptionDiff(const Option &O, float V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -677,6 +853,9 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "string"; } + void printOptionDiff(const Option &O, StringRef V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; @@ -698,12 +877,63 @@ public: // getValueName - Overload in subclass to provide a better default value. virtual const char *getValueName() const { return "char"; } + void printOptionDiff(const Option &O, char V, OptVal Default, + size_t GlobalWidth) const; + // An out-of-line virtual method to provide a 'home' for this class. virtual void anchor(); }; EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>); +//-------------------------------------------------- +// PrintOptionDiff +// +// This collection of wrappers is the intermediary between class opt and class +// parser to handle all the template nastiness. + +// This overloaded function is selected by the generic parser. +template<class ParserClass, class DT> +void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V, + const OptionValue<DT> &Default, size_t GlobalWidth) { + OptionValue<DT> OV = V; + P.printOptionDiff(O, OV, Default, GlobalWidth); +} + +// This is instantiated for basic parsers when the parsed value has a different +// type than the option value. e.g. HelpPrinter. +template<class ParserDT, class ValDT> +struct OptionDiffPrinter { + void print(const Option &O, const parser<ParserDT> P, const ValDT &/*V*/, + const OptionValue<ValDT> &/*Default*/, size_t GlobalWidth) { + P.printOptionNoValue(O, GlobalWidth); + } +}; + +// This is instantiated for basic parsers when the parsed value has the same +// type as the option value. +template<class DT> +struct OptionDiffPrinter<DT, DT> { + void print(const Option &O, const parser<DT> P, const DT &V, + const OptionValue<DT> &Default, size_t GlobalWidth) { + P.printOptionDiff(O, V, Default, GlobalWidth); + } +}; + +// This overloaded function is selected by the basic parser, which may parse a +// different type than the option type. +template<class ParserClass, class ValDT> +void printOptionDiff( + const Option &O, + const basic_parser<typename ParserClass::parser_data_type> &P, + const ValDT &V, const OptionValue<ValDT> &Default, + size_t GlobalWidth) { + + OptionDiffPrinter<typename ParserClass::parser_data_type, ValDT> printer; + printer.print(O, static_cast<const ParserClass&>(P), V, Default, + GlobalWidth); +} + //===----------------------------------------------------------------------===// // applicator class - This class is used because we must use partial // specialization to handle literal string arguments specially (const char* does @@ -753,7 +983,6 @@ void apply(const Mod &M, Opt *O) { applicator<Mod>::opt(M, *O); } - //===----------------------------------------------------------------------===// // opt_storage class @@ -764,6 +993,7 @@ void apply(const Mod &M, Opt *O) { template<class DataType, bool ExternalStorage, bool isClass> class opt_storage { DataType *Location; // Where to store the object... + OptionValue<DataType> Default; void check() const { assert(Location != 0 && "cl::location(...) not specified for a command " @@ -777,21 +1007,25 @@ public: if (Location) return O.error("cl::location(x) specified more than once!"); Location = &L; + Default = L; return false; } template<class T> - void setValue(const T &V) { + void setValue(const T &V, bool initial = false) { check(); *Location = V; + if (initial) + Default = V; } DataType &getValue() { check(); return *Location; } const DataType &getValue() const { check(); return *Location; } operator DataType() const { return this->getValue(); } -}; + const OptionValue<DataType> &getDefault() const { return Default; } +}; // Define how to hold a class type object, such as a string. Since we can // inherit from a class, we do so. This makes us exactly compatible with the @@ -800,11 +1034,19 @@ public: template<class DataType> class opt_storage<DataType,false,true> : public DataType { public: + OptionValue<DataType> Default; + template<class T> - void setValue(const T &V) { DataType::operator=(V); } + void setValue(const T &V, bool initial = false) { + DataType::operator=(V); + if (initial) + Default = V; + } DataType &getValue() { return *this; } const DataType &getValue() const { return *this; } + + const OptionValue<DataType> &getDefault() const { return Default; } }; // Define a partial specialization to handle things we cannot inherit from. In @@ -815,16 +1057,23 @@ template<class DataType> class opt_storage<DataType, false, false> { public: DataType Value; + OptionValue<DataType> Default; // Make sure we initialize the value with the default constructor for the // type. opt_storage() : Value(DataType()) {} template<class T> - void setValue(const T &V) { Value = V; } + void setValue(const T &V, bool initial = false) { + Value = V; + if (initial) + Default = V; + } DataType &getValue() { return Value; } DataType getValue() const { return Value; } + const OptionValue<DataType> &getDefault() const { return Default; } + operator DataType() const { return getValue(); } // If the datatype is a pointer, support -> on it. @@ -866,13 +1115,20 @@ class opt : public Option, Parser.printOptionInfo(*this, GlobalWidth); } + virtual void printOptionValue(size_t GlobalWidth, bool Force) const { + if (Force || this->getDefault().compare(this->getValue())) { + cl::printOptionDiff<ParserClass>( + *this, Parser, this->getValue(), this->getDefault(), GlobalWidth); + } + } + void done() { addArgument(); Parser.initialize(*this); } public: // setInitialValue - Used by the cl::init modifier... - void setInitialValue(const DataType &V) { this->setValue(V); } + void setInitialValue(const DataType &V) { this->setValue(V, true); } ParserClass &getParser() { return Parser; } @@ -1030,6 +1286,9 @@ class list : public Option, public list_storage<DataType, Storage> { Parser.printOptionInfo(*this, GlobalWidth); } + // Unimplemented: list options don't currently store their default value. + virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + void done() { addArgument(); Parser.initialize(*this); @@ -1229,6 +1488,9 @@ class bits : public Option, public bits_storage<DataType, Storage> { Parser.printOptionInfo(*this, GlobalWidth); } + // Unimplemented: bits options don't currently store their default values. + virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + void done() { addArgument(); Parser.initialize(*this); @@ -1320,6 +1582,9 @@ class alias : public Option { virtual size_t getOptionWidth() const; virtual void printOptionInfo(size_t GlobalWidth) const; + // Aliases do not need to print their values. + virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {} + void done() { if (!hasArgStr()) error("cl::alias must have argument name specified!"); diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 67f0fd7..e092157 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -126,4 +126,12 @@ decl #endif +// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands +// to an expression which states that it is undefined behavior for the +// compiler to reach this point. Otherwise is not defined. +#if defined(__clang__) || (__GNUC__ > 4) \ + || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() +#endif + #endif diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index bd3765d..d0eaa3e 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -22,12 +22,10 @@ namespace llvm { -class LLVMContext; - /// ConstantFolder - Create constants with minimum, target independent, folding. class ConstantFolder { public: - explicit ConstantFolder(LLVMContext &) {} + explicit ConstantFolder() {} //===--------------------------------------------------------------------===// // Binary Operators diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 2e9b5d4..db835e8 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -15,6 +15,8 @@ namespace llvm { class StringRef; +class CrashRecoveryContextCleanup; + /// \brief Crash recovery helper object. /// /// This class implements support for running operations in a safe context so @@ -42,10 +44,14 @@ class StringRef; /// Crash recovery contexts may not be nested. class CrashRecoveryContext { void *Impl; + CrashRecoveryContextCleanup *head; public: - CrashRecoveryContext() : Impl(0) {} + CrashRecoveryContext() : Impl(0), head(0) {} ~CrashRecoveryContext(); + + void registerCleanup(CrashRecoveryContextCleanup *cleanup); + void unregisterCleanup(CrashRecoveryContextCleanup *cleanup); /// \brief Enable crash recovery. static void Enable(); @@ -57,6 +63,10 @@ public: /// thread which is in a protected context. static CrashRecoveryContext *GetCurrent(); + /// \brief Return true if the current thread is recovering from a + /// crash. + static bool isRecoveringFromCrash(); + /// \brief Execute the provide callback function (with the given arguments) in /// a protected context. /// @@ -87,6 +97,99 @@ public: const std::string &getBacktrace() const; }; +class CrashRecoveryContextCleanup { +protected: + CrashRecoveryContext *context; + CrashRecoveryContextCleanup(CrashRecoveryContext *context) + : context(context), cleanupFired(false) {} +public: + bool cleanupFired; + + virtual ~CrashRecoveryContextCleanup(); + virtual void recoverResources() = 0; + + CrashRecoveryContext *getContext() const { + return context; + } + +private: + friend class CrashRecoveryContext; + CrashRecoveryContextCleanup *prev, *next; +}; + +template<typename DERIVED, typename T> +class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup { +protected: + T *resource; + CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource) + : CrashRecoveryContextCleanup(context), resource(resource) {} +public: + static DERIVED *create(T *x) { + if (x) { + if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent()) + return new DERIVED(context, x); + } + return 0; + } +}; + +template <typename T> +class CrashRecoveryContextDestructorCleanup : public + CrashRecoveryContextCleanupBase<CrashRecoveryContextDestructorCleanup<T>, T> { +public: + CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context, + T *resource) + : CrashRecoveryContextCleanupBase< + CrashRecoveryContextDestructorCleanup<T>, T>(context, resource) {} + + virtual void recoverResources() { + this->resource->~T(); + } +}; + +template <typename T> +class CrashRecoveryContextDeleteCleanup : public + CrashRecoveryContextCleanupBase<CrashRecoveryContextDeleteCleanup<T>, T> { +public: + CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource) + : CrashRecoveryContextCleanupBase< + CrashRecoveryContextDeleteCleanup<T>, T>(context, resource) {} + + virtual void recoverResources() { + delete this->resource; + } +}; + +template <typename T> +class CrashRecoveryContextReleaseRefCleanup : public + CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T> +{ +public: + CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context, + T *resource) + : CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, + T>(context, resource) {} + + virtual void recoverResources() { + this->resource->Release(); + } +}; + +template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> > +class CrashRecoveryContextCleanupRegistrar { + CrashRecoveryContextCleanup *cleanup; +public: + CrashRecoveryContextCleanupRegistrar(T *x) + : cleanup(Cleanup::create(x)) { + if (cleanup) + cleanup->getContext()->registerCleanup(cleanup); + } + + ~CrashRecoveryContextCleanupRegistrar() { + if (cleanup && !cleanup->cleanupFired) + cleanup->getContext()->unregisterCleanup(cleanup); + } +}; } #endif diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h index 796c74a..3cb8164 100644 --- a/include/llvm/Support/DOTGraphTraits.h +++ b/include/llvm/Support/DOTGraphTraits.h @@ -89,8 +89,9 @@ public: /// If you want to override the dot attributes printed for a particular edge, /// override this method. - template<typename EdgeIter> - static std::string getEdgeAttributes(const void *Node, EdgeIter EI) { + template<typename EdgeIter, typename GraphType> + static std::string getEdgeAttributes(const void *Node, EdgeIter EI, + const GraphType& Graph) { return ""; } diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h index ccc3446..98a05a4 100644 --- a/include/llvm/Support/DebugLoc.h +++ b/include/llvm/Support/DebugLoc.h @@ -15,6 +15,8 @@ #ifndef LLVM_SUPPORT_DEBUGLOC_H #define LLVM_SUPPORT_DEBUGLOC_H +#include "llvm/ADT/DenseMapInfo.h" + namespace llvm { class MDNode; class LLVMContext; @@ -23,6 +25,24 @@ namespace llvm { /// and MachineInstr to compactly encode file/line/scope information for an /// operation. class DebugLoc { + friend struct DenseMapInfo<DebugLoc>; + + /// getEmptyKey() - A private constructor that returns an unknown that is + /// not equal to the tombstone key or DebugLoc(). + static DebugLoc getEmptyKey() { + DebugLoc DL; + DL.LineCol = 1; + return DL; + } + + /// getTombstoneKey() - A private constructor that returns an unknown that + /// is not equal to the empty key or DebugLoc(). + static DebugLoc getTombstoneKey() { + DebugLoc DL; + DL.LineCol = 2; + return DL; + } + /// LineCol - This 32-bit value encodes the line and column number for the /// location, encoded as 24-bits for line and 8 bits for col. A value of 0 /// for either means unknown. @@ -75,6 +95,14 @@ namespace llvm { } bool operator!=(const DebugLoc &DL) const { return !(*this == DL); } }; + + template <> + struct DenseMapInfo<DebugLoc> { + static DebugLoc getEmptyKey(); + static DebugLoc getTombstoneKey(); + static unsigned getHashValue(const DebugLoc &Key); + static bool isEqual(const DebugLoc &LHS, const DebugLoc &RHS); + }; } // end namespace llvm #endif /* LLVM_DEBUGLOC_H */ diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 5d0b5a9..f6d680b 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -231,6 +231,10 @@ enum dwarf_constants { DW_AT_APPLE_major_runtime_vers = 0x3fe5, DW_AT_APPLE_runtime_class = 0x3fe6, DW_AT_APPLE_omit_frame_ptr = 0x3fe7, + DW_AT_APPLE_property_name = 0x3fe8, + DW_AT_APPLE_property_getter = 0x3fe9, + DW_AT_APPLE_property_setter = 0x3fea, + DW_AT_APPLE_property_attribute = 0x3feb, // Attribute form encodings DW_FORM_addr = 0x01, @@ -407,6 +411,7 @@ enum dwarf_constants { DW_OP_call_ref = 0x9a, DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, + DW_OP_bit_piece = 0x9d, DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff, @@ -584,7 +589,15 @@ enum dwarf_constants { DW_EH_PE_datarel = 0x30, DW_EH_PE_funcrel = 0x40, DW_EH_PE_aligned = 0x50, - DW_EH_PE_indirect = 0x80 + DW_EH_PE_indirect = 0x80, + + // Apple Objective-C Property Attributes + DW_APPLE_PROPERTY_readonly = 0x01, + DW_APPLE_PROPERTY_readwrite = 0x02, + DW_APPLE_PROPERTY_assign = 0x04, + DW_APPLE_PROPERTY_retain = 0x08, + DW_APPLE_PROPERTY_copy = 0x10, + DW_APPLE_PROPERTY_nonatomic = 0x20 }; /// TagString - Return the string for the specified tag. diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h index 5eca438..95b0109 100644 --- a/include/llvm/Support/ErrorHandling.h +++ b/include/llvm/Support/ErrorHandling.h @@ -86,16 +86,19 @@ namespace llvm { unsigned line=0); } -/// Prints the message and location info to stderr in !NDEBUG builds. -/// This is intended to be used for "impossible" situations that imply -/// a bug in the compiler. +/// Marks that the current location is not supposed to be reachable. +/// In !NDEBUG builds, prints the message and location info to stderr. +/// In NDEBUG builds, becomes an optimizer hint that the current location +/// is not supposed to be reachable. On compilers that don't support +/// such hints, prints a reduced message instead. /// -/// In NDEBUG mode it only prints "UNREACHABLE executed". -/// Use this instead of assert(0), so that the compiler knows this path -/// is not reachable even for NDEBUG builds. +/// Use this instead of assert(0). It conveys intent more clearly and +/// allows compilers to omit some unnecessary code. #ifndef NDEBUG #define llvm_unreachable(msg) \ ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) +#elif defined(LLVM_BUILTIN_UNREACHABLE) +#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE #else #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() #endif diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 4001bf0..4f013f8 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -595,7 +595,7 @@ public: void replace_filename(const Twine &filename, file_status st = file_status(), file_status symlink_st = file_status()); - StringRef path() const { return Path; } + const std::string &path() const { return Path; } error_code status(file_status &result) const; error_code symlink_status(file_status &result) const; diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h index 748ce7c..5456eb7 100644 --- a/include/llvm/Support/FileUtilities.h +++ b/include/llvm/Support/FileUtilities.h @@ -15,13 +15,14 @@ #ifndef LLVM_SUPPORT_FILEUTILITIES_H #define LLVM_SUPPORT_FILEUTILITIES_H +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" namespace llvm { /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if /// the files match, 1 if they are different, and 2 if there is a file error. - /// This function allows you to specify an absolete and relative FP error that + /// This function allows you to specify an absolute and relative FP error that /// is allowed to exist. If you specify a string to fill in for the error /// option, it will set the string to an error message if an error occurs, or /// if the files are different. @@ -37,29 +38,36 @@ namespace llvm { /// specified (if deleteIt is true). /// class FileRemover { - sys::Path Filename; + SmallString<128> Filename; bool DeleteIt; public: FileRemover() : DeleteIt(false) {} - explicit FileRemover(const sys::Path &filename, bool deleteIt = true) - : Filename(filename), DeleteIt(deleteIt) {} + explicit FileRemover(const Twine& filename, bool deleteIt = true) + : DeleteIt(deleteIt) { + filename.toVector(Filename); + } ~FileRemover() { if (DeleteIt) { // Ignore problems deleting the file. - Filename.eraseFromDisk(); + bool existed; + sys::fs::remove(Filename.str(), existed); } } /// setFile - Give ownership of the file to the FileRemover so it will /// be removed when the object is destroyed. If the FileRemover already /// had ownership of a file, remove it first. - void setFile(const sys::Path &filename, bool deleteIt = true) { - if (DeleteIt) - Filename.eraseFromDisk(); + void setFile(const Twine& filename, bool deleteIt = true) { + if (DeleteIt) { + // Ignore problems deleting the file. + bool existed; + sys::fs::remove(Filename.str(), existed); + } - Filename = filename; + Filename.clear(); + filename.toVector(Filename); DeleteIt = deleteIt; } diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h index 7573ef0..eab0c9d 100644 --- a/include/llvm/Support/GraphWriter.h +++ b/include/llvm/Support/GraphWriter.h @@ -70,7 +70,7 @@ class GraphWriter { for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) { std::string label = DTraits.getEdgeSourceLabel(Node, EI); - if (label == "") + if (label.empty()) continue; hasEdgeSourceLabels = true; @@ -78,7 +78,7 @@ class GraphWriter { if (i) O << "|"; - O << "<s" << i << ">" << DTraits.getEdgeSourceLabel(Node, EI); + O << "<s" << i << ">" << DOT::EscapeString(label); } if (EI != EE && hasEdgeSourceLabels) @@ -235,12 +235,12 @@ public: DestPort = static_cast<int>(Offset); } - if (DTraits.getEdgeSourceLabel(Node, EI) == "") + if (DTraits.getEdgeSourceLabel(Node, EI).empty()) edgeidx = -1; emitEdge(static_cast<const void*>(Node), edgeidx, static_cast<const void*>(TargetNode), DestPort, - DTraits.getEdgeAttributes(Node, EI)); + DTraits.getEdgeAttributes(Node, EI, G)); } } @@ -272,7 +272,7 @@ public: const void *DestNodeID, int DestNodePort, const std::string &Attrs) { if (SrcNodePort > 64) return; // Eminating from truncated part? - if (DestNodePort > 64) DestNodePort = 64; // Targetting the truncated part? + if (DestNodePort > 64) DestNodePort = 64; // Targeting the truncated part? O << "\tNode" << SrcNodeID; if (SrcNodePort >= 0) diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 2394a59..3878e79 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -17,6 +17,8 @@ #include "llvm/Instructions.h" #include "llvm/BasicBlock.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ConstantFolder.h" @@ -152,9 +154,10 @@ public: /// CreateGlobalString - Make a new global variable with an initializer that /// has array of i8 type filled in with the nul terminated string value - /// specified. If Name is specified, it is the name of the global variable - /// created. - Value *CreateGlobalString(const char *Str = "", const Twine &Name = ""); + /// specified. The new global variable will be marked mergable with any + /// others of the same contents. If Name is specified, it is the name of the + /// global variable created. + Value *CreateGlobalString(StringRef Str, const Twine &Name = ""); /// getInt1 - Get a constant value representing either true or false. ConstantInt *getInt1(bool V) { @@ -190,6 +193,10 @@ public: ConstantInt *getInt64(uint64_t C) { return ConstantInt::get(getInt64Ty(), C); } + + ConstantInt *getInt(const APInt &AI) { + return ConstantInt::get(Context, AI); + } //===--------------------------------------------------------------------===// // Type creation methods @@ -301,7 +308,7 @@ public: : IRBuilderBase(C), Inserter(I), Folder(F) { } - explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder(C) { + explicit IRBuilder(LLVMContext &C) : IRBuilderBase(C), Folder() { } explicit IRBuilder(BasicBlock *TheBB, const T &F) @@ -310,12 +317,12 @@ public: } explicit IRBuilder(BasicBlock *TheBB) - : IRBuilderBase(TheBB->getContext()), Folder(Context) { + : IRBuilderBase(TheBB->getContext()), Folder() { SetInsertPoint(TheBB); } explicit IRBuilder(Instruction *IP) - : IRBuilderBase(IP->getContext()), Folder(Context) { + : IRBuilderBase(IP->getContext()), Folder() { SetInsertPoint(IP); } @@ -325,7 +332,7 @@ public: } IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) - : IRBuilderBase(TheBB->getContext()), Folder(Context) { + : IRBuilderBase(TheBB->getContext()), Folder() { SetInsertPoint(TheBB, IP); } @@ -861,7 +868,7 @@ public: /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer /// with "i8*" type instead of a pointer to array of i8. - Value *CreateGlobalStringPtr(const char *Str = "", const Twine &Name = "") { + Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") { Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; @@ -1070,8 +1077,9 @@ public: // Instruction creation methods: Other Instructions //===--------------------------------------------------------------------===// - PHINode *CreatePHI(const Type *Ty, const Twine &Name = "") { - return Insert(PHINode::Create(Ty), Name); + PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues, + const Twine &Name = "") { + return Insert(PHINode::Create(Ty, NumReservedValues), Name); } CallInst *CreateCall(Value *Callee, const Twine &Name = "") { @@ -1101,6 +1109,11 @@ public: return Insert(CallInst::Create(Callee, Args, Args+5), Name); } + CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Arg, + const Twine &Name = "") { + return Insert(CallInst::Create(Callee, Arg.begin(), Arg.end(), Name)); + } + template<typename RandomAccessIterator> CallInst *CreateCall(Value *Callee, RandomAccessIterator ArgBegin, RandomAccessIterator ArgEnd, const Twine &Name = "") { diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h index 9c3f85b..37890e7 100644 --- a/include/llvm/Support/Memory.h +++ b/include/llvm/Support/Memory.h @@ -75,12 +75,12 @@ namespace sys { /// setExecutable - Before the JIT can run a block of code, it has to be /// given read and executable privilege. Return true if it is already r-x /// or the system is able to change its previlege. - static bool setExecutable (MemoryBlock &M, std::string *ErrMsg = 0); + static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0); /// setWritable - When adding to a block of code, the JIT may need /// to mark a block of code as RW since the protections are on page /// boundaries, and the JIT internal allocations are not page aligned. - static bool setWritable (MemoryBlock &M, std::string *ErrMsg = 0); + static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0); /// setRangeExecutable - Mark the page containing a range of addresses /// as executable. diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index b6243b7..d912e86 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -40,7 +40,8 @@ class MemoryBuffer { MemoryBuffer &operator=(const MemoryBuffer &); // DO NOT IMPLEMENT protected: MemoryBuffer() {} - void init(const char *BufStart, const char *BufEnd); + void init(const char *BufStart, const char *BufEnd, + bool RequiresNullTerminator); public: virtual ~MemoryBuffer(); @@ -63,21 +64,27 @@ public: /// specified, this means that the client knows that the file exists and that /// it has the specified size. static error_code getFile(StringRef Filename, OwningPtr<MemoryBuffer> &result, - int64_t FileSize = -1); + int64_t FileSize = -1, + bool RequiresNullTerminator = true); static error_code getFile(const char *Filename, OwningPtr<MemoryBuffer> &result, - int64_t FileSize = -1); + int64_t FileSize = -1, + bool RequiresNullTerminator = true); /// getOpenFile - Given an already-open file descriptor, read the file and /// return a MemoryBuffer. static error_code getOpenFile(int FD, const char *Filename, OwningPtr<MemoryBuffer> &result, - int64_t FileSize = -1); + size_t FileSize = -1, + size_t MapSize = -1, + off_t Offset = 0, + bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note /// that InputData must be null terminated. static MemoryBuffer *getMemBuffer(StringRef InputData, - StringRef BufferName = ""); + StringRef BufferName = "", + bool RequiresNullTerminator = true); /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, /// copying the contents and taking ownership of it. InputData does not @@ -112,6 +119,21 @@ public: static error_code getFileOrSTDIN(const char *Filename, OwningPtr<MemoryBuffer> &result, int64_t FileSize = -1); + + + //===--------------------------------------------------------------------===// + // Provided for performance analysis. + //===--------------------------------------------------------------------===// + + /// The kind of memory backing used to support the MemoryBuffer. + enum BufferKind { + MemoryBuffer_Malloc, + MemoryBuffer_MMap + }; + + /// Return information on the memory mechanism used to support the + /// MemoryBuffer. + virtual BufferKind getBufferKind() const = 0; }; } // end namespace llvm diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 92a9fd6..5ead26e 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -27,12 +27,10 @@ namespace llvm { -class LLVMContext; - /// NoFolder - Create "constants" (actually, instructions) with no folding. class NoFolder { public: - explicit NoFolder(LLVMContext &) {} + explicit NoFolder() {} //===--------------------------------------------------------------------===// // Binary Operators diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h index d7753a3..024bb39 100644 --- a/include/llvm/Support/PathV1.h +++ b/include/llvm/Support/PathV1.h @@ -608,14 +608,15 @@ namespace sys { /// /// This API is not intended for general use, clients should use /// MemoryBuffer::getFile instead. - static const char *MapInFilePages(int FD, uint64_t FileSize); + static const char *MapInFilePages(int FD, size_t FileSize, + off_t Offset); /// UnMapFilePages - Free pages mapped into the current process by /// MapInFilePages. /// /// This API is not intended for general use, clients should use /// MemoryBuffer::getFile instead. - static void UnMapFilePages(const char *Base, uint64_t FileSize); + static void UnMapFilePages(const char *Base, size_t FileSize); /// @} /// @name Data diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h index 948ae51..172480e 100644 --- a/include/llvm/Support/PatternMatch.h +++ b/include/llvm/Support/PatternMatch.h @@ -40,6 +40,23 @@ bool match(Val *V, const Pattern &P) { return const_cast<Pattern&>(P).match(V); } + +template<typename SubPattern_t> +struct OneUse_match { + SubPattern_t SubPattern; + + OneUse_match(const SubPattern_t &SP) : SubPattern(SP) {} + + template<typename OpTy> + bool match(OpTy *V) { + return V->hasOneUse() && SubPattern.match(V); + } +}; + +template<typename T> +inline OneUse_match<T> m_OneUse(const T &SubPattern) { return SubPattern; } + + template<typename Class> struct class_match { template<typename ITy> @@ -227,7 +244,25 @@ struct specificval_ty { /// m_Specific - Match if we have a specific specified value. inline specificval_ty m_Specific(const Value *V) { return V; } +struct bind_const_intval_ty { + uint64_t &VR; + bind_const_intval_ty(uint64_t &V) : VR(V) {} + + template<typename ITy> + bool match(ITy *V) { + if (ConstantInt *CV = dyn_cast<ConstantInt>(V)) + if (CV->getBitWidth() <= 64) { + VR = CV->getZExtValue(); + return true; + } + return false; + } +}; +/// m_ConstantInt - Match a ConstantInt and bind to its value. This does not +/// match ConstantInts wider than 64-bits. +inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; } + //===----------------------------------------------------------------------===// // Matchers for specific binary operators. // diff --git a/include/llvm/Support/PrettyStackTrace.h b/include/llvm/Support/PrettyStackTrace.h index 6dbce39..9b3ecda 100644 --- a/include/llvm/Support/PrettyStackTrace.h +++ b/include/llvm/Support/PrettyStackTrace.h @@ -20,7 +20,7 @@ namespace llvm { class raw_ostream; /// DisablePrettyStackTrace - Set this to true to disable this module. This - /// might be neccessary if the host application installs its own signal + /// might be necessary if the host application installs its own signal /// handlers which conflict with the ones installed by this module. /// Defaults to false. extern bool DisablePrettyStackTrace; diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 78a495e..96b3566 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -102,7 +102,7 @@ namespace sys { ); /// This function terminates the program. - /// @returns true if an error occured. + /// @returns true if an error occurred. /// @see Execute /// @brief Terminates the program. bool Kill diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h index b46a668..7648e77 100644 --- a/include/llvm/Support/Regex.h +++ b/include/llvm/Support/Regex.h @@ -53,7 +53,7 @@ namespace llvm { /// matches - Match the regex against a given \arg String. /// - /// \param Matches - If given, on a succesful match this will be filled in + /// \param Matches - If given, on a successful match this will be filled in /// with references to the matched group expressions (inside \arg String), /// the first group is always the entire pattern. /// diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h index 9a84df6..634f4cf 100644 --- a/include/llvm/Support/Signals.h +++ b/include/llvm/Support/Signals.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines some helpful functions for dealing with the possibility of -// unix signals occuring while your program is running. +// unix signals occurring while your program is running. // //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index a41a633..2a712e4 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -156,10 +156,9 @@ public: // Null diagnostic. SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {} // Diagnostic with no location (e.g. file not found, command line arg error). - SMDiagnostic(const std::string &filename, const std::string &Msg, - bool showline = true) + SMDiagnostic(const std::string &filename, const std::string &Msg) : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), - Message(Msg), ShowLine(showline) {} + Message(Msg), ShowLine(false) {} // Diagnostic with a location. SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN, @@ -171,7 +170,7 @@ public: const SourceMgr *getSourceMgr() const { return SM; } SMLoc getLoc() const { return Loc; } - const std::string &getFilename() { return Filename; } + const std::string &getFilename() const { return Filename; } int getLineNo() const { return LineNo; } int getColumnNo() const { return ColumnNo; } const std::string &getMessage() const { return Message; } diff --git a/include/llvm/Support/StandardPasses.h b/include/llvm/Support/StandardPasses.h index d774faf..8dfd6f9 100644 --- a/include/llvm/Support/StandardPasses.h +++ b/include/llvm/Support/StandardPasses.h @@ -72,6 +72,7 @@ namespace llvm { Pass *InliningPass) { createStandardAliasAnalysisPasses(PM); + // If all optimizations are disabled, just run the always-inline pass. if (OptimizationLevel == 0) { if (InliningPass) PM->add(InliningPass); @@ -83,9 +84,10 @@ namespace llvm { PM->add(createIPSCCPPass()); // IP SCCP PM->add(createDeadArgEliminationPass()); // Dead argument elimination + + PM->add(createInstructionCombiningPass());// Clean up after IPCP & DAE + PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE } - PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE - PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE // Start of CallGraph SCC passes. if (UnitAtATime && HaveExceptions) @@ -120,7 +122,6 @@ namespace llvm { PM->add(createLoopDeletionPass()); // Delete dead loops if (UnrollLoops) PM->add(createLoopUnrollPass()); // Unroll small loops - PM->add(createInstructionCombiningPass()); // Clean up after the unroller if (OptimizationLevel > 1) PM->add(createGVNPass()); // Remove redundancies PM->add(createMemCpyOptPass()); // Remove memcpy / form memset @@ -134,6 +135,7 @@ namespace llvm { PM->add(createDeadStoreEliminationPass()); // Delete dead stores PM->add(createAggressiveDCEPass()); // Delete dead instructions PM->add(createCFGSimplificationPass()); // Merge & remove BBs + PM->add(createInstructionCombiningPass()); // Clean up after everything. if (UnitAtATime) { PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h index e122711..94f132a 100644 --- a/include/llvm/Support/TimeValue.h +++ b/include/llvm/Support/TimeValue.h @@ -35,13 +35,13 @@ namespace sys { public: /// A constant TimeValue representing the smallest time - /// value permissable by the class. MinTime is some point + /// value permissible by the class. MinTime is some point /// in the distant past, about 300 billion years BCE. /// @brief The smallest possible time value. static const TimeValue MinTime; /// A constant TimeValue representing the largest time - /// value permissable by the class. MaxTime is some point + /// value permissible by the class. MaxTime is some point /// in the distant future, about 300 billion years AD. /// @brief The largest possible time value. static const TimeValue MaxTime; diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h index e5306ec..47759b9 100644 --- a/include/llvm/Support/system_error.h +++ b/include/llvm/Support/system_error.h @@ -1,4 +1,4 @@ -//===---------------------------- system_error ----------------------------===// +//===---------------------------- system_error ------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h index 6c21ae9..4213d9b 100644 --- a/include/llvm/Target/SubtargetFeature.h +++ b/include/llvm/Target/SubtargetFeature.h @@ -35,8 +35,8 @@ namespace llvm { struct SubtargetFeatureKV { const char *Key; // K-V key string const char *Desc; // Help descriptor - uint32_t Value; // K-V integer value - uint32_t Implies; // K-V bit mask + uint64_t Value; // K-V integer value + uint64_t Implies; // K-V bit mask // Compare routine for std binary search bool operator<(const SubtargetFeatureKV &S) const { @@ -94,7 +94,7 @@ public: void AddFeature(const std::string &String, bool IsEnabled = true); /// Get feature bits. - uint32_t getBits(const SubtargetFeatureKV *CPUTable, + uint64_t getBits(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, const SubtargetFeatureKV *FeatureTable, size_t FeatureTableSize); diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 0f7e6aa..68f0515 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -32,17 +32,6 @@ class Register<string n> { string Namespace = ""; string AsmName = n; - // SpillSize - If this value is set to a non-zero value, it is the size in - // bits of the spill slot required to hold this register. If this value is - // set to zero, the information is inferred from any register classes the - // register belongs to. - int SpillSize = 0; - - // SpillAlignment - This value is used to specify the alignment required for - // spilling the register. Like SpillSize, this should only be explicitly - // specified if the register is not in a register class. - int SpillAlignment = 0; - // Aliases - A list of registers that this register overlaps with. A read or // modification of this register can potentially read or modify the aliased // registers. @@ -78,6 +67,13 @@ class Register<string n> { // -1 indicates that the gcc number is undefined and -2 that register number // is invalid for this mode/flavour. list<int> DwarfNumbers = []; + + // CostPerUse - Additional cost of instructions using this register compared + // to other registers in its class. The register allocator will try to + // minimize the number of instructions using a register with a CostPerUse. + // This is used by the x86-64 and ARM Thumb targets where some registers + // require larger instruction encodings. + int CostPerUse = 0; } // RegisterWithSubRegs - This can be used to define instances of Register which @@ -200,6 +196,7 @@ class Instruction { bit isIndirectBranch = 0; // Is this instruction an indirect branch? bit isCompare = 0; // Is this instruction a comparison instruction? bit isMoveImm = 0; // Is this instruction a move immediate instruction? + bit isBitcast = 0; // Is this instruction a bitcast instruction? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? @@ -590,9 +587,10 @@ class MnemonicAlias<string From, string To> { /// InstAlias - This defines an alternate assembly syntax that is allowed to /// match an instruction that has a different (more canonical) assembly /// representation. -class InstAlias<string Asm, dag Result> { +class InstAlias<string Asm, dag Result, bit Emit = 0b1> { string AsmString = Asm; // The .s format to match the instruction with. dag ResultInst = Result; // The MCInst to generate. + bit EmitAlias = Emit; // Emit the alias instead of what's aliased. // Predicates - Predicates that must be true for this to match. list<Predicate> Predicates = []; diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/Target/TargetAsmBackend.h index 7527298..2111f6b 100644 --- a/include/llvm/Target/TargetAsmBackend.h +++ b/include/llvm/Target/TargetAsmBackend.h @@ -16,6 +16,7 @@ #include "llvm/Support/DataTypes.h" namespace llvm { +class MCELFObjectTargetWriter; class MCFixup; class MCInst; class MCObjectWriter; @@ -40,6 +41,13 @@ public: /// assembler backend to emit the final object file. virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0; + /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable + /// non-standard ELFObjectWriters. + virtual MCELFObjectTargetWriter *createELFObjectTargetWriter() const { + assert(0 && "createELFObjectTargetWriter is not supported by asm backend"); + return 0; + } + /// hasReliableSymbolDifference - Check whether this target implements /// accurate relocations for differences between symbols. If not, differences /// between symbols will always be relocatable expressions and any references diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 98aab14..0271b67 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -58,6 +58,14 @@ public: return TLOF->getEHFrameSection(); } + unsigned getFDEEncoding(bool CFI) const { + return TLOF->getFDEEncoding(CFI); + } + + bool isFunctionEHFrameSymbolPrivate() const { + return TLOF->isFunctionEHFrameSymbolPrivate(); + } + unsigned getDwarfRARegNum(bool isEH) const { return TRI->getDwarfRegNum(TRI->getRARegister(), isEH); } diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index 25065d3..32e3e2b 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -160,7 +160,18 @@ public: bool isIllegalInteger(unsigned Width) const { return !isLegalInteger(Width); } - + + /// fitsInLegalInteger - This function returns true if the specified type fits + /// in a native integer type supported by the CPU. For example, if the CPU + /// only supports i32 as a native integer type, then i27 fits in a legal + // integer type but i45 does not. + bool fitsInLegalInteger(unsigned Width) const { + for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i) + if (Width <= LegalIntWidths[i]) + return true; + return false; + } + /// Target pointer alignment unsigned getPointerABIAlignment() const { return PointerABIAlign; } /// Return target's alignment for stack-based pointers diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/Target/TargetInstrDesc.h index 8823d5a..6e20e8a 100644 --- a/include/llvm/Target/TargetInstrDesc.h +++ b/include/llvm/Target/TargetInstrDesc.h @@ -105,6 +105,7 @@ namespace TID { IndirectBranch, Compare, MoveImm, + Bitcast, DelaySlot, FoldableAsLoad, MayLoad, @@ -358,6 +359,12 @@ public: bool isMoveImmediate() const { return Flags & (1 << TID::MoveImm); } + + /// isBitcast - Return true if this instruction is a bitcast instruction. + /// + bool isBitcast() const { + return Flags & (1 << TID::Bitcast); + } /// isNotDuplicable - Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index fc7b51e..418f3fe 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -477,7 +477,7 @@ public: } /// shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to - /// determine (in conjuction with areLoadsFromSameBasePtr) if two loads should + /// determine (in conjunction with areLoadsFromSameBasePtr) if two loads should /// be scheduled togther. On some targets if two loads are loading from /// addresses in the same cache line, it's better if they are scheduled /// together. This function takes two integers that represent the load offsets @@ -641,6 +641,10 @@ public: virtual int getInstrLatency(const InstrItineraryData *ItinData, SDNode *Node) const; + /// isHighLatencyDef - Return true if this opcode has high latency to its + /// result. + virtual bool isHighLatencyDef(int opc) const { return false; } + /// hasHighOperandLatency - Compute operand latency between a def of 'Reg' /// and an use in the current loop, return true if the target considered /// it 'high'. This is used by optimization passes such as machine LICM to diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h index a95b70f..198d585 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/Target/TargetInstrItineraries.h @@ -155,9 +155,13 @@ public: /// in the itinerary. /// unsigned getStageLatency(unsigned ItinClassIndx) const { - // If the target doesn't provide itinerary information, use a - // simple non-zero default value for all instructions. - if (isEmpty()) + // If the target doesn't provide itinerary information, use a simple + // non-zero default value for all instructions. Some target's provide a + // dummy (Generic) itinerary which should be handled as if it's itinerary is + // empty. We identify this by looking for a reference to stage zero (invalid + // stage). This is different from beginStage == endState != 0, which could + // be used for zero-latency pseudo ops. + if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0) return 1; // Calculate the maximum completion time for any stage. diff --git a/include/llvm/Target/TargetLibraryInfo.h b/include/llvm/Target/TargetLibraryInfo.h index bdd214b..0914b5d 100644 --- a/include/llvm/Target/TargetLibraryInfo.h +++ b/include/llvm/Target/TargetLibraryInfo.h @@ -23,9 +23,21 @@ namespace llvm { // void *memcpy(void *s1, const void *s2, size_t n); memcpy, + // void *memmove(void *s1, const void *s2, size_t n); + memmove, + /// void memset_pattern16(void *b, const void *pattern16, size_t len); memset_pattern16, + /// int iprintf(const char *format, ...); + iprintf, + + /// int siprintf(char *str, const char *format, ...); + siprintf, + + /// int fiprintf(FILE *stream, const char *format, ...); + fiprintf, + NumLibFuncs }; } diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index ba7574d..17d761c 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -39,6 +39,7 @@ namespace llvm { class AllocaInst; class APFloat; class CallInst; + class CCState; class Function; class FastISel; class FunctionLoweringInfo; @@ -189,14 +190,6 @@ public: return RepRegClassCostForVT[VT.getSimpleVT().SimpleTy]; } - /// getRegPressureLimit - Return the register pressure "high water mark" for - /// the specific register class. The scheduler is in high register pressure - /// mode (for the specific register class) if it goes over the limit. - virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, - MachineFunction &MF) const { - return 0; - } - /// isTypeLegal - Return true if the target has native support for the /// specified value type. This means that it has a register that directly /// holds it without promotions or expansions. @@ -934,6 +927,7 @@ public: bool isCalledByLegalizer() const { return CalledByLegalizer; } void AddToWorklist(SDNode *N); + void RemoveFromWorklist(SDNode *N); SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To, bool AddTo = true); SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true); @@ -1048,7 +1042,7 @@ protected: } /// JumpIsExpensive - Tells the code generator not to expand sequence of - /// operations into a seperate sequences that increases the amount of + /// operations into a separate sequences that increases the amount of /// flow control. void setJumpIsExpensive(bool isExpensive = true) { JumpIsExpensive = isExpensive; @@ -1258,6 +1252,9 @@ public: return SDValue(); // this is here to silence compiler errors } + /// HandleByVal - Target-specific cleanup for formal ByVal parameters. + virtual void HandleByVal(CCState *, unsigned &) const {} + /// CanLowerReturn - This hook should be implemented to check whether the /// return values described by the Outs array can fit into the return /// registers. If false is returned, an sret-demotion is performed. @@ -1291,6 +1288,26 @@ public: return false; } + /// mayBeEmittedAsTailCall - Return true if the target may be able emit the + /// call instruction as a tail call. This is used by optimization passes to + /// determine if it's profitable to duplicate return instructions to enable + /// tailcall optimization. + virtual bool mayBeEmittedAsTailCall(CallInst *CI) const { + return false; + } + + /// getTypeForExtArgOrReturn - Return the type that should be used to zero or + /// sign extend a zeroext/signext integer argument or return value. + /// FIXME: Most C calling convention requires the return type to be promoted, + /// but this is not true all the time, e.g. i1 on x86-64. It is also not + /// necessary for non-C calling conventions. The frontend should handle this + /// and include all of the necessary information. + virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, + ISD::NodeType ExtendKind) const { + EVT MinVT = getRegisterType(Context, MVT::i32); + return VT.bitsLT(MinVT) ? MinVT : VT; + } + /// LowerOperationWrapper - This callback is invoked by the type legalizer /// to legalize nodes with an illegal operand type but legal result types. /// It replaces the LowerOperation callback in the type Legalizer. diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 34bf271..7402ed6 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -140,6 +140,9 @@ public: const MCSection *getStaticDtorSection() const { return StaticDtorSection; } const MCSection *getLSDASection() const { return LSDASection; } virtual const MCSection *getEHFrameSection() const = 0; + virtual void emitPersonalityValue(MCStreamer &Streamer, + const TargetMachine &TM, + const MCSymbol *Sym) const; const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } const MCSection *getDwarfLineSection() const { return DwarfLineSection; } @@ -218,15 +221,19 @@ public: MachineModuleInfo *MMI, unsigned Encoding, MCStreamer &Streamer) const; + // getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality. + virtual MCSymbol * + getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI) const; + /// const MCExpr * - getExprForDwarfReference(const MCSymbol *Sym, Mangler *Mang, - MachineModuleInfo *MMI, unsigned Encoding, + getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const; virtual unsigned getPersonalityEncoding() const; virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding() const; + virtual unsigned getFDEEncoding(bool CFI) const; virtual unsigned getTTypeEncoding() const; protected: diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 030bf5b..78f770c 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -38,6 +38,7 @@ class PassManager; class Pass; class TargetELFWriterInfo; class formatted_raw_ostream; +class raw_ostream; // Relocation model types. namespace Reloc { @@ -105,7 +106,9 @@ protected: // Can only create subclasses. unsigned MCRelaxAll : 1; unsigned MCNoExecStack : 1; + unsigned MCSaveTempLabels : 1; unsigned MCUseLoc : 1; + unsigned MCUseCFI : 1; public: virtual ~TargetMachine(); @@ -171,6 +174,14 @@ public: /// relaxed. void setMCRelaxAll(bool Value) { MCRelaxAll = Value; } + /// hasMCSaveTempLabels - Check whether temporary labels will be preserved + /// (i.e., not treated as temporary). + bool hasMCSaveTempLabels() const { return MCSaveTempLabels; } + + /// setMCSaveTempLabels - Set whether temporary labels will be preserved + /// (i.e., not treated as temporary). + void setMCSaveTempLabels(bool Value) { MCSaveTempLabels = Value; } + /// hasMCNoExecStack - Check whether an executable stack is not needed. bool hasMCNoExecStack() const { return MCNoExecStack; } @@ -183,6 +194,12 @@ public: /// setMCUseLoc - Set whether all we should use dwarf's .loc directive. void setMCUseLoc(bool Value) { MCUseLoc = Value; } + /// hasMCUseCFI - Check whether we should use dwarf's .cfi_* directives. + bool hasMCUseCFI() const { return MCUseCFI; } + + /// setMCUseCFI - Set whether all we should use dwarf's .cfi_* directives. + void setMCUseCFI(bool Value) { MCUseCFI = Value; } + /// getRelocationModel - Returns the code generation relocation model. The /// choices are static, PIC, and dynamic-no-pic, and target default. static Reloc::Model getRelocationModel(); @@ -267,6 +284,7 @@ public: /// virtual bool addPassesToEmitMC(PassManagerBase &, MCContext *&, + raw_ostream &, CodeGenOpt::Level, bool = true) { return true; @@ -324,6 +342,7 @@ public: /// virtual bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, + raw_ostream &OS, CodeGenOpt::Level OptLevel, bool DisableVerify = true); diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 97ceffd..62190c1 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -157,6 +157,11 @@ namespace llvm { /// wth earlier copy coalescing. extern bool StrongPHIElim; + /// getTrapFunctionName - If this returns a non-empty string, this means isel + /// should lower Intrinsic::trap to a call to the specified function name + /// instead of an ISD::TRAP node. + extern StringRef getTrapFunctionName(); + } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 121091c..205e76f 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -46,6 +46,7 @@ struct TargetRegisterDesc { const unsigned *Overlaps; // Overlapping registers, described above const unsigned *SubRegs; // Sub-register set, described above const unsigned *SuperRegs; // Super-register set, described above + unsigned CostPerUse; // Extra cost of instructions using register. }; class TargetRegisterClass { @@ -426,6 +427,12 @@ public: return get(RegNo).Name; } + /// getCostPerUse - Return the additional cost of using this register instead + /// of other registers in its class. + unsigned getCostPerUse(unsigned RegNo) const { + return get(RegNo).CostPerUse; + } + /// getNumRegs - Return the number of registers this target has (useful for /// sizing arrays holding per register information) unsigned getNumRegs() const { @@ -588,11 +595,32 @@ public: } /// getCrossCopyRegClass - Returns a legal register class to copy a register - /// in the specified class to or from. Returns NULL if it is possible to copy - /// between a two registers of the specified class. + /// in the specified class to or from. If it is possible to copy the register + /// directly without using a cross register class copy, return the specified + /// RC. Returns NULL if it is not possible to copy between a two registers of + /// the specified class. virtual const TargetRegisterClass * getCrossCopyRegClass(const TargetRegisterClass *RC) const { - return NULL; + return RC; + } + + /// getLargestLegalSuperClass - Returns the largest super class of RC that is + /// legal to use in the current sub-target and has the same spill size. + /// The returned register class can be used to create virtual registers which + /// means that all its registers can be copied and spilled. + virtual const TargetRegisterClass* + getLargestLegalSuperClass(const TargetRegisterClass *RC) const { + /// The default implementation is very conservative and doesn't allow the + /// register allocator to inflate register classes. + return RC; + } + + /// getRegPressureLimit - Return the register pressure "high water mark" for + /// the specific register class. The scheduler is in high register pressure + /// mode (for the specific register class) if it goes over the limit. + virtual unsigned getRegPressureLimit(const TargetRegisterClass *RC, + MachineFunction &MF) const { + return 0; } /// getAllocationOrder - Returns the register allocation order for a specified @@ -614,6 +642,14 @@ public: return 0; } + /// avoidWriteAfterWrite - Return true if the register allocator should avoid + /// writing a register from RC in two consecutive instructions. + /// This can avoid pipeline stalls on certain architectures. + /// It does cause increased register pressure, though. + virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const { + return false; + } + /// UpdateRegAllocHint - A callback to allow target a chance to update /// register allocation hints when a register is "changed" (e.g. coalesced) /// to another register. e.g. On ARM, some virtual registers should target @@ -631,6 +667,13 @@ public: return false; } + /// useFPForScavengingIndex - returns true if the target wants to use + /// frame pointer based accesses to spill to the scavenger emergency spill + /// slot. + virtual bool useFPForScavengingIndex(const MachineFunction &MF) const { + return true; + } + /// requiresFrameIndexScavenging - returns true if the target requires post /// PEI scavenging of registers for materializing frame index constants. virtual bool requiresFrameIndexScavenging(const MachineFunction &MF) const { diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index f851ad0..a464822 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -43,7 +43,7 @@ namespace llvm { MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, - bool useLoc, + bool useLoc, bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, TargetAsmBackend *TAB, @@ -78,6 +78,7 @@ namespace llvm { TargetMachine &TM); typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, + TargetMachine &TM, unsigned SyntaxVariant, const MCAsmInfo &MAI); typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T, @@ -95,6 +96,7 @@ namespace llvm { formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, + bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, TargetAsmBackend *TAB, @@ -286,11 +288,12 @@ namespace llvm { return MCDisassemblerCtorFn(*this); } - MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, + MCInstPrinter *createMCInstPrinter(TargetMachine &TM, + unsigned SyntaxVariant, const MCAsmInfo &MAI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); + return MCInstPrinterCtorFn(*this, TM, SyntaxVariant, MAI); } @@ -327,12 +330,13 @@ namespace llvm { formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, + bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, TargetAsmBackend *TAB, bool ShowInst) const { // AsmStreamerCtorFn is default to llvm::createAsmStreamer - return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, + return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI, InstPrint, CE, TAB, ShowInst); } diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h index 1891f87..c5ab90b 100644 --- a/include/llvm/Target/TargetSelect.h +++ b/include/llvm/Target/TargetSelect.h @@ -120,6 +120,19 @@ namespace llvm { 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/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index c9be40d..ff8d07d 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -490,6 +490,18 @@ class SDNodeXForm<SDNode opc, code xformFunction> { def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>; +//===----------------------------------------------------------------------===// +// PatPred Subclasses. +// +// These allow specifying different sorts of predicates that control whether a +// node is matched. +// +class PatPred; + +class CodePatPred<code predicate> : PatPred { + code PredicateCode = predicate; +} + //===----------------------------------------------------------------------===// // Selection DAG Pattern Fragments. @@ -507,7 +519,8 @@ class PatFrag<dag ops, dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator { dag Operands = ops; dag Fragment = frag; - code Predicate = pred; + code PredicateCode = pred; + code ImmediateCode = [{}]; SDNodeXForm OperandTransform = xform; } @@ -516,6 +529,27 @@ class PatFrag<dag ops, dag frag, code pred = [{}], class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> : PatFrag<(ops), frag, pred, xform>; + +// ImmLeaf is a pattern fragment with a constraint on the immediate. The +// constraint is a function that is run on the immediate (always with the value +// sign extended out to an int64_t) as Imm. For example: +// +// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>; +// +// this is a more convenient form to match 'imm' nodes in than PatLeaf and also +// is preferred over using PatLeaf because it allows the code generator to +// reason more about the constraint. +// +// If FastIsel should ignore all instructions that have an operand of this type, +// the FastIselShouldIgnore flag can be set. This is an optimization to reduce +// the code size of the generated fast instruction selector. +class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> + : PatFrag<(ops), (vt imm), [{}], xform> { + let ImmediateCode = pred; + bit FastIselShouldIgnore = 0; +} + + // Leaf fragments. def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 1239881..d12fd1d 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -152,7 +152,6 @@ ModulePass *createDeadArgHackingPass(); /// equal to maxElements (maxElements == 0 means always promote). /// Pass *createArgumentPromotionPass(unsigned maxElements = 3); -Pass *createStructRetPromotionPass(); //===----------------------------------------------------------------------===// /// createIPConstantPropagationPass - This pass propagates constants from call diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h index aa9873f..088775a 100644 --- a/include/llvm/Transforms/Instrumentation.h +++ b/include/llvm/Transforms/Instrumentation.h @@ -17,7 +17,6 @@ namespace llvm { class ModulePass; -class FunctionPass; // Insert edge profiling instrumentation ModulePass *createEdgeProfilerPass(); @@ -28,6 +27,9 @@ ModulePass *createOptimalEdgeProfilerPass(); // Insert path profiling instrumentation ModulePass *createPathProfilerPass(); +// Insert GCOV profiling instrumentation +ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true); + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 6f2a38e..de46a8d 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -128,7 +128,7 @@ Pass *createLoopInstSimplifyPass(); // // LoopUnroll - This pass is a simple loop unrolling pass. // -Pass *createLoopUnrollPass(); +Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1, int AllowPartial = -1); //===----------------------------------------------------------------------===// // @@ -301,12 +301,6 @@ FunctionPass *createSimplifyLibCallsPass(); //===----------------------------------------------------------------------===// // -/// createSimplifyHalfPowrLibCallsPass - This is an experimental pass that -/// optimizes specific half_pow functions. -FunctionPass *createSimplifyHalfPowrLibCallsPass(); - -//===----------------------------------------------------------------------===// -// // CodeGenPrepare - This pass prepares a function for instruction selection. // FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0); diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 5335860..90eabef 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -19,6 +19,7 @@ #include "llvm/BasicBlock.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/DebugLoc.h" namespace llvm { @@ -181,6 +182,10 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds, ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred); +/// GetFirstDebugLocInBasicBlock - Return first valid DebugLoc entry in a +/// given basic block. +DebugLoc GetFirstDebugLocInBasicBlock(const BasicBlock *BB); + } // End llvm namespace #endif diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 24ebb10..853de2d 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -207,7 +207,7 @@ public: /// /// Note that this only does one level of inlining. For example, if the /// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now -/// exists in the instruction stream. Similiarly this will inline a recursive +/// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. /// bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI); diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 2823fbb..e61dcb3 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -19,14 +19,19 @@ namespace llvm { class User; class BasicBlock; +class Function; class BranchInst; class Instruction; +class DbgDeclareInst; +class StoreInst; +class LoadInst; class Value; class Pass; class PHINode; class AllocaInst; class ConstantExpr; class TargetData; +class DIBuilder; template<typename T> class SmallVectorImpl; @@ -69,10 +74,6 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN); /// /// This returns true if it changed the code, note that it can delete /// instructions in other blocks as well in this block. -/// -/// WARNING: Do not use this function on unreachable blocks, as recursive -/// simplification is not able to handle corner-case scenarios that can -/// arise in them. bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetData *TD = 0); //===----------------------------------------------------------------------===// @@ -157,6 +158,24 @@ static inline unsigned getKnownAlignment(Value *V, const TargetData *TD = 0) { return getOrEnforceKnownAlignment(V, 0, TD); } +///===---------------------------------------------------------------------===// +/// Dbg Intrinsic utilities +/// + +/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value +/// that has an associated llvm.dbg.decl intrinsic. +bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + StoreInst *SI, DIBuilder &Builder); + +/// Inserts a llvm.dbg.value instrinsic before the stores to an alloca'd value +/// that has an associated llvm.dbg.decl intrinsic. +bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, + LoadInst *LI, DIBuilder &Builder); + +/// LowerDbgDeclare - Lowers llvm.dbg.declare intrinsics into appropriate set +/// of llvm.dbg.value intrinsics. +bool LowerDbgDeclare(Function &F); + } // End llvm namespace #endif diff --git a/include/llvm/TypeSymbolTable.h b/include/llvm/TypeSymbolTable.h index 9fdcb98..89ad534 100644 --- a/include/llvm/TypeSymbolTable.h +++ b/include/llvm/TypeSymbolTable.h @@ -133,7 +133,7 @@ private: /// is refined. virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); - /// This function markes a type as being concrete (defined). + /// This function marks a type as being concrete (defined). virtual void typeBecameConcrete(const DerivedType *AbsTy); /// @} diff --git a/include/llvm/User.h b/include/llvm/User.h index 1363495..3f9c28e 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -95,11 +95,11 @@ public: OperandList[i] = Val; } const Use &getOperandUse(unsigned i) const { - assert(i < NumOperands && "getOperand() out of range!"); + assert(i < NumOperands && "getOperandUse() out of range!"); return OperandList[i]; } Use &getOperandUse(unsigned i) { - assert(i < NumOperands && "getOperand() out of range!"); + assert(i < NumOperands && "getOperandUse() out of range!"); return OperandList[i]; } diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 130e273..3a1c3ca 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -51,8 +51,8 @@ class MDNode; /// This is a very important LLVM class. It is the base class of all values /// computed by a program that may be used as operands to other values. Value is /// the super class of other important classes such as Instruction and Function. -/// All Values have a Type. Type is not a subclass of Value. All types can have -/// a name and they should belong to some Module. Setting the name on the Value +/// All Values have a Type. Type is not a subclass of Value. Some values can +/// have a name and they belong to some Module. Setting the name on the Value /// automatically updates the module's symbol table. /// /// Every value has a "use list" that keeps track of which other Values are |